From 875d9b989eccf8d1c0ea6adb56efb1d22e33266a Mon Sep 17 00:00:00 2001 From: menshibin Date: Wed, 31 Jul 2024 11:46:03 +0800 Subject: [PATCH 01/14] add nodejs interface --- .../14-reference/05-connector/30-python.mdx | 1 + docs/zh/14-reference/05-connector/35-node.mdx | 268 ++++++++++++++++++ 2 files changed, 269 insertions(+) diff --git a/docs/zh/14-reference/05-connector/30-python.mdx b/docs/zh/14-reference/05-connector/30-python.mdx index 9f2be23067..366b85af4b 100644 --- a/docs/zh/14-reference/05-connector/30-python.mdx +++ b/docs/zh/14-reference/05-connector/30-python.mdx @@ -628,3 +628,4 @@ Consumer API 的 `seek` 方法用于重置 Consumer 的消费进度到指定位 ## 常见问题 欢迎[提问或报告问题](https://github.com/taosdata/taos-connector-python/issues)。 + diff --git a/docs/zh/14-reference/05-connector/35-node.mdx b/docs/zh/14-reference/05-connector/35-node.mdx index 778da19b34..88a27ad05a 100644 --- a/docs/zh/14-reference/05-connector/35-node.mdx +++ b/docs/zh/14-reference/05-connector/35-node.mdx @@ -330,4 +330,272 @@ taos.destroy(); **原因**:一般都是因为配置 FQDN 不正确。 可以参考[如何彻底搞懂 TDengine 的 FQDN](https://www.taosdata.com/blog/2021/07/29/2741.html) 。 +## API 参考 +Node.js 连接器(`@tdengine/websocket`), 其通过 taosAdapter 提供的 Websocket 接口连接 TDengine 实例。 + +### URL 规范 + +```text +[+]://[[:@]:][/][?=[&=]] +|------------|---|-----------|-----------|------|------|------------|-----------------------| +| protocol | | username | password | host | port | database | params | +``` + +- **protocol**: 使用 websocket 协议建立连接。例如`ws://localhost:6041` +- **username/password**: 数据库的用户名和密码。 +- **host/port**: 主机地址和端口号。例如`localhost:6041` +- **database**: 数据库名称。 +- **params**: 其他参数。 例如token。 + +- 完整 URL 示例: + +```js + ws://root:taosdata@localhost:6041 +``` +### WSConfig + +除了通过指定的 URL 获取连接,还可以使用 WSConfig 指定建立连接时的参数。 + +```js +try { + let url = 'ws://127.0.0.1:6041' + let conf = WsSql.NewConfig(url) + conf.setUser('root') + conf.setPwd('taosdata') + conf.setDb('db') + conf.setTimeOut(500) + let wsSql = await WsSql.open(conf); +} catch (e) { + console.error(e); +} +``` + +WSConfig 中的配置如下: +- setUrl(url string) 设置 taosAdapter 连接地址 url,详见上文 URL 规范。 +- setUser(user: string) 设置数据库用户名。 +- setPwd(pws:string) 设置数据库密码。 +- setDb(db: string) 设置数据库名称。 +- setTimeOut(ms : number) 设置连接超时,单位毫秒。 +- setToken(token: string) 设置 taosAdapter 认证token。 + +### 连接功能 + +- `static async open(wsConfig:WSConfig):Promise` + - **接口说明**:建立 taosAdapter 连接。 + - **参数说明**: + - `wsConfig`:连接配置,详见上文 WSConfig 章节。 + - **返回值**:连接对象。 + - **异常**:连接失败抛出 `TDWebSocketClientError` 异常。 +- `destroyed()` + - **接口说明**:释放销毁资源。 + - **异常**:连接失败抛出 `TDWebSocketClientError` 异常。 + +### 获取 taosc 版本号 + - `async version(): Promise` + - **接口说明**:获取 taosc 客户端版本。 + - **返回值**:taosc 客户端版本号。 + - **异常**:连接失败抛出 `TDWebSocketClientError` 异常。 + +### 执行 SQL +- `async exec(sql: string, reqId?: number): Promise` + - **接口说明**:执行 sql 语句。 + - **参数说明**: + - `sql`:待执行的 sql 语句。 + - `reqId`: 请求 id 非必填,用于问题追踪。 + - **返回值**:执行结果 + ```js + TaosResult { + affectRows: number, 影响的条数 + timing: number, 执行时长 + totalTime: number, 响应总时长 + } + ``` + - **异常**:连接失败抛出 `TDWebSocketClientError` 异常。 +- `async query(sql: string, reqId?:number): Promise` + - **接口说明**:查询数据。 + - **参数说明**: + - `sql`:待执行的查询 sql 语句。 + - `reqId`: 请求 id 非必填,用于问题追踪。 + - **返回值**:WSRows 数据集对象。 + - **异常**:连接失败抛出 `TDWebSocketClientError` 异常。 + +### 数据集 +- `getMeta():Array | null` + - **接口说明**:获取查询结果的的列的数量、类型和长度。 + - **返回值**:TDengineMeta 数据对象数组。 + ```js + export interface TDengineMeta { + name: string, + type: string, + length: number, + } + ``` +- `async next(): Promise` + - **接口说明**:将游标从当前位置向后移动一行。用于遍历查询结果集。 + - **返回值**:如果新的当前行有效,则返回 true;如果结果集中没有更多行,则返回 false。 + - **异常**:连接失败抛出 `TDWebSocketClientError` 异常。 + - `getData(): Array` + - **接口说明**:返回查询的一行数据。 + - **返回值**:返回查询的一行数据,此接口需要搭配 next 接口一起使用。 +- `async close():Promise` + - **接口说明**:数据读取完成后,释放结果集。 + - **异常**:连接失败抛出 `TDWebSocketClientError` 异常。 + +### 无模式写入 +- `async schemalessInsert(lines: Array, protocol: SchemalessProto, precision: Precision, ttl: number, reqId?: number): Promise` + - **接口说明**:无模式写入。 + - **参数说明**: + - `lines`:待写入的数据数组,无模式具体的数据格式可参考 `Schemaless 写入`。 + - `protocol`: + ```js + InfluxDBLineProtocol //InfluxDB 行协议(Line Protocol) + OpenTSDBTelnetLineProtocol //OpenTSDB 文本行协议 + OpenTSDBJsonFormatProtocol //JSON 协议格式 + ``` + - **异常**:连接失败抛出 `TaosResultError` 异常。 + +### 参数绑定 +- `async stmtInit(reqId?:number): Promise` + - **接口说明** 使用 WsSql 对象创建 stmt 对象创建。 + - **参数说明**: + - `reqId`: 请求 id 非必填,用于问题追踪。 + - **返回值**:stmt 对象。 + - **异常**:连接失败抛出 `TDWebSocketClientError` 异常。 +- `async prepare(sql: string): Promise` + - **接口说明** 绑定预编译 sql 语句。 + - **参数说明**: + - `sql`: 预编译的 SQL 语句。 + - **返回值**:stmt 对象。 + - **异常**:连接失败抛出 `TDWebSocketClientError` 异常。 +- `async setTableName(tableName: string): Promise` + - **接口说明** 设置将要写入数据的表名。 + - **参数说明**: + - `tableName`: 表名,如果需要指定数据库, 例如: `db_name.table_name` 即可。 + - **异常**:连接失败抛出 `TDWebSocketClientError` 异常。 +通过 StmtBindParams 对象设置绑定数据。 +- `setBoolean(params :any[])` + - **接口说明** 设置布尔值。 + - **参数说明**: + - `params`: 布尔类型列表。 + - **异常**:连接失败抛出 `TDWebSocketClientError` 异常。 +- 下面接口除了要设置的值类型不同外,其余同 setBoolean: + - `setTinyInt(params :any[])` + - `setUTinyInt(params :any[])` + - `setSmallInt(params :any[])` + - `setUSmallInt(params :any[])` + - `setInt(params :any[])` + - `setUInt(params :any[])` + - `setBigint(params :any[])` + - `setUBigint(params :any[])` + - `setFloat(params :any[])` + - `setDouble(params :any[])` + - `setVarchar(params :any[])` + - `setBinary(params :any[])` + - `setNchar(params :any[])` + - `setJson(params :any[])` + - `setVarBinary(params :any[])` + - `setGeometry(params :any[])` + - `setTimestamp(params :any[])` +- `async bind(paramsArray:StmtBindParams): Promise` + - **接口说明** 绑定数据。 + - **参数说明**: + - `paramsArray`: 绑定数据。 + - **异常**:连接失败抛出 `TDWebSocketClientError` 异常。 +- `async batch(): Promise` + - **接口说明** 提交绑定数据。 + - **异常**:连接失败抛出 `TDWebSocketClientError` 异常。 +- `async exec(): Promise` + - **接口说明** 执行将绑定的数据全部写入。 + - **异常**:连接失败抛出 `TDWebSocketClientError` 异常。 +- `async close(): Promise` + - **接口说明** 关闭 stmt 对象。 + - **异常**:连接失败抛出 `TDWebSocketClientError` 异常。 + +### 数据订阅 + +- **创建消费者支持属性列表**: + - taos.TMQConstants.CONNECT_USER: 用户名。 + - taos.TMQConstants.CONNECT_PASS: 密码。 + - taos.TMQConstants.GROUP_ID: 所在的 group。 + - taos.TMQConstants.CLIENT_ID: client id。 + - taos.TMQConstants.WS_URL: taosAdapter 的url地址。 + - taos.TMQConstants.AUTO_OFFSET_RESET: 来确定消费位置为最新数据(latest)还是包含旧数据(earliest)。 + - taos.TMQConstants.ENABLE_AUTO_COMMIT: 是否允许自动提交。 + - taos.TMQConstants.AUTO_COMMIT_INTERVAL_MS: 自动提交间隔。 + - taos.TMQConstants.CONNECT_MESSAGE_TIMEOUT: 数据传输超时参数,单位 ms,默认为 10000 ms。 +- `static async newConsumer(wsConfig:Map):Promise` + - **接口说明** 消费者构造函数。 + - **参数说明**: + - `wsConfig`: 创建消费者属性配置。 + - **返回值**:WsConsumer 消费者对象。 + - **异常**:连接失败抛出 `TDWebSocketClientError` 异常。 +- `async subscribe(topics: Array, reqId?:number): Promise` + - **接口说明** 订阅一组主题。 + - **参数说明**: + - `topics`: 订阅的主题列表。 + - `reqId`: 请求 id 非必填,用于问题追踪。 + - **异常**:连接失败抛出 `TDWebSocketClientError` 异常。 +- `async unsubscribe(reqId?:number): Promise` + - **接口说明** 取消订阅。 + - **参数说明**: + - `reqId`: 请求 id 非必填,用于问题追踪。 + - **异常**:连接失败抛出 `TDWebSocketClientError` 异常。 +- `async poll(timeoutMs: number, reqId?:number):Promise>` + - **接口说明** 轮询消息。 + - **参数说明**: + - `timeoutMs`: 表示轮询的超时时间,单位毫秒。 + - `reqId`: 请求 id 非必填,用于问题追踪。 + - **返回值**:`Map` 每个主题对应的数据。 + - **异常**:连接失败抛出 `TDWebSocketClientError` 异常。 +- `async subscription(reqId?:number):Promise>` + - **接口说明** 获取当前订阅的所有主题。 + - **参数说明**: + - `reqId`: 请求 id 非必填,用于问题追踪。 + - **返回值**:`Array` 主题列表。 + - **异常**:连接失败抛出 `TDWebSocketClientError` 异常。 +- `async commit(reqId?:number):Promise>` + - **接口说明** 提交当前处理的消息的偏移量。 + - **参数说明**: + - `reqId`: 请求 id 非必填,用于问题追踪。 + - **返回值**:`Array` 每个主题的消费进度。 + - **异常**:连接失败抛出 `TDWebSocketClientError` 异常。 +- `async committed(partitions:Array, reqId?:number):Promise>` + - **接口说明**:获取一组分区最后提交的偏移量。 + - **参数说明**: + - `partitions`:一个 `Array` 类型的参数,表示要查询的分区集合。 + - `reqId`: 请求 id 非必填,用于问题追踪。 + - **返回值**:`Array`,即一组分区最后提交的偏移量。 + - **异常**:如果在获取提交的偏移量过程中发生错误,将抛出 TDWebSocketClientError 异常。 +- `async seek(partition:TopicPartition, reqId?:number):Promise` + - **接口说明**:将给定分区的偏移量设置到指定的位置。 + - **参数说明**: + - `partition`:一个 `TopicPartition` 类型的参数,表示要操作的分区和要设置的偏移量。 + - `reqId`: 请求 id 非必填,用于问题追踪。 + - **异常**:如果在设置偏移量过程中发生错误,将抛出 TDWebSocketClientError 异常。 +- `async positions(partitions:Array, reqId?:number):Promise>` + - **接口说明**:获取给定分区当前的偏移量。 + - **参数说明**: + - `partitions`:一个 `TopicPartition` 类型的参数,表示要查询的分区。 + - `reqId`: 请求 id 非必填,用于问题追踪。 + - **返回值**:`Array`,即一组分区最后提交的偏移量。 + - **异常**:如果在获取偏移量过程中发生错误,将抛出 TDWebSocketClientError 异常。 +- `async seekToBeginning(partitions:Array):Promise` + - **接口说明**:将一组分区的偏移量设置到最早的偏移量。 + - **参数说明**: + - `partitions`:一个 `Array` 类型的参数,表示要操作的分区集合。 + - **异常**:如果在设置偏移量过程中发生错误,将抛出 TDWebSocketClientError 异常。 +- `async seekToEnd(partitions:Array):Promise` + - **接口说明**:将一组分区的偏移量设置到最新的偏移量。 + - **参数说明**: + - `partitions`:一个 `Array` 类型的参数,表示要操作的分区集合。 + - **异常**:如果在设置偏移量过程中发生错误,将抛出 TDWebSocketClientError 异常。 +- `async assignment(topics?:string[]):Promise>` + - **接口说明**:获取消费者当前分配的指定的分区或所有分区。 + - **参数说明**: + - `topics`:需要获取的分区(非必填),不填表示获取全部的分区 + - **返回值**:返回值类型为 `Array`,即消费者当前分配的所有分区。 + - **异常**:如果在获取分配的分区过程中发生错误,将抛出 TDWebSocketClientError 异常。 +- `async close():Promise` + - **接口说明**:关闭数据库连接。 + - **异常**:操作失败抛出 `TDWebSocketClientError` 异常。 From e7e10312e31804bc0737371e786907e88d08cfee Mon Sep 17 00:00:00 2001 From: sheyanjie-qq <249478495@qq.com> Date: Wed, 31 Jul 2024 14:20:20 +0800 Subject: [PATCH 02/14] mod jdbc doc --- docs/zh/08-develop/01-connect/index.md | 7 +++- docs/zh/08-develop/04-schemaless.md | 30 +++++++++++-- docs/zh/08-develop/07-tmq.md | 2 + docs/zh/08-develop/index.md | 2 +- docs/zh/14-reference/05-connector/index.md | 42 +++++++++---------- .../taosdata/example/AbsConsumerLoopFull.java | 6 +++ .../taosdata/example/AbsWsConsumerLoop.java | 6 +++ 7 files changed, 68 insertions(+), 27 deletions(-) diff --git a/docs/zh/08-develop/01-connect/index.md b/docs/zh/08-develop/01-connect/index.md index fcb70f2293..6392f324db 100644 --- a/docs/zh/08-develop/01-connect/index.md +++ b/docs/zh/08-develop/01-connect/index.md @@ -264,6 +264,8 @@ phpize && ./configure --enable-swoole && make -j && make install 在执行这一步之前,请确保有一个正在运行的,且可以访问到的 TDengine,而且服务端的 FQDN 配置正确。以下示例代码,都假设 TDengine 安装在本机,且 FQDN(默认 localhost) 和 serverPort(默认 6030) 都使用默认配置。 ### 连接参数 +连接的配置项较多,因此在建立连接之前,我们能先介绍一下各语言连接器建立连接使用的参数。 + @@ -317,7 +319,7 @@ properties 中的配置参数如下: **配置参数的优先级:** -通过前面三种方式获取连接,如果配置参数在 url、Properties、客户端配置文件中有重复,则参数的`优先级由高到低`分别如下: +通过前面三种方式获取连接,如果配置参数在 url、Properties、客户端配置文件中有重复,则参数的**优先级由高到低**分别如下: 1. JDBC URL 参数,如上所述,可以在 JDBC URL 的参数中指定。 2. Properties connProps @@ -344,6 +346,7 @@ properties 中的配置参数如下: ### Websocket 连接 +各语言连接器建立 Websocket 连接代码样例。 @@ -383,6 +386,7 @@ properties 中的配置参数如下: ### 原生连接 +各语言连接器建立原生连接代码样例。 ```java @@ -414,6 +418,7 @@ properties 中的配置参数如下: ### REST 连接 +各语言连接器建立 REST 连接代码样例。 ```java diff --git a/docs/zh/08-develop/04-schemaless.md b/docs/zh/08-develop/04-schemaless.md index 6ce5d69c82..816b3aa170 100644 --- a/docs/zh/08-develop/04-schemaless.md +++ b/docs/zh/08-develop/04-schemaless.md @@ -158,7 +158,6 @@ st,t1=3,t2=4,t3=t3 c1=3i64,c6="passit" 1626006833640000000 - ```java {{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/SchemalessWsTest.java:schemaless}} ``` @@ -190,9 +189,9 @@ writer.write(lineDemo, SchemalessProtocolType.LINE, SchemalessTimestampType.NANO ### 原生连接 - ```java - {{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/SchemalessJniTest.java:schemaless}} - ``` +```java +{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/SchemalessJniTest.java:schemaless}} +``` 执行带有 reqId 的无模式写入,此 reqId 可用于请求链路追踪。 @@ -219,6 +218,29 @@ writer.write(lineDemo, SchemalessProtocolType.LINE, SchemalessTimestampType.NANO +### REST 连接 + + + 不支持 + + + + + + + + + + + + + + + + + + + ## 查询写入的数据 运行上节的样例代码,会在 power 数据库中自动建表,我们可以通过 taos shell 或者应用程序来查询数据。下面给出用 taos shell 查询超级表和 meters 表数据的样例。 diff --git a/docs/zh/08-develop/07-tmq.md b/docs/zh/08-develop/07-tmq.md index 64b01eea54..e6d866c29c 100644 --- a/docs/zh/08-develop/07-tmq.md +++ b/docs/zh/08-develop/07-tmq.md @@ -26,6 +26,8 @@ TDengine 消费者的概念跟 Kafka 类似,消费者通过订阅主题来接 ### 创建参数 +创建消费者的参数较多,非常灵活的支持了各种连接类型、 Offset 提交方式、压缩、重连、反序列化等特性,下面单独介绍各语言连接器创建消费者的参数。 + Java 连接器创建消费者的参数为 Properties, 可以设置如下参数: diff --git a/docs/zh/08-develop/index.md b/docs/zh/08-develop/index.md index e7578232c0..d7b0c137e2 100644 --- a/docs/zh/08-develop/index.md +++ b/docs/zh/08-develop/index.md @@ -15,7 +15,7 @@ description: 让开发者能够快速上手的指南 7. 在很多场景下(如车辆管理),应用需要获取每个数据采集点的最新状态,那么建议你采用 TDengine 的 Cache 功能,而不用单独部署 Redis 等缓存软件。 8. 如果你发现 TDengine 的函数无法满足你的要求,那么你可以使用用户自定义函数(UDF)来解决问题。 -本部分内容就是按照上述顺序组织的。为便于理解,TDengine 为每个功能和每个支持的编程语言都提供了示例代码。如果你希望深入了解 SQL 的使用,需要查看[SQL 手册](../taos-sql/)。如果想更深入地了解各连接器的使用,请阅读[连接器参考指南](../connector/)。如果还希望想将 TDengine 与第三方系统集成起来,比如 Grafana, 请参考[第三方工具](../third-party/)。 +本部分内容就是按照上述顺序组织的。为便于理解,TDengine 为每个功能和每个支持的编程语言都提供了示例代码。如果你希望深入了解 SQL 的使用,需要查看[SQL 手册](../taos-sql/)。如果想更深入地了解各连接器的使用,请阅读[连接器参考指南](../reference/connector/)。如果还希望想将 TDengine 与第三方系统集成起来,比如 Grafana, 请参考[第三方工具](../third-party/)。 如果在开发过程中遇到任何问题,请点击每个页面下方的["反馈问题"](https://github.com/taosdata/TDengine/issues/new/choose), 在 GitHub 上直接递交 Issue。 diff --git a/docs/zh/14-reference/05-connector/index.md b/docs/zh/14-reference/05-connector/index.md index e3c7a0be3f..1e68dcc40e 100644 --- a/docs/zh/14-reference/05-connector/index.md +++ b/docs/zh/14-reference/05-connector/index.md @@ -12,13 +12,13 @@ TDengine 提供了丰富的应用程序开发接口,为了便于用户快速 目前 TDengine 的原生接口连接器可支持的平台包括:X64/ARM64 等硬件平台,以及 Linux/Win64 等开发环境。对照矩阵如下: -| **CPU** | **OS** | **Java** | **Python** | **Go** | **Node.js** | **C#** | **Rust** | C/C++ | -| -------------- | --------- | -------- | ---------- | ------ | ----------- | ------ | -------- | ----- | -| **X86 64bit** | **Linux** | ● | ● | ● | ● | ● | ● | ● | -| **X86 64bit** | **Win64** | ● | ● | ● | ● | ● | ● | ● | -| **X86 64bit** | **macOS** | ● | ● | ● | ○ | ○ | ● | ● | -| **ARM64** | **Linux** | ● | ● | ● | ● | ○ | ○ | ● | -| **ARM64** | **macOS** | ● | ● | ● | ○ | ○ | ● | ● | +| **CPU** | **OS** | **Java** | **Python** | **Go** | **Node.js** | **C#** | **Rust** | C/C++ | +| ------------- | --------- | -------- | ---------- | ------ | ----------- | ------ | -------- | ----- | +| **X86 64bit** | **Linux** | ● | ● | ● | ● | ● | ● | ● | +| **X86 64bit** | **Win64** | ● | ● | ● | ● | ● | ● | ● | +| **X86 64bit** | **macOS** | ● | ● | ● | ○ | ○ | ● | ● | +| **ARM64** | **Linux** | ● | ● | ● | ● | ○ | ○ | ● | +| **ARM64** | **macOS** | ● | ● | ● | ○ | ○ | ● | ● | 其中 ● 表示官方测试验证通过,○ 表示非官方测试验证通过,-- 表示未经验证。 @@ -30,7 +30,7 @@ TDengine 版本更新往往会增加新的功能特性,列表中的连接器 | **TDengine 版本** | **Java** | **Python** | **Go** | **C#** | **Node.js** | **Rust** | | ---------------------- | --------- | ---------- | ------------ | ------------- | --------------- | -------- | -| **3.0.0.0 及以上** | 3.0.2以上 | 当前版本 | 3.0 分支 | 3.0.0 | 3.0.0 | 当前版本 | +| **3.0.0.0 及以上** | 3.0.2以上 | 当前版本 | 3.0 分支 | 3.0.0 | 3.1.0 | 当前版本 | | **2.4.0.14 及以上** | 2.0.38 | 当前版本 | develop 分支 | 1.0.2 - 1.0.6 | 2.0.10 - 2.0.12 | 当前版本 | | **2.4.0.4 - 2.4.0.13** | 2.0.37 | 当前版本 | develop 分支 | 1.0.2 - 1.0.6 | 2.0.10 - 2.0.12 | 当前版本 | | **2.2.x.x ** | 2.0.36 | 当前版本 | master 分支 | n/a | 2.0.7 - 2.0.9 | 当前版本 | @@ -44,11 +44,11 @@ TDengine 版本更新往往会增加新的功能特性,列表中的连接器 | **功能特性** | **Java** | **Python** | **Go** | **C#** | **Node.js** | **Rust** | | ------------------- | -------- | ---------- | ------ | ------ | ----------- | -------- | -| **连接管理** | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | -| **普通查询** | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | -| **参数绑定** | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | -| **数据订阅(TMQ)** | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | -| **Schemaless** | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | +| **连接管理** | 支持 | 支持 | 支持 | 支持 | 不支持 | 支持 | +| **普通查询** | 支持 | 支持 | 支持 | 支持 | 不支持 | 支持 | +| **参数绑定** | 支持 | 支持 | 支持 | 支持 | 不支持 | 支持 | +| **数据订阅(TMQ)** | 支持 | 支持 | 支持 | 支持 | 不支持 | 支持 | +| **Schemaless** | 支持 | 支持 | 支持 | 支持 | 不支持 | 支持 | :::info 由于不同编程语言数据库框架规范不同,并不意味着所有 C/C++ 接口都需要对应封装支持。 @@ -56,14 +56,14 @@ TDengine 版本更新往往会增加新的功能特性,列表中的连接器 ### 使用 http (REST 或 WebSocket) 接口 -| **功能特性** | **Java** | **Python** | **Go** | **C# ** | **Node.js** | **Rust** | -| ------------------------------ | -------- | ---------- | -------- | ---- | ----------- | -------- | -| **连接管理** | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | -| **普通查询** | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | -| **参数绑定** | 支持 | 支持 | 支持 | 支持 | 暂不支持 | 支持 | -| **数据订阅(TMQ)** | 支持 | 支持 | 支持 | 支持 | 暂不支持 | 支持 | -| **Schemaless** | 支持 | 支持 | 支持 | 支持 | 暂不支持 | 支持 | -| **批量拉取(基于 WebSocket)** | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | +| **功能特性** | **Java** | **Python** | **Go** | **C# ** | **Node.js** | **Rust** | +| ------------------------------ | -------- | ---------- | ------ | ------- | ----------- | -------- | +| **连接管理** | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | +| **普通查询** | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | +| **参数绑定** | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | +| **数据订阅(TMQ)** | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | +| **Schemaless** | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | +| **批量拉取(基于 WebSocket)** | 支持 | 支持 | 支持 | 支持 | 支持 | 支持 | :::warning diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoopFull.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoopFull.java index 86a823bbb1..af3537ef0e 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoopFull.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoopFull.java @@ -52,16 +52,21 @@ public abstract class AbsConsumerLoopFull { public void pollData() throws SQLException { try { + // subscribe to the topics consumer.subscribe(topics); while (!shutdown.get()) { + // poll data ConsumerRecords records = consumer.poll(Duration.ofMillis(100)); for (ConsumerRecord record : records) { ResultBean bean = record.value(); + // process the data here process(bean); } } + // unsubscribe the topics consumer.unsubscribe(); } finally { + // close the consumer consumer.close(); shutdownLatch.countDown(); } @@ -76,6 +81,7 @@ public abstract class AbsConsumerLoopFull { } + // use this class to define the data structure of the result record public static class ResultBean { private Timestamp ts; private double current; diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsWsConsumerLoop.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsWsConsumerLoop.java index c622c20cba..5abfc95cae 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsWsConsumerLoop.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsWsConsumerLoop.java @@ -53,17 +53,22 @@ try { public void pollData() throws SQLException { try { + // Subscribe to the topic consumer.subscribe(topics); while (!shutdown.get()) { + // poll data ConsumerRecords records = consumer.poll(Duration.ofMillis(100)); for (ConsumerRecord record : records) { ResultBean bean = record.value(); + // process data here process(bean); } } + // unsubscribe the topics consumer.unsubscribe(); } finally { + // close the consumer consumer.close(); shutdownLatch.countDown(); } @@ -78,6 +83,7 @@ try { } + // use this class to define the data structure of the result record public static class ResultBean { private Timestamp ts; private double current; From a675425f5ddd6aa3c10e93e77669f7d25f0b1882 Mon Sep 17 00:00:00 2001 From: sheyanjie-qq <249478495@qq.com> Date: Wed, 31 Jul 2024 15:18:37 +0800 Subject: [PATCH 03/14] use table for properties --- docs/zh/08-develop/01-connect/index.md | 66 ++++++++------ docs/zh/14-reference/05-connector/14-java.mdx | 91 ++++++++++--------- 2 files changed, 85 insertions(+), 72 deletions(-) diff --git a/docs/zh/08-develop/01-connect/index.md b/docs/zh/08-develop/01-connect/index.md index 6392f324db..93da9c9266 100644 --- a/docs/zh/08-develop/01-connect/index.md +++ b/docs/zh/08-develop/01-connect/index.md @@ -279,43 +279,49 @@ TDengine 的 JDBC URL 规范格式为: **注意**:使用 JDBC 原生连接,taos-jdbcdriver 需要依赖客户端驱动(Linux 下是 libtaos.so;Windows 下是 taos.dll;macOS 下是 libtaos.dylib)。 url 中的配置参数如下: -- user:登录 TDengine 用户名,默认值 'root'。 -- password:用户登录密码,默认值 'taosdata'。 -- batchfetch: true:在执行查询时批量拉取结果集;false:逐行拉取结果集。默认值为:false。逐行拉取结果集使用 HTTP 方式进行数据传输。JDBC REST 连接支持批量拉取数据功能。taos-jdbcdriver 与 TDengine 之间通过 WebSocket 连接进行数据传输。相较于 HTTP,WebSocket 可以使 JDBC REST 连接支持大数据量查询,并提升查询性能。 -- charset: 当开启批量拉取数据时,指定解析字符串数据的字符集。 -- batchErrorIgnore:true:在执行 Statement 的 executeBatch 时,如果中间有一条 SQL 执行失败,继续执行下面的 SQL 了。false:不再执行失败 SQL 后的任何语句。默认值为:false。 -- httpConnectTimeout: 连接超时时间,单位 ms, 默认值为 60000。 -- httpSocketTimeout: socket 超时时间,单位 ms,默认值为 60000。仅在 batchfetch 设置为 false 时生效。 -- messageWaitTimeout: 消息超时时间, 单位 ms, 默认值为 60000。 仅在 batchfetch 设置为 true 时生效。 -- useSSL: 连接中是否使用 SSL。 -- httpPoolSize: REST 并发请求大小,默认 20。 + +| 参数 | 描述 | 默认值 | +| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | +| user | 登录 TDengine 用户名 | 'root' | +| password | 用户登录密码 | 'taosdata' | +| batchfetch | true:在执行查询时批量拉取结果集;false:逐行拉取结果集。逐行拉取结果集使用 HTTP 方式进行数据传输。JDBC REST 连接支持批量拉取数据功能。taos-jdbcdriver 与 TDengine 之间通过 WebSocket 连接进行数据传输。相较于 HTTP,WebSocket 可以使 JDBC REST 连接支持大数据量查询,并提升查询性能。 | false | +| charset | 当开启批量拉取数据时,指定解析字符串数据的字符集。 | | +| batchErrorIgnore | true:在执行 Statement 的 executeBatch 时,如果中间有一条 SQL 执行失败,继续执行下面的 SQL 了。false:不再执行失败 SQL 后的任何语句。 | false | +| httpConnectTimeout | 连接超时时间,单位 ms | 60000 | +| httpSocketTimeout | socket 超时时间,单位 ms,仅在 batchfetch 设置为 false 时生效。 | 60000 | +| messageWaitTimeout | 消息超时时间, 单位 ms,仅在 batchfetch 设置为 true 时生效。 | 60000 | +| useSSL | 连接中是否使用 SSL。 | | +| httpPoolSize | REST 并发请求大小,默认 20。 | 20 | **注意**:部分配置项(比如:locale、timezone)在 REST 连接中不生效。 除了通过指定的 URL 获取连接,还可以使用 Properties 指定建立连接时的参数。 -properties 中的配置参数如下: -- TSDBDriver.PROPERTY_KEY_USER:登录 TDengine 用户名,默认值 'root'。 -- TSDBDriver.PROPERTY_KEY_PASSWORD:用户登录密码,默认值 'taosdata'。 -- TSDBDriver.PROPERTY_KEY_BATCH_LOAD: true:在执行查询时批量拉取结果集;false:逐行拉取结果集。默认值为:false。 -- TSDBDriver.PROPERTY_KEY_BATCH_ERROR_IGNORE:true:在执行 Statement 的 executeBatch 时,如果中间有一条 SQL 执行失败,继续执行下面的 sq 了。false:不再执行失败 SQL 后的任何语句。默认值为:false。 -- TSDBDriver.PROPERTY_KEY_CONFIG_DIR:仅在使用 JDBC 原生连接时生效。客户端配置文件目录路径,Linux OS 上默认值 `/etc/taos`,Windows OS 上默认值 `C:/TDengine/cfg`。 -- TSDBDriver.PROPERTY_KEY_CHARSET:客户端使用的字符集,默认值为系统字符集。 -- TSDBDriver.PROPERTY_KEY_LOCALE:仅在使用 JDBC 原生连接时生效。 客户端语言环境,默认值系统当前 locale。 -- TSDBDriver.PROPERTY_KEY_TIME_ZONE:仅在使用 JDBC 原生连接时生效。 客户端使用的时区,默认值为系统当前时区。因为历史的原因,我们只支持POSIX标准的部分规范,如UTC-8(代表中国上上海), GMT-8,Asia/Shanghai 这几种形式。 -- TSDBDriver.HTTP_CONNECT_TIMEOUT: 连接超时时间,单位 ms, 默认值为 60000。仅在 REST 连接时生效。 -- TSDBDriver.HTTP_SOCKET_TIMEOUT: socket 超时时间,单位 ms,默认值为 60000。仅在 REST 连接且 batchfetch 设置为 false 时生效。 -- TSDBDriver.PROPERTY_KEY_MESSAGE_WAIT_TIMEOUT: 消息超时时间, 单位 ms, 默认值为 60000。 仅在 REST 连接且 batchfetch 设置为 true 时生效。 -- TSDBDriver.PROPERTY_KEY_USE_SSL: 连接中是否使用 SSL。仅在 REST 连接时生效。 -- TSDBDriver.HTTP_POOL_SIZE: REST 并发请求大小,默认 20。 -- TSDBDriver.PROPERTY_KEY_ENABLE_COMPRESSION: 传输过程是否启用压缩。仅在使用 REST/Websocket 连接时生效。true: 启用,false: 不启用。默认为 false。 -- TSDBDriver.PROPERTY_KEY_ENABLE_AUTO_RECONNECT: 是否启用自动重连。仅在使用 Websocket 连接时生效。true: 启用,false: 不启用。默认为 false。 -> **注意**:启用自动重连仅对简单执行 SQL 语句以及 无模式写入、数据订阅有效。对于参数绑定无效。自动重连仅对连接建立时通过参数指定数据库有效,对后面的 `use db` 语句切换数据库无效。 +properties 中的配置参数如下(**注意**:属性使用需要加上类名,如 `TSDBDriver.PROPERTY_KEY_USER` ): -- TSDBDriver.PROPERTY_KEY_RECONNECT_INTERVAL_MS: 自动重连重试间隔,单位毫秒,默认值 2000。仅在 PROPERTY_KEY_ENABLE_AUTO_RECONNECT 为 true 时生效。 -- TSDBDriver.PROPERTY_KEY_RECONNECT_RETRY_COUNT: 自动重连重试次数,默认值 3,仅在 PROPERTY_KEY_ENABLE_AUTO_RECONNECT 为 true 时生效。 -- TSDBDriver.PROPERTY_KEY_DISABLE_SSL_CERT_VALIDATION: 关闭 SSL 证书验证 。仅在使用 Websocket 连接时生效。true: 启用,false: 不启用。默认为 false。 +| 属性 | 描述 | 默认值 | +| ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | --------------- | +| PROPERTY_KEY_USER | 登录 TDengine 用户名 | 'root' | +| PROPERTY_KEY_PASSWORD | 用户登录密码 | 'taosdata' | +| PROPERTY_KEY_BATCH_LOAD | true:在执行查询时批量拉取结果集;false:逐行拉取结果集 | false | +| PROPERTY_KEY_BATCH_ERROR_IGNORE | true:在执行 Statement 的 executeBatch 时,如果中间有一条 SQL 执行失败,继续执行下面的 SQL;false:不再执行失败 SQL 后的任何语句 | false | +| PROPERTY_KEY_CONFIG_DIR | 仅在使用 JDBC 原生连接时生效。客户端配置文件目录路径,Linux OS 上默认值 /etc/taos,Windows OS 上默认值 C:/TDengine/cfg | 系统依赖 | +| PROPERTY_KEY_CHARSET | 客户端使用的字符集 | 系统字符集 | +| PROPERTY_KEY_LOCALE | 仅在使用 JDBC 原生连接时生效。客户端语言环境 | 系统当前 locale | +| PROPERTY_KEY_TIME_ZONE | 仅在使用 JDBC 原生连接时生效。客户端使用的时区 | 系统当前时区 | +| HTTP_CONNECT_TIMEOUT | 连接超时时间,单位 ms,仅在 REST 连接时生效 | 60000 | +| HTTP_SOCKET_TIMEOUT | socket 超时时间,单位 ms,仅在 REST 连接且 batchfetch 设置为 false 时生效 | 60000 | +| PROPERTY_KEY_MESSAGE_WAIT_TIMEOUT | 消息超时时间, 单位 ms,仅在 REST 连接且 batchfetch 设置为 true 时生效 | 60000 | +| PROPERTY_KEY_USE_SSL | 连接中是否使用 SSL。仅在 REST 连接时生效 | | +| HTTP_POOL_SIZE | REST 并发请求大小 | 20 | +| PROPERTY_KEY_ENABLE_COMPRESSION | 传输过程是否启用压缩。仅在使用 REST/Websocket 连接时生效 | false | +| PROPERTY_KEY_ENABLE_AUTO_RECONNECT | 是否启用自动重连。仅在使用 Websocket 连接时生效 | false | +| PROPERTY_KEY_RECONNECT_INTERVAL_MS | 自动重连重试间隔,单位毫秒。仅在 PROPERTY_KEY_ENABLE_AUTO_RECONNECT 为 true 时生效 | 2000 | +| PROPERTY_KEY_RECONNECT_RETRY_COUNT | 自动重连重试次数。仅在 PROPERTY_KEY_ENABLE_AUTO_RECONNECT 为 true 时生效 | 3 | +| PROPERTY_KEY_DISABLE_SSL_CERT_VALIDATION | 关闭 SSL 证书验证。仅在使用 Websocket 连接时生效 | false | + +> **注意**:启用自动重连仅对简单执行 SQL 语句以及 无模式写入、数据订阅有效。对于参数绑定无效。自动重连仅对连接建立时通过参数指定数据库有效,对后面的 `use db` 语句切换数据库无效。 **配置参数的优先级:** diff --git a/docs/zh/14-reference/05-connector/14-java.mdx b/docs/zh/14-reference/05-connector/14-java.mdx index 47a0625b9b..23b4392008 100644 --- a/docs/zh/14-reference/05-connector/14-java.mdx +++ b/docs/zh/14-reference/05-connector/14-java.mdx @@ -205,7 +205,7 @@ TDengine 的 JDBC URL 规范格式为: **注**:REST 连接中增加 `batchfetch` 参数并设置为 true,将开启 WebSocket 连接。 -##### 原生连接 +**原生连接** `jdbc:TAOS://taosdemo.com:6030/power?user=root&password=taosdata`,使用了 JDBC 原生连接的 TSDBDriver,建立了到 hostname 为 taosdemo.com,端口为 6030(TDengine 的默认端口),数据库名为 power 的连接。这个 URL 中指定用户名(user)为 root,密码(password)为 taosdata。 @@ -213,18 +213,20 @@ TDengine 的 JDBC URL 规范格式为: 对于原生连接 url 中支持的配置参数如下: -- user:登录 TDengine 用户名,默认值 'root'。 -- password:用户登录密码,默认值 'taosdata'。 -- cfgdir:客户端配置文件目录路径,Linux OS 上默认值 `/etc/taos`,Windows OS 上默认值 `C:/TDengine/cfg`。 -- charset:客户端使用的字符集,默认值为系统字符集。 -- locale:客户端语言环境,默认值系统当前 locale。 -- timezone:客户端使用的时区,默认值为系统当前时区。 -- batchfetch: true:在执行查询时批量拉取结果集;false:逐行拉取结果集。默认值为:true。开启批量拉取同时获取一批数据在查询数据量较大时批量拉取可以有效的提升查询性能。 -- batchErrorIgnore:true:在执行 Statement 的 executeBatch 时,如果中间有一条 SQL 执行失败将继续执行下面的 SQL。false:不再执行失败 SQL 后的任何语句。默认值为:false。 +| 属性 | 描述 | 默认值 | +|------------------|--------------------------------------------------------------------------------------------------------|-----------------| +| user | 登录 TDengine 用户名 | 'root' | +| password | 用户登录密码 | 'taosdata' | +| cfgdir | 客户端配置文件目录路径,Linux OS 上默认值 `/etc/taos`,Windows OS 上默认值 `C:/TDengine/cfg` | 系统依赖 | +| charset | 客户端使用的字符集 | 系统字符集 | +| locale | 客户端语言环境 | 系统当前 locale | +| timezone | 客户端使用的时区 | 系统当前时区 | +| batchfetch | 在执行查询时批量拉取结果集;false:逐行拉取结果集。开启批量拉取可以有效的提升查询性能 | true | +| batchErrorIgnore | true:在执行 Statement 的 executeBatch 时,如果中间有一条 SQL 执行失败将继续执行下面的 SQL。false:不再执行失败 SQL 后的任何语句 | false | JDBC 原生连接的使用请参见[视频教程](https://www.taosdata.com/blog/2020/11/11/1955.html)。 -**使用 TDengine 客户端驱动配置文件建立连接** +**使用 TDengine 客户端驱动配置文件建立连接** 当使用 JDBC 原生连接连接 TDengine 集群时,可以使用 TDengine 客户端驱动配置文件,在配置文件中指定集群的 firstEp、secondEp 等参数。 此时在 JDBC url 中不指定 `hostname` 和 `port`。 配置如 `jdbc:TAOS://:/power?user=root&password=taosdata`。 @@ -234,7 +236,7 @@ TDengine 中,只要保证 firstEp 和 secondEp 中一个节点有效,就可 > **注意**:这里的配置文件指的是调用 JDBC Connector 的应用程序所在机器上的配置文件,Linux OS 上默认值 /etc/taos/taos.cfg ,Windows OS 上默认值 C://TDengine/cfg/taos.cfg。 -##### Websocket 和 REST 连接 +**Websocket 和 REST 连接** 使用 JDBC Websocket 或 REST 连接,不需要依赖客户端驱动。与 JDBC 原生连接相比,仅需要: 1. driverClass 指定为“com.taosdata.jdbc.rs.RestfulDriver”; @@ -243,16 +245,19 @@ TDengine 中,只要保证 firstEp 和 secondEp 中一个节点有效,就可 对于 Websocket 和 REST 连接,url 中的配置参数如下: -- user:登录 TDengine 用户名,默认值 'root'。 -- password:用户登录密码,默认值 'taosdata'。 -- batchfetch: true:在执行查询时批量拉取结果集;false:逐行拉取结果集。默认值为:false。逐行拉取结果集使用 HTTP 方式进行数据传输。JDBC REST 连接支持批量拉取数据功能。taos-jdbcdriver 与 TDengine 之间通过 WebSocket 连接进行数据传输。相较于 HTTP,WebSocket 可以使 JDBC REST 连接支持大数据量查询,并提升查询性能。 -- charset: 当开启批量拉取数据时,指定解析字符串数据的字符集。 -- batchErrorIgnore:true:在执行 Statement 的 executeBatch 时,如果中间有一条 SQL 执行失败,继续执行下面的 SQL 了。false:不再执行失败 SQL 后的任何语句。默认值为:false。 -- httpConnectTimeout: 连接超时时间,单位 ms, 默认值为 60000。 -- httpSocketTimeout: socket 超时时间,单位 ms,默认值为 60000。仅在 batchfetch 设置为 false 时生效。 -- messageWaitTimeout: 消息超时时间, 单位 ms, 默认值为 60000。 仅在 batchfetch 设置为 true 时生效。 -- useSSL: 连接中是否使用 SSL。 -- httpPoolSize: REST 并发请求大小,默认 20。 +| 属性 | 描述 | 默认值 | +|-------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------| +| user | 登录 TDengine 用户名 | 'root' | +| password | 用户登录密码 | 'taosdata' | +| batchfetch | true:在执行查询时批量拉取结果集;false:逐行拉取结果集。逐行拉取结果集使用 HTTP 方式进行数据传输。JDBC REST 连接支持批量拉取数据功能。taos-jdbcdriver 与 TDengine 之间通过 WebSocket 连接进行数据传输,提升查询性能。 | false | +| charset | 当开启批量拉取数据时,指定解析字符串数据的字符集。 | | +| batchErrorIgnore | true:在执行 Statement 的 executeBatch 时,如果中间有一条 SQL 执行失败,继续执行下面的 SQL。false:不再执行失败 SQL 后的任何语句。 | false | +| httpConnectTimeout| 连接超时时间,单位 ms | 60000 | +| httpSocketTimeout | socket 超时时间,单位 ms。仅在 batchfetch 设置为 false 时生效。 | 60000 | +| messageWaitTimeout| 消息超时时间, 单位 ms。仅在 batchfetch 设置为 true 时生效。 | 60000 | +| useSSL | 连接中是否使用 SSL。 | | +| httpPoolSize | REST 并发请求大小 | 20 | + **注意**:部分配置项(比如:locale、timezone)在 REST 连接中不生效。 @@ -269,33 +274,35 @@ TDengine 中,只要保证 firstEp 和 secondEp 中一个节点有效,就可 > **注意**:应用中设置的 client parameter 为进程级别的,即如果要更新 client 的参数,需要重启应用。这是因为 client parameter 是全局参数,仅在应用程序的第一次设置生效。 -properties 中的配置参数如下: +properties 中的配置参数如下(**注意**:属性使用需要加上类名,如 `TSDBDriver.PROPERTY_KEY_USER` ): + +| 属性 | 描述 | 默认值 | +|-------------------------------------------|------------------------------------------------------------------------------------------------------------------------------|----------------------| +| PROPERTY_KEY_USER | 登录 TDengine 用户名 | 'root' | +| PROPERTY_KEY_PASSWORD | 用户登录密码 | 'taosdata' | +| PROPERTY_KEY_BATCH_LOAD | 在执行查询时批量拉取结果集;false:逐行拉取结果集 | false | +| PROPERTY_KEY_BATCH_ERROR_IGNORE | 在执行 Statement 的 executeBatch 时,如果中间有一条 SQL 执行失败,继续执行下面的 SQL。false:不再执行失败 SQL 后的任何语句。 | false | +| PROPERTY_KEY_CONFIG_DIR | 仅在使用 JDBC 原生连接时生效。客户端配置文件目录路径 | Linux: `/etc/taos`, Windows: `C:/TDengine/cfg` | +| PROPERTY_KEY_CHARSET | 客户端使用的字符集 | 系统字符集 | +| PROPERTY_KEY_LOCALE | 仅在使用 JDBC 原生连接时生效。客户端语言环境 | 系统当前 locale | +| PROPERTY_KEY_TIME_ZONE | 仅在使用 JDBC 原生连接时生效。客户端使用的时区 | 系统当前时区 | +| HTTP_CONNECT_TIMEOUT | 连接超时时间,单位 ms。仅在 REST 连接时生效。 | 60000 | +| HTTP_SOCKET_TIMEOUT | socket 超时时间,单位 ms。仅在 REST 连接且 batchfetch 设置为 false 时生效。 | 60000 | +| PROPERTY_KEY_MESSAGE_WAIT_TIMEOUT | 消息超时时间, 单位 ms。仅在 REST 连接且 batchfetch 设置为 true 时生效。 | 60000 | +| PROPERTY_KEY_USE_SSL | 连接中是否使用 SSL。仅在 REST 连接时生效。 | | +| HTTP_POOL_SIZE | REST 并发请求大小 | 20 | +| PROPERTY_KEY_ENABLE_COMPRESSION | 传输过程是否启用压缩。仅在使用 REST/Websocket 连接时生效。 | false | +| PROPERTY_KEY_ENABLE_AUTO_RECONNECT | 是否启用自动重连。仅在使用 Websocket 连接时生效。 | false | +| PROPERTY_KEY_RECONNECT_INTERVAL_MS | 自动重连重试间隔,单位毫秒。仅在 PROPERTY_KEY_ENABLE_AUTO_RECONNECT 为 true 时生效。 | 2000 | +| PROPERTY_KEY_RECONNECT_RETRY_COUNT | 自动重连重试次数。仅在 PROPERTY_KEY_ENABLE_AUTO_RECONNECT 为 true 时生效。 | 3 | +| PROPERTY_KEY_DISABLE_SSL_CERT_VALIDATION | 关闭 SSL 证书验证。仅在使用 Websocket 连接时生效。 | false | -- TSDBDriver.PROPERTY_KEY_USER:登录 TDengine 用户名,默认值 'root'。 -- TSDBDriver.PROPERTY_KEY_PASSWORD:用户登录密码,默认值 'taosdata'。 -- TSDBDriver.PROPERTY_KEY_BATCH_LOAD: true:在执行查询时批量拉取结果集;false:逐行拉取结果集。默认值为:false。 -- TSDBDriver.PROPERTY_KEY_BATCH_ERROR_IGNORE:true:在执行 Statement 的 executeBatch 时,如果中间有一条 SQL 执行失败,继续执行下面的 sq 了。false:不再执行失败 SQL 后的任何语句。默认值为:false。 -- TSDBDriver.PROPERTY_KEY_CONFIG_DIR:仅在使用 JDBC 原生连接时生效。客户端配置文件目录路径,Linux OS 上默认值 `/etc/taos`,Windows OS 上默认值 `C:/TDengine/cfg`。 -- TSDBDriver.PROPERTY_KEY_CHARSET:客户端使用的字符集,默认值为系统字符集。 -- TSDBDriver.PROPERTY_KEY_LOCALE:仅在使用 JDBC 原生连接时生效。 客户端语言环境,默认值系统当前 locale。 -- TSDBDriver.PROPERTY_KEY_TIME_ZONE:仅在使用 JDBC 原生连接时生效。 客户端使用的时区,默认值为系统当前时区。因为历史的原因,我们只支持POSIX标准的部分规范,如UTC-8(代表中国上上海), GMT-8,Asia/Shanghai 这几种形式。 -- TSDBDriver.HTTP_CONNECT_TIMEOUT: 连接超时时间,单位 ms, 默认值为 60000。仅在 REST 连接时生效。 -- TSDBDriver.HTTP_SOCKET_TIMEOUT: socket 超时时间,单位 ms,默认值为 60000。仅在 REST 连接且 batchfetch 设置为 false 时生效。 -- TSDBDriver.PROPERTY_KEY_MESSAGE_WAIT_TIMEOUT: 消息超时时间, 单位 ms, 默认值为 60000。 仅在 REST 连接且 batchfetch 设置为 true 时生效。 -- TSDBDriver.PROPERTY_KEY_USE_SSL: 连接中是否使用 SSL。仅在 REST 连接时生效。 -- TSDBDriver.HTTP_POOL_SIZE: REST 并发请求大小,默认 20。 -- TSDBDriver.PROPERTY_KEY_ENABLE_COMPRESSION: 传输过程是否启用压缩。仅在使用 REST/Websocket 连接时生效。true: 启用,false: 不启用。默认为 false。 -- TSDBDriver.PROPERTY_KEY_ENABLE_AUTO_RECONNECT: 是否启用自动重连。仅在使用 Websocket 连接时生效。true: 启用,false: 不启用。默认为 false。 > **注意**:启用自动重连仅对简单执行 SQL 语句以及 无模式写入、数据订阅有效。对于参数绑定无效。自动重连仅对连接建立时通过参数指定数据库有效,对后面的 `use db` 语句切换数据库无效。 -- TSDBDriver.PROPERTY_KEY_RECONNECT_INTERVAL_MS: 自动重连重试间隔,单位毫秒,默认值 2000。仅在 PROPERTY_KEY_ENABLE_AUTO_RECONNECT 为 true 时生效。 -- TSDBDriver.PROPERTY_KEY_RECONNECT_RETRY_COUNT: 自动重连重试次数,默认值 3,仅在 PROPERTY_KEY_ENABLE_AUTO_RECONNECT 为 true 时生效。 -- TSDBDriver.PROPERTY_KEY_DISABLE_SSL_CERT_VALIDATION: 关闭 SSL 证书验证 。仅在使用 Websocket 连接时生效。true: 启用,false: 不启用。默认为 false。 - 此外对 JDBC 原生连接,通过指定 URL 和 Properties 还可以指定其他参数,比如日志级别、SQL 长度等。更多详细配置请参考[客户端配置](../../reference/config/)。 -##### 配置参数的优先级 +**配置参数的优先级** 通过前面三种方式获取连接,如果配置参数在 url、Properties、客户端配置文件中有重复,则参数的`优先级由高到低`分别如下: From d3a70581434b6010f366615ab3ffda9b4e56a65c Mon Sep 17 00:00:00 2001 From: sheyanjie-qq <249478495@qq.com> Date: Wed, 31 Jul 2024 17:18:07 +0800 Subject: [PATCH 04/14] mod jdbc doc --- .../com/taos/example/JNIConnectExample.java | 6 +- .../com/taos/example/RESTConnectExample.java | 6 +- .../com/taos/example/WSConnectExample.java | 10 +- docs/zh/08-develop/01-connect/index.md | 62 +----------- docs/zh/08-develop/07-tmq.md | 96 +++++++++++-------- docs/zh/14-reference/05-connector/14-java.mdx | 29 +++--- .../com/taosdata/example/AbsConsumerLoop.java | 26 ++--- .../taosdata/example/AbsWsConsumerLoop.java | 5 +- .../com/taosdata/example/JdbcBasicDemo.java | 5 +- .../com/taosdata/example/JdbcCreatDBDemo.java | 5 +- .../taosdata/example/JdbcInsertDataDemo.java | 5 +- .../com/taosdata/example/JdbcQueryDemo.java | 5 +- .../com/taosdata/example/JdbcReqIdDemo.java | 5 +- .../example/ParameterBindingBasicDemo.java | 5 +- .../taosdata/example/SchemalessJniTest.java | 4 +- .../taosdata/example/SchemalessWsTest.java | 4 +- .../example/WSParameterBindingBasicDemo.java | 5 +- .../example/WSParameterBindingDemo.java | 4 +- .../example/WSParameterBindingFullDemo.java | 4 +- 19 files changed, 142 insertions(+), 149 deletions(-) diff --git a/docs/examples/java/src/main/java/com/taos/example/JNIConnectExample.java b/docs/examples/java/src/main/java/com/taos/example/JNIConnectExample.java index 24cf3c98ef..8905150a0a 100644 --- a/docs/examples/java/src/main/java/com/taos/example/JNIConnectExample.java +++ b/docs/examples/java/src/main/java/com/taos/example/JNIConnectExample.java @@ -25,8 +25,10 @@ public static void main(String[] args) throws SQLException { // you can use the connection for execute SQL here } catch (SQLException ex) { - // handle any errors - System.out.println("SQLException: " + ex.getMessage()); + // handle any errors, please refer to the JDBC specifications for detailed exceptions info + System.out.println("SQLState: " + ex.getSQLState()); + System.out.println("Error Code: " + ex.getErrorCode()); + System.out.println("Message: " + ex.getMessage()); } } // ANCHOR_END: main diff --git a/docs/examples/java/src/main/java/com/taos/example/RESTConnectExample.java b/docs/examples/java/src/main/java/com/taos/example/RESTConnectExample.java index 1eb4c0755e..cd129db699 100644 --- a/docs/examples/java/src/main/java/com/taos/example/RESTConnectExample.java +++ b/docs/examples/java/src/main/java/com/taos/example/RESTConnectExample.java @@ -14,8 +14,10 @@ public static void main(String[] args) throws SQLException { // you can use the connection for execute SQL here } catch (SQLException ex) { - // handle any errors - System.out.println("SQLException: " + ex.getMessage()); + // handle any errors, please refer to the JDBC specifications for detailed exceptions info + System.out.println("SQLState: " + ex.getSQLState()); + System.out.println("Error Code: " + ex.getErrorCode()); + System.out.println("Message: " + ex.getMessage()); } } // ANCHOR_END: main diff --git a/docs/examples/java/src/main/java/com/taos/example/WSConnectExample.java b/docs/examples/java/src/main/java/com/taos/example/WSConnectExample.java index b28f4c7ff8..3f417841b2 100644 --- a/docs/examples/java/src/main/java/com/taos/example/WSConnectExample.java +++ b/docs/examples/java/src/main/java/com/taos/example/WSConnectExample.java @@ -16,14 +16,20 @@ public static void main(String[] args) throws SQLException { String jdbcUrl = "jdbc:TAOS-RS://localhost:6041?user=root&password=taosdata"; Properties connProps = new Properties(); connProps.setProperty(TSDBDriver.PROPERTY_KEY_BATCH_LOAD, "true"); + connProps.setProperty(TSDBDriver.PROPERTY_KEY_ENABLE_AUTO_RECONNECT, "true"); + connProps.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); + connProps.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); + try (Connection conn = DriverManager.getConnection(jdbcUrl, connProps)){ System.out.println("Connected"); // you can use the connection for execute SQL here } catch (SQLException ex) { - // handle any errors - System.out.println("SQLException: " + ex.getMessage()); + // handle any errors, please refer to the JDBC specifications for detailed exceptions info + System.out.println("SQLState: " + ex.getSQLState()); + System.out.println("Error Code: " + ex.getErrorCode()); + System.out.println("Message: " + ex.getMessage()); } } // ANCHOR_END: main diff --git a/docs/zh/08-develop/01-connect/index.md b/docs/zh/08-develop/01-connect/index.md index 93da9c9266..29e363c019 100644 --- a/docs/zh/08-develop/01-connect/index.md +++ b/docs/zh/08-develop/01-connect/index.md @@ -269,69 +269,11 @@ phpize && ./configure --enable-swoole && make -j && make install -Java 连接器建立连接的参数有 URL 和 properties,下面分别详细介绍。 +Java 连接器建立连接的参数有 URL 和 Properties。 TDengine 的 JDBC URL 规范格式为: `jdbc:[TAOS|TAOS-RS]://[host_name]:[port]/[database_name]?[user={user}|&password={password}|&charset={charset}|&cfgdir={config_dir}|&locale={locale}|&timezone={timezone}]` -对于建立连接,原生连接与 REST 连接有细微不同。 -**注**:REST 连接中增加 `batchfetch` 参数并设置为 true,将开启 WebSocket 连接。 - -**注意**:使用 JDBC 原生连接,taos-jdbcdriver 需要依赖客户端驱动(Linux 下是 libtaos.so;Windows 下是 taos.dll;macOS 下是 libtaos.dylib)。 - -url 中的配置参数如下: - -| 参数 | 描述 | 默认值 | -| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | -| user | 登录 TDengine 用户名 | 'root' | -| password | 用户登录密码 | 'taosdata' | -| batchfetch | true:在执行查询时批量拉取结果集;false:逐行拉取结果集。逐行拉取结果集使用 HTTP 方式进行数据传输。JDBC REST 连接支持批量拉取数据功能。taos-jdbcdriver 与 TDengine 之间通过 WebSocket 连接进行数据传输。相较于 HTTP,WebSocket 可以使 JDBC REST 连接支持大数据量查询,并提升查询性能。 | false | -| charset | 当开启批量拉取数据时,指定解析字符串数据的字符集。 | | -| batchErrorIgnore | true:在执行 Statement 的 executeBatch 时,如果中间有一条 SQL 执行失败,继续执行下面的 SQL 了。false:不再执行失败 SQL 后的任何语句。 | false | -| httpConnectTimeout | 连接超时时间,单位 ms | 60000 | -| httpSocketTimeout | socket 超时时间,单位 ms,仅在 batchfetch 设置为 false 时生效。 | 60000 | -| messageWaitTimeout | 消息超时时间, 单位 ms,仅在 batchfetch 设置为 true 时生效。 | 60000 | -| useSSL | 连接中是否使用 SSL。 | | -| httpPoolSize | REST 并发请求大小,默认 20。 | 20 | - - -**注意**:部分配置项(比如:locale、timezone)在 REST 连接中不生效。 - - -除了通过指定的 URL 获取连接,还可以使用 Properties 指定建立连接时的参数。 -properties 中的配置参数如下(**注意**:属性使用需要加上类名,如 `TSDBDriver.PROPERTY_KEY_USER` ): - -| 属性 | 描述 | 默认值 | -| ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | --------------- | -| PROPERTY_KEY_USER | 登录 TDengine 用户名 | 'root' | -| PROPERTY_KEY_PASSWORD | 用户登录密码 | 'taosdata' | -| PROPERTY_KEY_BATCH_LOAD | true:在执行查询时批量拉取结果集;false:逐行拉取结果集 | false | -| PROPERTY_KEY_BATCH_ERROR_IGNORE | true:在执行 Statement 的 executeBatch 时,如果中间有一条 SQL 执行失败,继续执行下面的 SQL;false:不再执行失败 SQL 后的任何语句 | false | -| PROPERTY_KEY_CONFIG_DIR | 仅在使用 JDBC 原生连接时生效。客户端配置文件目录路径,Linux OS 上默认值 /etc/taos,Windows OS 上默认值 C:/TDengine/cfg | 系统依赖 | -| PROPERTY_KEY_CHARSET | 客户端使用的字符集 | 系统字符集 | -| PROPERTY_KEY_LOCALE | 仅在使用 JDBC 原生连接时生效。客户端语言环境 | 系统当前 locale | -| PROPERTY_KEY_TIME_ZONE | 仅在使用 JDBC 原生连接时生效。客户端使用的时区 | 系统当前时区 | -| HTTP_CONNECT_TIMEOUT | 连接超时时间,单位 ms,仅在 REST 连接时生效 | 60000 | -| HTTP_SOCKET_TIMEOUT | socket 超时时间,单位 ms,仅在 REST 连接且 batchfetch 设置为 false 时生效 | 60000 | -| PROPERTY_KEY_MESSAGE_WAIT_TIMEOUT | 消息超时时间, 单位 ms,仅在 REST 连接且 batchfetch 设置为 true 时生效 | 60000 | -| PROPERTY_KEY_USE_SSL | 连接中是否使用 SSL。仅在 REST 连接时生效 | | -| HTTP_POOL_SIZE | REST 并发请求大小 | 20 | -| PROPERTY_KEY_ENABLE_COMPRESSION | 传输过程是否启用压缩。仅在使用 REST/Websocket 连接时生效 | false | -| PROPERTY_KEY_ENABLE_AUTO_RECONNECT | 是否启用自动重连。仅在使用 Websocket 连接时生效 | false | -| PROPERTY_KEY_RECONNECT_INTERVAL_MS | 自动重连重试间隔,单位毫秒。仅在 PROPERTY_KEY_ENABLE_AUTO_RECONNECT 为 true 时生效 | 2000 | -| PROPERTY_KEY_RECONNECT_RETRY_COUNT | 自动重连重试次数。仅在 PROPERTY_KEY_ENABLE_AUTO_RECONNECT 为 true 时生效 | 3 | -| PROPERTY_KEY_DISABLE_SSL_CERT_VALIDATION | 关闭 SSL 证书验证。仅在使用 Websocket 连接时生效 | false | - -> **注意**:启用自动重连仅对简单执行 SQL 语句以及 无模式写入、数据订阅有效。对于参数绑定无效。自动重连仅对连接建立时通过参数指定数据库有效,对后面的 `use db` 语句切换数据库无效。 - -**配置参数的优先级:** - -通过前面三种方式获取连接,如果配置参数在 url、Properties、客户端配置文件中有重复,则参数的**优先级由高到低**分别如下: - -1. JDBC URL 参数,如上所述,可以在 JDBC URL 的参数中指定。 -2. Properties connProps -3. 使用原生连接时,TDengine 客户端驱动的配置文件 taos.cfg - -例如:在 url 中指定了 password 为 taosdata,在 Properties 中指定了 password 为 taosdemo,那么,JDBC 会使用 url 中的 password 建立连接。 +URL 和 Properties 的详细参数说明和如何使用详见 [API 说明](../../reference/connector/java/#url-规范) diff --git a/docs/zh/08-develop/07-tmq.md b/docs/zh/08-develop/07-tmq.md index e6d866c29c..f548126e49 100644 --- a/docs/zh/08-develop/07-tmq.md +++ b/docs/zh/08-develop/07-tmq.md @@ -7,7 +7,7 @@ toc_max_heading_level: 4 import Tabs from "@theme/Tabs"; import TabItem from "@theme/TabItem"; -TDengine 提供了类似于消息队列产品的数据订阅和消费接口。在许多场景中,采用TDengine 的时序大数据平台,无须再集成消息队列产品,从而简化应用程序设计并降低运维成本。本章介绍各语言连接器数据订阅的相关API以及使用方法。 数据订阅的基础知识请参考 [数据订阅](../../advanced/subscription/) +TDengine 提供了类似于消息队列产品的数据订阅和消费接口。在许多场景中,采用 TDengine 的时序大数据平台,无须再集成消息队列产品,从而简化应用程序设计并降低运维成本。本章介绍各语言连接器数据订阅的相关 API 以及使用方法。 数据订阅的基础知识请参考 [数据订阅](../../advanced/subscription/) ## 创建主题 请用 taos shell 或者 参考 [执行 SQL](../sql/) 章节用程序执行创建主题的 SQL:`CREATE TOPIC IF NOT EXISTS topic_meters AS SELECT ts, current, voltage, phase, groupid, location FROM meters` @@ -16,7 +16,7 @@ TDengine 提供了类似于消息队列产品的数据订阅和消费接口。 **注意** 在 TDengine 连接器实现中,对于订阅查询,有以下限制。 -- 查询语句限制:订阅查询只能使用 select 语句,不支持其他类型的SQL,如 insert、update或delete等。 +- 查询语句限制:订阅查询只能使用 select 语句,不支持其他类型的SQL,如 insert、update 或 delete 等。 - 原始始数据查询:订阅查询只能查询原始数据,而不能查询聚合或计算结果。 - 时间顺序限制:订阅查询只能按照时间正序查询数据。 @@ -26,32 +26,29 @@ TDengine 消费者的概念跟 Kafka 类似,消费者通过订阅主题来接 ### 创建参数 -创建消费者的参数较多,非常灵活的支持了各种连接类型、 Offset 提交方式、压缩、重连、反序列化等特性,下面单独介绍各语言连接器创建消费者的参数。 +创建消费者的参数较多,非常灵活的支持了各种连接类型、 Offset 提交方式、压缩、重连、反序列化等特性。各语言连接器都适用的通用基础配置项如下表所示: +| 参数名称 | 类型 | 参数说明 | 备注 | +| :-----------------------: | :-----: | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `td.connect.ip` | string | 服务端的 IP 地址 | | +| `td.connect.user` | string | 用户名 | | +| `td.connect.pass` | string | 密码 | | +| `td.connect.port` | integer | 服务端的端口号 | | +| `group.id` | string | 消费组 ID,同一消费组共享消费进度 |
**必填项**。最大长度:192。
每个topic最多可建立100个 consumer group | +| `client.id` | string | 客户端 ID | 最大长度:192。 | +| `auto.offset.reset` | enum | 消费组订阅的初始位置 |
`earliest`: default(version < 3.2.0.0);从头开始订阅;
`latest`: default(version >= 3.2.0.0);仅从最新数据开始订阅;
`none`: 没有提交的 offset 无法订阅 | +| `enable.auto.commit` | boolean | 是否启用消费位点自动提交,true: 自动提交,客户端应用无需commit;false:客户端应用需要自行commit | 默认值为 true | +| `auto.commit.interval.ms` | integer | 消费记录自动提交消费位点时间间隔,单位为毫秒 | 默认值为 5000 | +| `msg.with.table.name` | boolean | 是否允许从消息中解析表名, 不适用于列订阅(列订阅时可将 tbname 作为列写入 subquery 语句)(从3.2.0.0版本该参数废弃,恒为true) | 默认关闭 | +| `enable.replay` | boolean | 是否开启数据回放功能 | 默认关闭 | + + +下面是各语言连接器创建参数: -Java 连接器创建消费者的参数为 Properties, 可以设置如下参数: +Java 连接器创建消费者的参数为 Properties, 可以设置的参数列表请参考 [API 说明](../../reference/connector/java/#消费者) +其他参数请参考上文通用基础配置项。 -- td.connect.type: 连接方式。jni:表示使用动态库连接的方式,ws/WebSocket:表示使用 WebSocket 进行数据通信。默认为 jni 方式。 -- bootstrap.servers: TDengine 服务端所在的`ip:port`,如果使用 WebSocket 连接,则为 taosAdapter 所在的`ip:port`。 -- enable.auto.commit: 是否允许自动提交。 -- group.id: consumer: 所在的 group。 -- value.deserializer: 结果集反序列化方法,可以继承 `com.taosdata.jdbc.tmq.ReferenceDeserializer`,并指定结果集 bean,实现反序列化。也可以继承 `com.taosdata.jdbc.tmq.Deserializer`,根据 SQL 的 resultSet 自定义反序列化方式。 -- httpConnectTimeout: 创建连接超时参数,单位 ms,默认为 5000 ms。仅在 WebSocket 连接下有效。 -- messageWaitTimeout: 数据传输超时参数,单位 ms,默认为 10000 ms。仅在 WebSocket 连接下有效。 -- httpPoolSize: 同一个连接下最大并行请求数。仅在 WebSocket 连接下有效。 -- TSDBDriver.PROPERTY_KEY_ENABLE_COMPRESSION: 传输过程是否启用压缩。仅在使用 Websocket 连接时生效。true: 启用,false: 不启用。默认为 false。 -- TSDBDriver.PROPERTY_KEY_ENABLE_AUTO_RECONNECT: 是否启用自动重连。仅在使用 Websocket 连接时生效。true: 启用,false: 不启用。默认为 false。 -- TSDBDriver.PROPERTY_KEY_RECONNECT_INTERVAL_MS: 自动重连重试间隔,单位毫秒,默认值 2000。仅在 PROPERTY_KEY_ENABLE_AUTO_RECONNECT 为 true 时生效。 -- TSDBDriver.PROPERTY_KEY_RECONNECT_RETRY_COUNT: 自动重连重试次数,默认值 3,仅在 PROPERTY_KEY_ENABLE_AUTO_RECONNECT 为 true 时生效。 - -其他参数请参考:[Consumer 参数列表](../../develop/tmq/#数据订阅相关参数), 注意TDengine服务端自 3.2.0.0 版本开始消息订阅中的 auto.offset.reset 默认值发生变化。 - -:::note - -- Java 连接器数据订阅 WebSocket 连接方式跟 原生连接方式,除了在创建消费者时参数不同之外,其他接口并无区别。因此我们以 Websocket 连接方式为例介绍数据订阅的其他功能。 - -::: @@ -81,6 +78,7 @@ Java 连接器创建消费者的参数为 Properties, 可以设置如下参数 ### Websocket 连接 +介绍各语言连接器使用 Websocket 连接方式创建消费者。 @@ -128,6 +126,8 @@ Java 连接器创建消费者的参数为 Properties, 可以设置如下参数 ### 原生连接 +介绍各语言连接器使用原生连接方式创建消费者。 + @@ -271,20 +271,27 @@ Java 连接器创建消费者的参数为 Properties, 可以设置如下参数 ```java -// 获取订阅的 topicPartition -Set assignment() throws SQLException; -// 指定下一次 poll 中使用的 offset +// 获取指定分区的当前偏移量 +long position(TopicPartition partition) throws SQLException; +// 获取指定主题的所有分区的当前偏移量 +Map position(String topic) throws SQLException; +// 获取指定主题的所有分区的起始偏移量 +Map beginningOffsets(String topic) throws SQLException; +// 获取指定主题的所有分区的最新偏移量 +Map endOffsets(String topic) throws SQLException; +// 获取指定分区集合中的已提交偏移量 +Map committed(Set partitions) throws SQLException; + +// 设置指定分区的偏移量 void seek(TopicPartition partition, long offset) throws SQLException; -void seekToBeginning(Collection partitions) throws SQLException; +// 将指定分区集合的偏移量设置为最新 +void seekToEnd(Collection partitions) throws SQLException; ``` 示例代码: @@ -381,11 +388,16 @@ void seekToEnd(Collection ```java -void commitSync() throws SQLException; -void commitSync(Map offsets) throws SQLException; + // 异步提交仅在 native 连接下有效 -void commitAsync(OffsetCommitCallback callback) throws SQLException; +// 异步提交指定的偏移量,需要提供回调以处理可能的提交结果 +void commitAsync(Map offsets, OffsetCommitCallback callback) throws SQLException; ``` @@ -583,7 +595,8 @@ void commitAsync(Map @@ -630,6 +643,9 @@ void commitAsync(Map diff --git a/docs/zh/14-reference/05-connector/14-java.mdx b/docs/zh/14-reference/05-connector/14-java.mdx index 23b4392008..acb1dee674 100644 --- a/docs/zh/14-reference/05-connector/14-java.mdx +++ b/docs/zh/14-reference/05-connector/14-java.mdx @@ -1348,18 +1348,23 @@ JDBC 标准不支持数据订阅,因此本章所有接口都是扩展接口。 - **异常**:如果创建失败,抛出 SQLException 异常。 创建消费者支持属性列表: -- td.connect.type: 连接方式。jni:表示使用动态库连接的方式,ws/WebSocket:表示使用 WebSocket 进行数据通信。默认为 jni 方式。 -- bootstrap.servers: TDengine 服务端所在的`ip:port`,如果使用 WebSocket 连接,则为 taosAdapter 所在的`ip:port`。 -- enable.auto.commit: 是否允许自动提交。 -- group.id: consumer: 所在的 group。 -- value.deserializer: 结果集反序列化方法,可以继承 `com.taosdata.jdbc.tmq.ReferenceDeserializer`,并指定结果集 bean,实现反序列化。也可以继承 `com.taosdata.jdbc.tmq.Deserializer`,根据 SQL 的 resultSet 自定义反序列化方式。 -- httpConnectTimeout: 创建连接超时参数,单位 ms,默认为 5000 ms。仅在 WebSocket 连接下有效。 -- messageWaitTimeout: 数据传输超时参数,单位 ms,默认为 10000 ms。仅在 WebSocket 连接下有效。 -- httpPoolSize: 同一个连接下最大并行请求数。仅在 WebSocket 连接下有效。 -- TSDBDriver.PROPERTY_KEY_ENABLE_COMPRESSION: 传输过程是否启用压缩。仅在使用 Websocket 连接时生效。true: 启用,false: 不启用。默认为 false。 -- TSDBDriver.PROPERTY_KEY_ENABLE_AUTO_RECONNECT: 是否启用自动重连。仅在使用 Websocket 连接时生效。true: 启用,false: 不启用。默认为 false。 -- TSDBDriver.PROPERTY_KEY_RECONNECT_INTERVAL_MS: 自动重连重试间隔,单位毫秒,默认值 2000。仅在 PROPERTY_KEY_ENABLE_AUTO_RECONNECT 为 true 时生效。 -- TSDBDriver.PROPERTY_KEY_RECONNECT_RETRY_COUNT: 自动重连重试次数,默认值 3,仅在 PROPERTY_KEY_ENABLE_AUTO_RECONNECT 为 true 时生效。 + + +| 属性 | 描述 | 默认值 | +| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | +| td.connect.type | 连接方式。jni:表示使用动态库连接的方式,ws/WebSocket:表示使用 WebSocket 进行数据通信。 | jni | +| bootstrap.servers | TDengine 服务端所在的ip:port,如果使用 WebSocket 连接,则为 taosAdapter 所在的ip:port。 | | +| enable.auto.commit | 是否允许自动提交。 | | +| group.id | consumer 所在的 group。 | | +| value.deserializer | 结果集反序列化方法。可以继承 com.taosdata.jdbc.tmq.ReferenceDeserializer,并指定结果集 bean,实现反序列化。也可以继承 com.taosdata.jdbc.tmq.Deserializer,根据 SQL 的 resultSet 自定义反序列化方式。 | | +| httpConnectTimeout | 创建连接超时参数,单位 ms。仅在 WebSocket 连接下有效。 | 5000 ms | +| messageWaitTimeout | 数据传输超时参数,单位 ms。仅在 WebSocket 连接下有效。 | 10000 ms | +| httpPoolSize | 同一个连接下最大并行请求数。仅在 WebSocket 连接下有效。 | | +| enableCompression | 传输过程是否启用压缩。仅在使用 Websocket 连接时生效。true: 启用,false: 不启用。 | false | +| enableAutoReconnect | 是否启用自动重连。仅在使用 Websocket 连接时生效。true: 启用,false: 不启用。 | false | +| reconnectIntervalMs | 自动重连重试间隔,单位毫秒。仅在 enableCompression 为 true 时生效。 | 2000 ms | +| reconnectRetryCount | 自动重连重试次数。仅在 enableCompression 为 true 时生效。 | 3 | + 其他参数请参考:[Consumer 参数列表](../../develop/tmq/#数据订阅相关参数), 注意TDengine服务端自 3.2.0.0 版本开始消息订阅中的 auto.offset.reset 默认值发生变化。 - `public void subscribe(Collection topics) throws SQLException` diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoop.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoop.java index d3a484dc43..62e3939573 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoop.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoop.java @@ -38,8 +38,9 @@ config.setProperty("value.deserializer.encoding", "UTF-8"); try { this.consumer = new TaosConsumer<>(config); } catch (SQLException ex) { - // handle exception - System.out.println("SQLException: " + ex.getMessage()); + // handle any errors, please refer to the JDBC specifications for detailed exceptions info + System.out.println("Error Code: " + ex.getErrorCode()); + System.out.println("Message: " + ex.getMessage()); throw new SQLException("Failed to create consumer", ex); } // ANCHOR_END: create_consumer @@ -63,9 +64,10 @@ try { process(bean); } } -} catch (Exception ex){ - // handle exception - System.out.println("SQLException: " + ex.getMessage()); +} catch (SQLException ex){ + // handle any errors, please refer to the JDBC specifications for detailed exceptions info + System.out.println("Error Code: " + ex.getErrorCode()); + System.out.println("Message: " + ex.getMessage()); } finally { consumer.close(); @@ -90,9 +92,10 @@ try { consumer.commitSync(); } } -} catch (Exception ex){ - // handle exception - System.out.println("SQLException: " + ex.getMessage()); +} catch (SQLException ex){ + // handle any errors, please refer to the JDBC specifications for detailed exceptions info + System.out.println("Error Code: " + ex.getErrorCode()); + System.out.println("Message: " + ex.getMessage()); } finally { consumer.close(); @@ -105,9 +108,10 @@ try { // ANCHOR: unsubscribe_data_code_piece try { consumer.unsubscribe(); -} catch (Exception ex){ - // handle exception - System.out.println("SQLException: " + ex.getMessage()); +} catch (SQLException ex){ + // handle any errors, please refer to the JDBC specifications for detailed exceptions info + System.out.println("Error Code: " + ex.getErrorCode()); + System.out.println("Message: " + ex.getMessage()); } finally { consumer.close(); } diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsWsConsumerLoop.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsWsConsumerLoop.java index 5abfc95cae..98ff5657d8 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsWsConsumerLoop.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsWsConsumerLoop.java @@ -38,8 +38,9 @@ config.setProperty("value.deserializer.encoding", "UTF-8"); try { this.consumer = new TaosConsumer<>(config); } catch (SQLException ex) { - // handle exception - System.out.println("SQLException: " + ex.getMessage()); + // handle any errors, please refer to the JDBC specifications for detailed exceptions info + System.out.println("Error Code: " + ex.getErrorCode()); + System.out.println("Message: " + ex.getMessage()); throw new SQLException("Failed to create consumer", ex); } // ANCHOR_END: create_consumer diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcBasicDemo.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcBasicDemo.java index ca5813710b..4831567eab 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcBasicDemo.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcBasicDemo.java @@ -109,8 +109,9 @@ try (Statement statement = connection.createStatement(); } // ANCHOR_END: jdbc_exception } catch (SQLException ex) { - // handle any errors - System.out.println("SQLException: " + ex.getMessage()); + // handle any errors, please refer to the JDBC specifications for detailed exceptions info + System.out.println("Error Code: " + ex.getErrorCode()); + System.out.println("Message: " + ex.getMessage()); } } diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcCreatDBDemo.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcCreatDBDemo.java index 0f12b6828c..b2246e96cf 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcCreatDBDemo.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcCreatDBDemo.java @@ -43,8 +43,9 @@ try (Connection connection = DriverManager.getConnection(url, properties); assert rowsAffected == 0; } catch (SQLException ex) { - // handle any errors - System.out.println("SQLException: " + ex.getMessage()); + // handle any errors, please refer to the JDBC specifications for detailed exceptions info + System.out.println("Error Code: " + ex.getErrorCode()); + System.out.println("Message: " + ex.getMessage()); } // ANCHOR_END: create_db_and_table diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcInsertDataDemo.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcInsertDataDemo.java index e56a47279b..76e16c9cee 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcInsertDataDemo.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcInsertDataDemo.java @@ -41,8 +41,9 @@ try (Connection connection = DriverManager.getConnection(url, properties); // you can check affectedRows here System.out.println("insert " + affectedRows + " rows."); } catch (SQLException ex) { - // handle any errors - System.out.println("SQLException: " + ex.getMessage()); + // handle any errors, please refer to the JDBC specifications for detailed exceptions info + System.out.println("Error Code: " + ex.getErrorCode()); + System.out.println("Message: " + ex.getMessage()); } // ANCHOR_END: insert_data } diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcQueryDemo.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcQueryDemo.java index d0cc362bbe..fdbab204c2 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcQueryDemo.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcQueryDemo.java @@ -42,8 +42,9 @@ try (Connection connection = DriverManager.getConnection(url, properties); System.out.printf("%s, %f, %s\n", ts, current, location); } } catch (SQLException ex) { - // handle any errors - System.out.println("SQLException: " + ex.getMessage()); + // handle any errors, please refer to the JDBC specifications for detailed exceptions info + System.out.println("Error Code: " + ex.getErrorCode()); + System.out.println("Message: " + ex.getMessage()); } // ANCHOR_END: query_data } diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcReqIdDemo.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcReqIdDemo.java index 1c44c2916e..5fb7e9760e 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcReqIdDemo.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcReqIdDemo.java @@ -42,8 +42,9 @@ try (Connection connection = DriverManager.getConnection(url, properties); } } } catch (SQLException ex) { - // handle any errors - System.out.println("SQLException: " + ex.getMessage()); + // handle any errors, please refer to the JDBC specifications for detailed exceptions info + System.out.println("Error Code: " + ex.getErrorCode()); + System.out.println("Message: " + ex.getMessage()); } // ANCHOR_END: with_reqid } diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ParameterBindingBasicDemo.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ParameterBindingBasicDemo.java index ee70049dba..d5f547b50f 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ParameterBindingBasicDemo.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ParameterBindingBasicDemo.java @@ -69,8 +69,9 @@ public class ParameterBindingBasicDemo { pstmt.columnDataExecuteBatch(); } } catch (SQLException ex) { - // handle any errors - System.out.println("SQLException: " + ex.getMessage()); + // handle any errors, please refer to the JDBC specifications for detailed exceptions info + System.out.println("Error Code: " + ex.getErrorCode()); + System.out.println("Message: " + ex.getMessage()); } } diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/SchemalessJniTest.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/SchemalessJniTest.java index 61d1acf08b..238ad35502 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/SchemalessJniTest.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/SchemalessJniTest.java @@ -26,7 +26,9 @@ public class SchemalessJniTest { conn.write(telnetDemo, SchemalessProtocolType.TELNET, SchemalessTimestampType.MILLI_SECONDS); conn.write(jsonDemo, SchemalessProtocolType.JSON, SchemalessTimestampType.NOT_CONFIGURED); } catch (SQLException ex) { - System.out.println("SQLException: " + ex.getMessage()); + // handle any errors, please refer to the JDBC specifications for detailed exceptions info + System.out.println("Error Code: " + ex.getErrorCode()); + System.out.println("Message: " + ex.getMessage()); } } diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/SchemalessWsTest.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/SchemalessWsTest.java index 4c7a93981a..ed5444a4ec 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/SchemalessWsTest.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/SchemalessWsTest.java @@ -26,7 +26,9 @@ public class SchemalessWsTest { conn.write(telnetDemo, SchemalessProtocolType.TELNET, SchemalessTimestampType.MILLI_SECONDS); conn.write(jsonDemo, SchemalessProtocolType.JSON, SchemalessTimestampType.SECONDS); } catch (SQLException ex) { - System.out.println("SQLException: " + ex.getMessage()); + // handle any errors, please refer to the JDBC specifications for detailed exceptions info + System.out.println("Error Code: " + ex.getErrorCode()); + System.out.println("Message: " + ex.getMessage()); } } diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WSParameterBindingBasicDemo.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WSParameterBindingBasicDemo.java index 72a6d0e887..9501d4adab 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WSParameterBindingBasicDemo.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WSParameterBindingBasicDemo.java @@ -48,8 +48,9 @@ public class WSParameterBindingBasicDemo { } } } catch (SQLException ex) { - // handle any errors - System.out.println("SQLException: " + ex.getMessage()); + // handle any errors, please refer to the JDBC specifications for detailed exceptions info + System.out.println("Error Code: " + ex.getErrorCode()); + System.out.println("Message: " + ex.getMessage()); } } diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WSParameterBindingDemo.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WSParameterBindingDemo.java index 75261e93e5..a4d3bf2659 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WSParameterBindingDemo.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WSParameterBindingDemo.java @@ -36,7 +36,9 @@ public class WSParameterBindingDemo { bindString(conn); } catch (SQLException ex) { - System.out.println("SQLException: " + ex.getMessage()); + // handle any errors, please refer to the JDBC specifications for detailed exceptions info + System.out.println("Error Code: " + ex.getErrorCode()); + System.out.println("Message: " + ex.getMessage()); } } diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WSParameterBindingFullDemo.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WSParameterBindingFullDemo.java index f9cf5cc992..5d63ce8bf3 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WSParameterBindingFullDemo.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WSParameterBindingFullDemo.java @@ -38,7 +38,9 @@ public class WSParameterBindingFullDemo { bindString(conn); } catch (SQLException ex) { - System.out.println("SQLException: " + ex.getMessage()); + // handle any errors, please refer to the JDBC specifications for detailed exceptions info + System.out.println("Error Code: " + ex.getErrorCode()); + System.out.println("Message: " + ex.getMessage()); } } From 46591c88f394cd4066e2f2bc8553a9af80316e35 Mon Sep 17 00:00:00 2001 From: sheyanjie-qq <249478495@qq.com> Date: Wed, 31 Jul 2024 17:21:41 +0800 Subject: [PATCH 05/14] mod jdbc doc --- docs/zh/08-develop/02-sql.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/docs/zh/08-develop/02-sql.md b/docs/zh/08-develop/02-sql.md index 4fef3c8659..eec1bcd70b 100644 --- a/docs/zh/08-develop/02-sql.md +++ b/docs/zh/08-develop/02-sql.md @@ -11,7 +11,6 @@ TDengine 对 SQL 语言提供了全面的支持,允许用户以熟悉的 SQL 下面介绍使用各语言连接器通过执行 SQL 完成建库、建表、写入数据和查询数据。 - ## 建库和表 以智能电表为例,展示如何使用连接器执行 SQL 来创建数据库和表。 @@ -70,7 +69,6 @@ NOW 为系统内部函数,默认为客户端所在计算机当前时间。 NOW - ## 查询数据 以智能电表为例,展示如何使用各语言连接器执行 SQL 来查询数据,并将获取到的结果打印出来。 @@ -100,7 +98,6 @@ NOW 为系统内部函数,默认为客户端所在计算机当前时间。 NOW - ## 执行带有 reqId 的 SQL reqId 可用于请求链路追踪,reqId 就像分布式系统中的 traceId 作用一样。一个请求可能需要经过多个服务或者模块才能完成。reqId 用于标识和关联这个请求的所有相关操作,以便于我们可以追踪和分析请求的完整路径。 From 31bdddde5706766250f7a3f4671938e7429fc6fb Mon Sep 17 00:00:00 2001 From: t_max <1172915550@qq.com> Date: Thu, 1 Aug 2024 13:55:01 +0800 Subject: [PATCH 06/14] docs: go and csharp api reference documentation --- docs/zh/14-reference/05-connector/20-go.mdx | 801 +++++++++++++++++- .../14-reference/05-connector/40-csharp.mdx | 738 ++++++++++++++++ 2 files changed, 1538 insertions(+), 1 deletion(-) diff --git a/docs/zh/14-reference/05-connector/20-go.mdx b/docs/zh/14-reference/05-connector/20-go.mdx index 97fc474e44..0c3dfa6681 100644 --- a/docs/zh/14-reference/05-connector/20-go.mdx +++ b/docs/zh/14-reference/05-connector/20-go.mdx @@ -396,4 +396,803 @@ TDengine Go 连接器支持订阅功能,应用 API 如下: ## API 参考 -全部 API 见 [driver-go 文档](https://pkg.go.dev/github.com/taosdata/driver-go/v3) +### database/sql 驱动 + +`driver-go` 实现了 Go 的 `database/sql/driver` 接口,可以直接使用 Go 的 `database/sql` 包。提供了三个驱动:`github.com/taosdata/driver-go/v3/taosSql` 、`github.com/taosdata/driver-go/v3/taosRestful` 和 `github.com/taosdata/driver-go/v3/taosWS` 分别对应 `原生连接`、`REST 连接` 和 `WebSocket 连接`。 + +#### DSN 规范 + +数据源名称具有通用格式,例如 [PEAR DB](http://pear.php.net/manual/en/package.database.db.intro-dsn.php),但没有类型前缀(方括号表示可选): + +``` text +[username[:password]@][protocol[(address)]]/[dbname][?param1=value1&...¶mN=valueN] +``` + +完整形式的 DSN: + +```text +username:password@protocol(address)/dbname?param=value +``` + +##### 原生连接 + +导入驱动: + +```go +import ( + "database/sql" + _ "github.com/taosdata/driver-go/v3/taosSql" +) +``` + +使用 `taosSql` 作为 `driverName` 并且使用一个正确的 DSN 作为 `dataSourceName` 如下: + +```go +var taosUri = "root:taosdata@tcp(localhost:6030)/" +taos, err := sql.Open("taosSql", taosUri) +``` + +支持的 DSN 参数: + +* `cfg` 指定 taos.cfg 目录 +* `cgoThread` 指定 cgo 同时执行的数量,默认为系统核数 +* `cgoAsyncHandlerPoolSize` 指定异步函数的 handle 大小,默认为 10000 + +##### Rest 连接 + +导入驱动: + +```go +import ( + "database/sql" + _ "github.com/taosdata/driver-go/v3/taosRestful" +) +``` + +使用 `taosRestful` 作为 `driverName` 并且使用一个正确的 DSN 作为 `dataSourceName` 如下: + +```go +var taosUri = "root:taosdata@http(localhost:6041)/" +taos, err := sql.Open("taosRestful", taosUri) +``` + +支持的 DSN 参数: + +* `disableCompression` 是否接受压缩数据,默认为 true 不接受压缩数据,如果传输数据使用 gzip 压缩设置为 false。 +* `readBufferSize` 读取数据的缓存区大小默认为 4K(4096),当查询结果数据量多时可以适当调大该值。 +* `token` 连接云服务时使用的 token。 +* `skipVerify` 是否跳过证书验证,默认为 false 不跳过证书验证,如果连接的是不安全的服务设置为 true。 + +##### WebSocket 连接 + +导入驱动: + +```go +import ( + "database/sql" + _ "github.com/taosdata/driver-go/v3/taosWS" +) +``` + +使用 `taosWS` 作为 `driverName` 并且使用一个正确的 DSN 作为 `dataSourceName` 如下: + +```go +var taosUri = "root:taosdata@ws(localhost:6041)/" +taos, err := sql.Open("taosWS", taosUri) +``` + +支持的 DSN 参数: + +* `enableCompression` 是否发送压缩数据,默认为 false 不发送压缩数据,如果传输数据使用压缩设置为 true。 +* `readTimeout` 读取数据的超时时间,默认为 5m。 +* `writeTimeout` 写入数据的超时时间,默认为 10s。 + +:::note + +- 与原生连接方式不同,REST 接口是无状态的。在使用 REST 连接时,需要在 SQL 中指定表、超级表的数据库名称。 +- 如果在 DSN 中指定了 dbname,那么,REST 连接会默认使用/rest/sql/dbname 作为 restful 请求的 url,在 SQL 中不需要指定 dbname。 + +::: + +### 连接功能 + +Go 驱动支持创建连接,返回支持 `sql/driver` 标准的 `Connector` 接口的对象,还提供了 `af` 包,扩充了一些无模式写入接口。 + +#### 标准接口 + +`database/sql` 包中创建连接的接口 + +- `func Open(driverName, dataSourceName string) (*DB, error)` + - **接口说明**:(`database/sql`)连接数据库 + - **参数说明**: + - `driverName`:驱动名称。 + - `dataSourceName`:连接参数 DSN。 + - **返回值**:连接对象,错误信息。 + +#### 扩展接口 + +`af` 包中创建连接的接口 + +- `func Open(host, user, pass, db string, port int) (*Connector, error)` + - **接口说明**:连接数据库。 + - **参数说明**: + - `host`:主机地址。 + - `user`:用户名。 + - `pass`:密码。 + - `db`:数据库名称。 + - `port`:端口号。 + - **返回值**:连接对象,错误信息。 + +#### 无模式写入 + +`af` 包中使用原生连接进行无模式写入的接口。 + +- `func (conn *Connector) InfluxDBInsertLines(lines []string, precision string) error` + - **接口说明**:无模式写入 influxDB 格式数据。 + - **参数说明**: + - `lines`:写入的数据。 + - `precision`:时间精度。 + - **返回值**:错误信息。 + +- `func (conn *Connector) OpenTSDBInsertJsonPayload(payload string) error` + - **接口说明**:无模式写入 OpenTSDB JSON 格式数据。 + - **参数说明**: + - `payload`:写入的数据。 + - **返回值**:错误信息。 + +- `func (conn *Connector) OpenTSDBInsertTelnetLines(lines []string) error` + - **接口说明**:无模式写入 OpenTSDB Telnet 格式数据。 + - **参数说明**: + - `lines`:写入的数据。 + - **返回值**:错误信息。 + +`ws/schemaless` 包中使用 WebSocket 无模式写入的接口 + +- `func (s *Schemaless) Insert(lines string, protocol int, precision string, ttl int, reqID int64) error` + - **接口说明**:无模式写入数据。 + - **参数说明**: + - `lines`:写入的数据。 + - `protocol`:写入的数据协议支持的协议 `InfluxDBLineProtocol = 1` `OpenTSDBTelnetLineProtocol = 2` `OpenTSDBJsonFormatProtocol = 3`。 + - `precision`:时间精度。 + - `ttl`:数据过期时间,0 表示不过期。 + - `reqID`:请求 ID。 + - **返回值**:错误信息。 + +### 执行 SQL + +Go 驱动提供了符合 `database/sql` 标准的接口,支持以下功能: + +1. **执行 SQL 语句**:执行静态 SQL 语句,并返回其生成的结果对象。 +2. **查询执行**:可以执行返回数据集的查询(`SELECT` 语句)。 +3. **更新执行**:可以执行影响行数的 SQL 语句,如 `INSERT`、`UPDATE`、`DELETE` 等。 +4. **获取结果**:可以获取查询执行后返回的结果集,并遍历查询返回的数据。 +5. **获取更新计数**:对于非查询 SQL 语句,可以获取执行后影响的行数。 +6. **关闭资源**:释放数据库资源。 + +#### 标准接口 + +- `func (db *DB) Close() error` + - **接口说明**:关闭连接。 + - **返回值**:错误信息。 + +- `func (db *DB) Exec(query string, args ...any) (Result, error)` + - **接口说明**:执行查询但不返回任何行。 + - **参数说明**: + - `query`:要执行的命令。 + - `args`:命令参数。 + - **返回值**:Result 对象(只有影响行数),错误信息。 + +- `func (db *DB) Query(query string, args ...any) (*Rows, error)` + - **接口说明**:执行查询并返回行的结果。 + - **参数说明**: + - `query`:要执行的命令。 + - `args`:命令参数。 + - **返回值**:Rows 对象,错误信息。 + +- `func (db *DB) QueryRow(query string, args ...any) *Row` + - **接口说明**:执行查询并返回一行结果。 + - **参数说明**: + - `query`:要执行的命令。 + - `args`:命令参数。 + - **返回值**:Row 对象。 + +#### 扩展接口 + +- `func (db *DB) ExecContext(ctx context.Context, query string, args ...any) (Result, error)` + - **接口说明**:执行查询但不返回任何行。 + - **参数说明**: + - `ctx`:上下文,使用 Value 传递请求 id 进行链路追踪,key 为 `taos_req_id` value 为 int64 类型值。 + - `query`:要执行的命令。 + - `args`:命令参数。 + - **返回值**:结果 Result 对象(只有影响行数),错误信息。 + +- `func (db *DB) QueryContext(ctx context.Context, query string, args ...any) (*Rows, error)` + - **接口说明**:执行查询并返回行结果。 + - **参数说明**: + - `ctx`:上下文,使用 Value 传递请求 id 进行链路追踪,key 为 `taos_req_id` value 为 int64 类型值。 + - `query`:要执行的命令。 + - `args`:命令参数。 + - **返回值**:结果集 Rows 对象,错误信息。 + +- `func (db *DB) QueryRowContext(ctx context.Context, query string, args ...any) *Row` + - **接口说明**:执行查询并返回一行结果,错误信息会在扫描 Row 时延迟返回。 + - **参数说明**: + - `ctx`:上下文,使用 Value 传递请求 id 进行链路追踪,key 为 `taos_req_id` value 为 int64 类型值。 + - `query`:要执行的命令。 + - `args`:命令参数。 + - **返回值**:单行结果 Row 对象。 + +### 结果获取 + +Go 驱动支持获取查询结果集,以及对应的结果集元数据,提供了用于读取结果集中元数据和数据的方法。 + +#### 结果集 + +通过 `Rows` 对象获取查询结果集,提供了以下方法: + +- `func (rs *Rows) Next() bool` + - **接口说明**:准备下一行数据。 + - **返回值**:是否有下一行数据。 + +- `func (rs *Rows) Columns() ([]string, error)` + - **接口说明**:返回列名。 + - **返回值**:列名,错误信息。 + +- `func (rs *Rows) Scan(dest ...any) error` + - **接口说明**:将当前行的列值复制到 dest 指向的值中。 + - **参数说明**: + - `dest`:目标值。 + - **返回值**:错误信息。 + +- `func (rs *Rows) Close() error` + - **接口说明**:关闭行。 + - **返回值**:错误信息。 + +- `func (r *Row) Scan(dest ...any) error` + - **接口说明**:将当前行的列值复制到 dest 指向的值中。 + - **参数说明**: + - `dest`:目标值。 + - **返回值**:错误信息。 + +通过 `Result` 对象获取更新结果集,提供了以下方法: + +- `func (dr driverResult) RowsAffected() (int64, error)` + - **接口说明**:返回受影响的行数。 + - **返回值**:受影响的行数,错误信息。 + +#### 结果集元数据 + +通过 `Rows` 对象获取查询结果集元数据,提供了以下方法: + +- `func (rs *Rows) ColumnTypes() ([]*ColumnType, error)` + - **接口说明**:返回列类型。 + - **返回值**:列类型,错误信息。 + +- `func (ci *ColumnType) Name() string` + - **接口说明**:返回列名。 + - **返回值**:列名。 + +- `func (ci *ColumnType) Length() (length int64, ok bool)` + - **接口说明**:返回列长度。 + - **返回值**:列长度,是否有长度。 + +- `func (ci *ColumnType) ScanType() reflect.Type` + - **接口说明**:返回列类型对应的 Go 类型。 + - **返回值**:列类型。 + +- `func (ci *ColumnType) DatabaseTypeName() string` + - **接口说明**:返回列类型数据库名称。 + - **返回值**:列类型名称。 + +### 参数绑定 + +Prepare 允许使用预编译的 SQL 语句,可以提高性能并提供参数化查询的能力,从而增加安全性。 + +#### 标准接口 + +使用 `sql/driver` 的 `Conn` 接口中的 `Prepare` 方法准备一个与此连接绑定的准备好的语句,返回 `Stmt` 对象,使用。 + +- `Prepare(query string) (Stmt, error)` + - **接口说明**:准备返回一个与此连接绑定的准备好的语句(statement)。 + - **参数说明**: + - `query`:要进行参数绑定的语句。 + - **返回值**:Stmt 对象,错误信息。 + +- `func (s *Stmt) Exec(args ...any) (Result, error)` + - **接口说明**:使用给定的参数执行准备好的语句并返回总结该语句效果的结果(只可以绑定列值,不支持绑定表名和 tag)。 + - **参数说明**: + - `args`:命令参数,Go 原始类型会自动转换数据库类型,类型不匹配可能会丢精度,建议使用与数据库相同的类型,时间类型使用 int64 或 `RFC3339Nano` 格式化后的字符串。 + - **返回值**:结果 Result 对象(只有影响行数),错误信息。 + +- `func (s *Stmt) Query(args ...any) (*Rows, error)` + - **接口说明**:使用给定的参数执行准备好的语句并返回行的结果。 + - **参数说明**: + - `args`:命令参数,Go 原始类型会自动转换数据库类型,类型不匹配可能会丢精度,建议使用与数据库相同的类型,时间类型使用 int64 或 `RFC3339Nano` 格式化后的字符串。 + - **返回值**:结果集 Rows 对象,错误信息。 + +- `func (s *Stmt) Close() error` + - **接口说明**:关闭语句。 + - **返回值**:错误信息。 + +#### 扩展接口 + +`af` 包中提供了使用原生连接进行参数绑定的更多接口 + +- `func (conn *Connector) Stmt() *Stmt` + - **接口说明**:返回一个与此连接绑定的 Stmt 对象。 + - **返回值**:Stmt 对象。 + +- `func (s *Stmt) Prepare(sql string) error` + - **接口说明**:准备一个 sql 。 + - **参数说明**: + - `sql`:要进行参数绑定的语句。 + - **返回值**:错误信息。 + +- `func (s *Stmt) NumParams() (int, error)` + - **接口说明**:返回参数数量。 + - **返回值**:参数数量,错误信息。 + +- `func (s *Stmt) SetTableNameWithTags(tableName string, tags *param.Param)` + - **接口说明**:设置表名和 tag。 + - **参数说明**: + - `tableName`:表名。 + - `tags`:tag。 + - **返回值**:错误信息。 + +- `func (s *Stmt) SetTableName(tableName string) error` + - **接口说明**:设置表名。 + - **参数说明**: + - `tableName`:表名。 + - **返回值**:错误信息。 + +- `func (s *Stmt) BindRow(row *param.Param) error` + - **接口说明**:绑定行。 + - **参数说明**: + - `row`:行数据。 + - **返回值**:错误信息。 + +- `func (s *Stmt) GetAffectedRows() int` + - **接口说明**:获取受影响的行数。 + - **返回值**:受影响的行数。 + +- `func (s *Stmt) AddBatch() error` + - **接口说明**:添加批处理。 + - **返回值**:错误信息。 + +- `func (s *Stmt) Execute() error` + - **接口说明**:执行批处理。 + - **返回值**:错误信息。 + +- `func (s *Stmt) UseResult() (driver.Rows, error)` + - **接口说明**:使用结果。 + - **返回值**:结果集 Rows 对象,错误信息。 + +- `func (s *Stmt) Close() error` + - **接口说明**:关闭语句。 + - **返回值**:错误信息。 + +`ws/stmt` 包提供了通过 WebSocket 进行参数绑定的接口 + +- `func (c *Connector) Init() (*Stmt, error)` + - **接口说明**:初始化。 + - **返回值**:Stmt 对象,错误信息。 + +- `func (s *Stmt) Prepare(sql string) error` + - **接口说明**:准备一个 sql 。 + - **参数说明**: + - `sql`:要进行参数绑定的语句。 + - **返回值**:错误信息。 + +- `func (s *Stmt) SetTableName(name string) error` + - **接口说明**:设置表名。 + - **参数说明**: + - `name`:表名。 + - **返回值**:错误信息。 + +- `func (s *Stmt) SetTags(tags *param.Param, bindType *param.ColumnType)` + - **接口说明**:设置 tag。 + - **参数说明**: + - `tags`:tag。 + - `bindType`:类型信息。 + - **返回值**:错误信息。 + +- `func (s *Stmt) BindParam(params []*param.Param, bindType *param.ColumnType) error` + - **接口说明**:绑定参数。 + - **参数说明**: + - `params`:参数。 + - `bindType`:类型信息。 + - **返回值**:错误信息。 + +- `func (s *Stmt) AddBatch() error` + - **接口说明**:添加批处理。 + - **返回值**:错误信息。 + +- `func (s *Stmt) Exec() error` + - **接口说明**:执行批处理。 + - **返回值**:错误信息。 + +- `func (s *Stmt) GetAffectedRows() int` + - **接口说明**:获取受影响的行数。 + - **返回值**:受影响的行数。 + +- `func (s *Stmt) UseResult() (*Rows, error)` + - **接口说明**:使用结果。 + - **返回值**:Rows 对象,错误信息。 + +- `func (s *Stmt) Close() error` + - **接口说明**:关闭语句。 + - **返回值**:错误信息。 + +Rows 行结果参考 `sql/driver` 包中的 `Rows` 接口,提供以下接口 + +- `func (rs *Rows) Columns() []string` + - **接口说明**:返回列名。 + - **返回值**:列名。 + +- `func (rs *Rows) ColumnTypeDatabaseTypeName(i int) string` + - **接口说明**:返回列类型数据库名称。 + - **参数说明**: + - `i`:列索引。 + - **返回值**:列类型名称。 + +- `func (rs *Rows) ColumnTypeLength(i int) (length int64, ok bool)` + - **接口说明**:返回列长度。 + - **参数说明**: + - `i`:列索引。 + - **返回值**:列长度,是否有长度。 + +- `func (rs *Rows) ColumnTypeScanType(i int) reflect.Type` + - **接口说明**:返回列类型对应的 Go 类型。 + - **参数说明**: + - `i`:列索引。 + - **返回值**:列类型。 + +- `func (rs *Rows) Next(dest []driver.Value) error` + - **接口说明**:准备下一行数据,并赋值给目标。 + - **参数说明**: + - `dest`:目标值。 + - **返回值**:错误信息。 + +- `func (rs *Rows) Close() error` + - **接口说明**:关闭行。 + - **返回值**:错误信息。 + + +`common/param` 包中提供了参数绑定数据结构 + +以下是按照偏移设置参数的接口: + +- `func NewParam(size int) *Param` + - **接口说明**:创建一个参数绑定数据结构。 + - **参数说明**: + - `size`:参数数量。 + - **返回值**:Param 对象。 + +- `func (p *Param) SetBool(offset int, value bool)` + - **接口说明**:设置布尔值。 + - **参数说明**: + - `offset`:偏移量(列或标签)。 + - `value`:布尔值。 + +- `func (p *Param) SetNull(offset int)` + - **接口说明**:设置空值。 + - **参数说明**: + - `offset`:偏移量(列或标签)。 + +- `func (p *Param) SetTinyint(offset int, value int)` + - **接口说明**:设置 Tinyint 值。 + - **参数说明**: + - `offset`:偏移量(列或标签)。 + - `value`:Tinyint 值。 + +- `func (p *Param) SetSmallint(offset int, value int)` + - **接口说明**:设置 Smallint 值。 + - **参数说明**: + - `offset`:偏移量(列或标签)。 + - `value`:Smallint 值。 + +- `func (p *Param) SetInt(offset int, value int)` + - **接口说明**:设置 Int 值。 + - **参数说明**: + - `offset`:偏移量(列或标签)。 + - `value`:Int 值。 + +- `func (p *Param) SetBigint(offset int, value int)` + - **接口说明**:设置 Bigint 值。 + - **参数说明**: + - `offset`:偏移量(列或标签)。 + - `value`:Bigint 值。 + +- `func (p *Param) SetUTinyint(offset int, value uint)` + - **接口说明**:设置 UTinyint 值。 + - **参数说明**: + - `offset`:偏移量(列或标签)。 + - `value`:UTinyint 值。 + +- `func (p *Param) SetUSmallint(offset int, value uint)` + - **接口说明**:设置 USmallint 值。 + - **参数说明**: + - `offset`:偏移量(列或标签)。 + - `value`:USmallint 值。 + +- `func (p *Param) SetUInt(offset int, value uint)` + - **接口说明**:设置 UInt 值。 + - **参数说明**: + - `offset`:偏移量(列或标签)。 + - `value`:UInt 值。 + +- `func (p *Param) SetUBigint(offset int, value uint)` + - **接口说明**:设置 UBigint 值。 + - **参数说明**: + - `offset`:偏移量(列或标签)。 + - `value`:UBigint 值。 + +- `func (p *Param) SetFloat(offset int, value float32)` + - **接口说明**:设置 Float 值。 + - **参数说明**: + - `offset`:偏移量(列或标签)。 + - `value`:Float 值。 + +- `func (p *Param) SetDouble(offset int, value float64)` + - **接口说明**:设置 Double 值。 + - **参数说明**: + - `offset`:偏移量(列或标签)。 + - `value`:Double 值。 + +- `func (p *Param) SetBinary(offset int, value []byte)` + - **接口说明**:设置 Binary 值。 + - **参数说明**: + - `offset`:偏移量(列或标签)。 + - `value`:Binary 值。 + +- `func (p *Param) SetVarBinary(offset int, value []byte)` + - **接口说明**:设置 VarBinary 值。 + - **参数说明**: + - `offset`:偏移量(列或标签)。 + - `value`:VarBinary 值。 + +- `func (p *Param) SetNchar(offset int, value string)` + - **接口说明**:设置 Nchar 值。 + - **参数说明**: + - `offset`:偏移量(列或标签)。 + - `value`:Nchar 值。 + +- `func (p *Param) SetTimestamp(offset int, value time.Time, precision int)` + - **接口说明**:设置 Timestamp 值。 + - **参数说明**: + - `offset`:偏移量(列或标签)。 + - `value`:Timestamp 值。 + - `precision`:时间精度。 + +- `func (p *Param) SetJson(offset int, value []byte)` + - **接口说明**:设置 Json 值。 + - **参数说明**: + - `offset`:偏移量(列或标签)。 + - `value`:Json 值。 + +- `func (p *Param) SetGeometry(offset int, value []byte)` + - **接口说明**:设置 Geometry 值。 + - **参数说明**: + - `offset`:偏移量(列或标签)。 + - `value`:Geometry 值。 + +以下是链式调用设置参数的接口: + +- `func (p *Param) AddBool(value bool) *Param` + - **接口说明**:添加布尔值。 + - **参数说明**: + - `value`:布尔值。 + - **返回值**:Param 对象。 + +其他类型与布尔值类似,具体接口如下: + +- AddNull +- AddTinyint +- AddSmallint +- AddInt +- AddBigint +- AddUTinyint +- AddUSmallint +- AddUInt +- AddUBigint +- AddFloat +- AddDouble +- AddBinary +- AddVarBinary +- AddNchar +- AddTimestamp +- AddJson +- AddGeometry + +以下是设置列类型信息的接口: + +- `func NewColumnType(size int) *ColumnType` + - **接口说明**:创建一个列类型信息数据结构。 + - **参数说明**: + - `size`:列数量。 + - **返回值**:ColumnType 对象。 + +- `func (c *ColumnType) AddBool() *ColumnType` + - **接口说明**:添加布尔类型。 + - **返回值**:ColumnType 对象。 + +其他类型与布尔类型类似,具体接口如下: + +- AddTinyint +- AddSmallint +- AddInt +- AddBigint +- AddUTinyint +- AddUSmallint +- AddUInt +- AddUBigint +- AddFloat +- AddDouble +- AddBinary +- AddVarBinary +- AddNchar +- AddTimestamp +- AddJson +- AddGeometry + + +### 数据订阅 + +Go 驱动支持数据订阅功能,提供了基于原生连接和 WebSocket 连接的数据订阅接口。原生实现在 `af/tmq` 包中,WebSocket 实现在 `ws/tmq` 包中。 + +#### 消费者 + +- `func NewConsumer(conf *tmq.ConfigMap) (*Consumer, error)` + - **接口说明**:创建一个消费者。 + - **参数说明**: + - `conf`:配置信息。 + - **返回值**:Consumer 对象,错误信息。 + +配置信息定义为: + +```go +type ConfigValue interface{} +type ConfigMap map[string]ConfigValue +``` +创建消费者支持属性列表: + +- `ws.url`:WebSocket 连接地址。 +- `ws.message.channelLen`:WebSocket 消息通道缓存长度,默认 0。 +- `ws.message.timeout`:WebSocket 消息超时时间,默认 5m。 +- `ws.message.writeWait`:WebSocket 写入消息超时时间,默认 10s。 +- `ws.message.enableCompression`:WebSocket 是否启用压缩,默认 false。 +- `ws.autoReconnect`:WebSocket 是否自动重连,默认 false。 +- `ws.reconnectIntervalMs`:WebSocket 重连间隔时间毫秒,默认 2000。 +- `ws.reconnectRetryCount`:WebSocket 重连重试次数,默认 3。 + +其他参数请参考:[Consumer 参数列表](../../develop/tmq/#数据订阅相关参数), 注意TDengine服务端自 3.2.0.0 版本开始消息订阅中的 auto.offset.reset 默认值发生变化。 + +- `func (c *Consumer) Subscribe(topic string, rebalanceCb RebalanceCb) error` + - **接口说明**:订阅主题。 + - **参数说明**: + - `topic`:主题。 + - `rebalanceCb`:平衡回调(未使用)。 + - **返回值**:错误信息。 + +- `func (c *Consumer) SubscribeTopics(topics []string, rebalanceCb RebalanceCb) error` + - **接口说明**:订阅主题列表。 + - **参数说明**: + - `topics`:主题列表。 + - `rebalanceCb`:平衡回调(未使用)。 + - **返回值**:错误信息。 + +- `func (c *Consumer) Unsubscribe() error` + - **接口说明**:取消订阅。 + - **返回值**:错误信息。 + +- `func (c *Consumer) Poll(timeoutMs int) tmq.Event` + - **接口说明**:轮询事件。 + - **参数说明**: + - `timeoutMs`:超时时间。 + - **返回值**:事件。 + +- `func (c *Consumer) Commit() ([]tmq.TopicPartition, error)` + - **接口说明**:提交偏移量。 + - **返回值**:TopicPartition 列表,错误信息。 + +- `func (c *Consumer) Assignment() (partitions []tmq.TopicPartition, err error)` + - **接口说明**:获取分配信息。 + - **返回值**:TopicPartition 列表,错误信息。 + +- `func (c *Consumer) Seek(partition tmq.TopicPartition, ignoredTimeoutMs int) error` + - **接口说明**:跳转到偏移量。 + - **参数说明**: + - `partition`:分区和偏移信息。 + - `ignoredTimeoutMs`:超时时间(未使用)。 + - **返回值**:错误信息。 + +- `func (c *Consumer) Committed(partitions []tmq.TopicPartition, timeoutMs int) (offsets []tmq.TopicPartition, err error)` + - **接口说明**:获取提交的偏移量。 + - **参数说明**: + - `partitions`:分区列表。 + - `timeoutMs`:超时时间。 + - **返回值**:TopicPartition 列表,错误信息。 + +- `func (c *Consumer) CommitOffsets(offsets []tmq.TopicPartition) ([]tmq.TopicPartition, error) ` + - **接口说明**:提交偏移量。 + - **参数说明**: + - `offsets`:偏移量列表。 + - **返回值**:TopicPartition 列表,错误信息。 + +- `func (c *Consumer) Position(partitions []tmq.TopicPartition) (offsets []tmq.TopicPartition, err error)` + - **接口说明**:获取当前偏移量。 + - **参数说明**: + - `partitions`:分区列表。 + - **返回值**:TopicPartition 列表,错误信息。 + +- `func (c *Consumer) Close() error` + - **接口说明**:关闭消费者。 + - **返回值**:错误信息。 + +#### 消费记录 + +当 `Poll` 返回 `tmq.Event` 事件时,可以通过判断 `tmq.Event` 的类型获取消费记录或错误信息。当类型为 `*tmq.DataMessage` 时,可以获取消费记录。 + +- `func (m *DataMessage) Topic() string` + - **接口说明**:获取主题。 + - **返回值**:主题。 + +- `func (m *DataMessage) DBName() string` + - **接口说明**:获取数据库名称。 + - **返回值**:数据库名称。 + +- `func (m *DataMessage) Offset() Offset` + - **接口说明**:获取偏移量。 + - **返回值**:偏移量。 + +- `func (m *DataMessage) Value() interface{}` + - **接口说明**:获取值,具体值为 `[]*tmq.data`。 + - **返回值**:消费到的值。 + +tmq.data 结构如下: + +```go +type Data struct { + TableName string + Data [][]driver.Value +} +``` + +- TableName 为表名 +- Data 为数据,每个元素为一行数据,每行数据为一个数组,数组元素为列值。 + +当 Poll 返回类型为 `tmq.Error` 时,可以使用 `func (e Error) Error() string` 获取错误信息。 + +#### 分区信息 + +当消费到数据类型为 `*tmq.DataMessage` 时,可以从 `TopicPartition` 属性中获取分区信息。 + +```go +type TopicPartition struct { + Topic *string + Partition int32 + Offset Offset + Metadata *string + Error error +} +``` + +- `Topic`:主题。 +- `Partition`:分区。 +- `Offset`:偏移量。 +- `Metadata`:元数据(未使用)。 +- `Error`:错误信息。 + +可以使用 `func (p TopicPartition) String() string` 获取分区信息。 + +#### 偏移量元数据 + +从 `TopicPartition` 中获取的偏移量信息,可以通过 `Offset` 属性获取偏移量元数据。当偏移量为 `-2147467247` 时表示未设置偏移量。 + +#### 反序列化 + +当消费到数据类型为 `*tmq.DataMessage` 时,可以使用 `func (m *DataMessage) Value() interface{}` 获取数据,数据类型为 `[]*tmq.data` 。 + +## 附录 + +[driver-go 文档](https://pkg.go.dev/github.com/taosdata/driver-go/v3) diff --git a/docs/zh/14-reference/05-connector/40-csharp.mdx b/docs/zh/14-reference/05-connector/40-csharp.mdx index a175e6bf05..ad316d581c 100644 --- a/docs/zh/14-reference/05-connector/40-csharp.mdx +++ b/docs/zh/14-reference/05-connector/40-csharp.mdx @@ -1207,3 +1207,741 @@ namespace WSADO ### 更多示例程序 [示例程序](https://github.com/taosdata/taos-connector-dotnet/tree/3.0/examples) + +## API 参考 + +### ADO.NET 驱动 + +`TDengine.Data.Client` 接口实现了 ADO.NET 驱动,支持连接 TDengine 数据库,进行数据操作。 + +#### 参数规范 + +ConnectionStringBuilder 使用 key-value 对方式设置连接参数,key 为参数名,value 为参数值,不同参数之间使用分号 `;` 分割。 + +例如: + +```csharp +"protocol=WebSocket;host=127.0.0.1;port=6041;useSSL=false" +``` + +##### 原生连接 + +例如:`"host=127.0.0.1;port=6030;username=root;password=taosdata;protocol=Native;db=test"` + +支持的参数如下: + +- `host`:TDengine 运行实例的地址。 +- `port`:TDengine 运行实例的端口。 +- `username`:连接的用户名。 +- `password`:连接的密码。 +- `protocol`:连接的协议,可选值为 Native 或 WebSocket,默认为 Native。 +- `db`:连接的数据库。 +- `timezone`:时区,默认为本地时区。 + +##### WebSocket 连接 + +例如:`"protocol=WebSocket;host=127.0.0.1;port=6041;useSSL=false;enableCompression=true;autoReconnect=true;reconnectIntervalMs=10;reconnectRetryCount=5"` + +支持的参数如下: + +- `host`:TDengine 运行实例的地址。 +- `port`:TDengine 运行实例的端口。 +- `username`:连接的用户名。 +- `password`:连接的密码。 +- `protocol`:连接的协议,可选值为 Native 或 WebSocket,默认为 Native。 +- `db`:连接的数据库。 +- `timezone`:时区,默认为本地时区。 +- `connTimeout`:连接超时时间,默认为 1 分钟。 +- `readTimeout`:读取超时时间,默认为 5 分钟。 +- `writeTimeout`:发送超时时间,默认为 10 秒。 +- `token`:连接 TDengine cloud 的 token。 +- `useSSL`:是否使用 SSL 连接,默认为 false。 +- `enableCompression`:是否启用 WebSocket 压缩,默认为 false。 +- `autoReconnect`:是否自动重连,默认为 false。 +- `reconnectRetryCount`:重连次数,默认为 3。 +- `reconnectIntervalMs`:重连间隔毫秒时间,默认为 2000。 + +#### 接口说明 + +`ConnectionStringBuilder` 类提供了连接配置字符串的解析功能。 + +- `public ConnectionStringBuilder(string connectionString)` + - **接口说明**:ConnectionStringBuilder 构造函数。 + - **参数说明**: + - `connectionString`:连接配置字符串。 + +### 连接功能 + +C# 驱动支持创建 ADO.NET 连接,返回支持 ADO.NET 标准的 `DbConnection` 接口的对象,还提供了 `ITDengineClient` 接口,扩充了一些无模式写入接口。 + +#### 标准接口 + +ADO.NET 连接支持的标准接口如下: + +- `public TDengineConnection(string connectionString)` + - **接口说明**:TDengineConnection 构造函数。 + - **参数说明**: + - `connectionString`:连接配置字符串。 + - **异常**:格式错误抛出 `ArgumentException` 异常。 + +- `public void ChangeDatabase(string databaseName)` + - **接口说明**:切换数据库。 + - **参数说明**: + - `databaseName`:数据库名。 + - **异常**:执行失败抛出 `TDengineError` 异常。 + +- `public void Close()` + - **接口说明**:关闭连接。 + +- `public void Open()` + - **接口说明**:打开连接。 + - **异常**:打开失败抛出 `TDengineError` 异常,WebSocket 连接可能存在网络异常须注意处理。 + +- `public string ServerVersion` + - **接口说明**:返回服务器版本。 + - **返回值**:服务器版本字符串。 + - **异常**:执行失败抛出 `TDengineError` 异常。 + +- `public string DataSource` + - **接口说明**:返回数据源。 + - **返回值**:创建连接 host 配置。 + +- `public string Database` + - **接口说明**:返回连接数据库。 + - **返回值**:创建连接 db 配置。 + +- `public TDengineCommand(TDengineConnection connection)` + - **接口说明**:TDengineCommand 构造函数。 + - **参数说明**: + - `connection`:TDengineConnection 对象。 + - **异常**:执行失败抛出 `TDengineError` 异常。 + +- `public void Prepare()` + - **接口说明**:检查连接和命令文本,并准备命令执行。 + - **异常**:未执行 open 或未设置 CommandText 抛出 `InvalidOperationException` 异常。 + +- `public string CommandText` + - **接口说明**:获取或设置命令文本。 + - **返回值**:命令文本。 + +- `public new virtual TDengineParameterCollection Parameters` + - **接口说明**:获取参数集合。 + - **返回值**:TDengineParameterCollection 对象。 + + +#### 无模式写入 + +- `public static ITDengineClient Open(ConnectionStringBuilder builder)` + - **接口说明**:打开连接。 + - **参数说明**: + - `builder`:连接配置。 + - **返回值**:ITDengineClient 接口。 + - **异常**:打开失败抛出 `TDengineError` 异常,WebSocket 连接可能存在网络异常须注意处理。 + +- `void SchemalessInsert(string[] lines, TDengineSchemalessProtocol protocol,TDengineSchemalessPrecision precision, int ttl, long reqId)` + - **接口说明**:无模式写入。 + - **参数说明**: + - `lines`:数据行数组。 + - `protocol`:数据协议,支持协议:`TSDB_SML_LINE_PROTOCOL = 1` `TSDB_SML_TELNET_PROTOCOL = 2` `TSDB_SML_JSON_PROTOCOL = 3`。 + - `precision`:时间精度,支持配置:`TSDB_SML_TIMESTAMP_NOT_CONFIGURED = 0` `TSDB_SML_TIMESTAMP_HOURS = 1` `TSDB_SML_TIMESTAMP_MINUTES = 2` `TSDB_SML_TIMESTAMP_SECONDS = 3` `TSDB_SML_TIMESTAMP_MILLI_SECONDS = 4` `TSDB_SML_TIMESTAMP_MICRO_SECONDS = 5` `TSDB_SML_TIMESTAMP_NANO_SECONDS = 6`。 + - `ttl`:数据过期时间,0表示不配置。 + - `reqId`:请求 ID。 + - **异常**:执行失败抛出 `TDengineError` 异常。 + +### 执行 SQL + +C# 驱动提供了符合 ADO.NET 标准的 `DbCommand` 接口,支持以下功能: + +1. **执行 SQL 语句**:执行静态 SQL 语句,并返回其生成的结果对象。 +2. **查询执行**:可以执行返回数据集的查询(`SELECT` 语句)。 +3. **更新执行**:可以执行影响行数的 SQL 语句,如 `INSERT`、`UPDATE`、`DELETE` 等。 +4. **获取结果**:可以获取查询执行后返回的结果集(`ResultSet` 对象),并遍历查询返回的数据。 +5. **获取更新计数**:对于非查询 SQL 语句,可以获取执行后影响的行数。 +6. **关闭资源**:提供了关闭的方法,以释放数据库资源。 + +另外 C# 驱动还提供了用于请求链路跟踪的扩展接口。 + +#### 标准接口 + +- `public int ExecuteNonQuery()` + - **接口说明**:执行 SQL 语句,返回受影响的行数。 + - **返回值**:受影响的行数。 + - **异常**:执行失败抛出 `TDengineError` 异常。 + +- `public object ExecuteScalar()` + - **接口说明**:执行查询,并返回查询结果的第一行第一列。 + - **返回值**:查询结果的第一行第一列。 + - **异常**:执行失败抛出 `TDengineError` 异常。 + +- `public DbDataReader ExecuteReader()` + - **接口说明**:执行查询,并返回查询结果的数据读取器。 + - **返回值**:查询结果的数据读取器。 + - **异常**:执行失败抛出 `TDengineError` 异常。 + +- `public void Dispose();` + - **接口说明**:释放资源。 + +#### 扩展接口 + +扩展接口主要用于请求链路跟踪。 + +- `IRows Query(string query, long reqId)` + - **接口说明**:执行查询,返回查询结果。 + - **参数说明**: + - `query`:查询语句。 + - `reqId`:请求 ID。 + - **返回值**:查询结果。 + - **异常**:执行失败抛出 `TDengineError` 异常。 + +- `long Exec(string query, long reqId)` + - **接口说明**:执行 SQL 语句。 + - **参数说明**: + - `query`:SQL 语句。 + - `reqId`:请求 ID。 + - **返回值**:受影响的行数。 + - **异常**:执行失败抛出 `TDengineError` 异常。 + + +### 结果获取 + +C# 驱动提供了符合 ADO.NET 标准的 `DbDataReader` 接口,提供了用于读取结果集中元数据和数据的方法。 + +#### 结果集 + +`DbDataReader` 接口提供了以下方法获取结果集: + +- `public bool GetBoolean(int ordinal)` + - **接口说明**:获取指定列的布尔值。 + - **参数说明**: + - `ordinal`:列索引。 + - **返回值**:布尔值。 + - **异常**:类型不对应抛出 `InvalidCastException` 异常。 + +- `public byte GetByte(int ordinal)` + - **接口说明**:获取指定列的字节值。 + - **参数说明**: + - `ordinal`:列索引。 + - **返回值**:字节值。 + - **异常**:类型不对应抛出 `InvalidCastException` 异常。 + +- `public long GetBytes(int ordinal, long dataOffset, byte[] buffer, int bufferOffset, int length)` + - **接口说明**:获取指定列的字节值。 + - **参数说明**: + - `ordinal`:列索引。 + - `dataOffset`:数据偏移量。 + - `buffer`:缓冲区。 + - `bufferOffset`:缓冲区偏移量。 + - `length`:长度。 + - **返回值**:字节值。 + - **异常**:类型不对应抛出 `InvalidCastException` 异常。 + +- `public char GetChar(int ordinal)` + - **接口说明**:获取指定列的字符值。 + - **参数说明**: + - `ordinal`:列索引。 + - **返回值**:字符值。 + - **异常**:类型不对应抛出 `InvalidCastException` 异常。 + +- `public long GetChars(int ordinal, long dataOffset, char[] buffer, int bufferOffset, int length)` + - **接口说明**:获取指定列的字符值。 + - **参数说明**: + - `ordinal`:列索引。 + - `dataOffset`:数据偏移量。 + - `buffer`:缓冲区。 + - `bufferOffset`:缓冲区偏移量。 + - `length`:长度。 + - **返回值**:字符值。 + - **异常**:类型不对应抛出 `InvalidCastException` 异常。 + +- `public DateTime GetDateTime(int ordinal)` + - **接口说明**:获取指定列的日期时间值。 + - **参数说明**: + - `ordinal`:列索引。 + - **返回值**:日期时间值。 + - **异常**:类型不对应抛出 `InvalidCastException` 异常。 + +- `public double GetDouble(int ordinal)` + - **接口说明**:获取指定列的双精度浮点数值。 + - **参数说明**: + - `ordinal`:列索引。 + - **返回值**:双精度浮点数值。 + - **异常**:类型不对应抛出 `InvalidCastException` 异常。 + +- `public float GetFloat(int ordinal)` + - **接口说明**:获取指定列的单精度浮点数值。 + - **参数说明**: + - `ordinal`:列索引。 + - **返回值**:单精度浮点数值。 + - **异常**:类型不对应抛出 `InvalidCastException` 异常。 + +- `public short GetInt16(int ordinal)` + - **接口说明**:获取指定列的 16 位整数值。 + - **参数说明**: + - `ordinal`:列索引。 + - **返回值**:16 位整数值。 + - **异常**:类型不对应抛出 `InvalidCastException` 异常。 + +- `public int GetInt32(int ordinal)` + - **接口说明**:获取指定列的 32 位整数值。 + - **参数说明**: + - `ordinal`:列索引。 + - **返回值**:32 位整数值。 + - **异常**:类型不对应抛出 `InvalidCastException` 异常。 + +- `public long GetInt64(int ordinal)` + - **接口说明**:获取指定列的 64 位整数值。 + - **参数说明**: + - `ordinal`:列索引。 + - **返回值**:64 位整数值。 + - **异常**:类型不对应抛出 `InvalidCastException` 异常。 + +- `public string GetString(int ordinal)` + - **接口说明**:获取指定列的字符串值。 + - **参数说明**: + - `ordinal`:列索引。 + - **返回值**:字符串值。 + - **异常**:类型不对应抛出 `InvalidCastException` 异常。 + +- `public object GetValue(int ordinal)` + - **接口说明**:获取指定列的值。 + - **参数说明**: + - `ordinal`:列索引。 + - **返回值**: 结果对象。 + + +- `public int GetValues(object[] values)` + - **接口说明**:获取所有列的值。 + - **参数说明**: + - `values`:值数组。 + - **返回值**:值数量。 + +- `public bool IsDBNull(int ordinal)` + - **接口说明**:判断指定列是否为 NULL。 + - **参数说明**: + - `ordinal`:列索引。 + - **返回值**:是否为 NULL。 + +- `public int RecordsAffected` + - **接口说明**:获取受影响的行数。 + - **返回值**:受影响的行数。 + +- `public bool HasRows` + - **接口说明**:结果是否有行数据。 + - **返回值**:结果是否有行数据。 + +- `public bool Read()` + - **接口说明**:读取下一行。 + - **返回值**:是否读取成功。 + +- `public IEnumerator GetEnumerator()` + - **接口说明**:获取枚举器。 + - **返回值**:枚举器。 + +- `public void Close()` + - **接口说明**:关闭结果集。 + +#### 结果集元数据 + +`DbDataReader` 接口提供了以下方法获取结果集元数据: + +- `public DataTable GetSchemaTable()` + - **接口说明**:获取结果集元数据。 + - **返回值**:结果集元数据。 + +- `public string GetDataTypeName(int ordinal)` + - **接口说明**:获取指定列的数据类型名称。 + - **参数说明**: + - `ordinal`:列索引。 + - **返回值**:数据类型名称。 + +- ` public Type GetFieldType(int ordinal)` + - **接口说明**:获取指定列的数据类型。 + - **参数说明**: + - `ordinal`:列索引。 + - **返回值**:数据类型。 + +- `public string GetName(int ordinal)` + - **接口说明**:获取指定列的名称。 + - **参数说明**: + - `ordinal`:列索引。 + - **返回值**:列名称。 + +- ` public int GetFieldSize(int ordinal)` + - **接口说明**:获取指定列的大小。 + - **参数说明**: + - `ordinal`:列索引。 + - **返回值**:列大小。 + +- `public int GetOrdinal(string name)` + - **接口说明**:获取指定列的索引。 + - **参数说明**: + - `name`:列名称。 + - **返回值**:列索引。 + +- `public int FieldCount` + - **接口说明**:获取列数。 + - **返回值**:列数。 + +### 参数绑定 + +`TDengineCommand` 类支持参数绑定。 + +#### 标准接口 + +`TDengineCommand` 类继承了 `DbCommand` 接口,支持以下功能: + +- `public string CommandText` + - **接口说明**:获取或设置命令文本,支持参数绑定。 + - **返回值**:命令文本。 + +- `public new virtual TDengineParameterCollection Parameters` + - **接口说明**:获取参数集合。 + - **返回值**:`TDengineParameterCollection` 对象。 + +#### 参数元数据 + +`TDengineParameterCollection` 继承了 `DbParameterCollection` 接口,支持以下功能: + +- `public int Add(object value)` + - **接口说明**:添加参数。 + - **参数说明**: + - `value`:参数值。 + - **返回值**:参数索引。 + +- `public void Clear()` + - **接口说明**:清空参数。 + +- `public bool Contains(object value)` + - **接口说明**:是否包含参数。 + - **参数说明**: + - `value`:参数值。 + - **返回值**:是否包含参数。 + +- `public int IndexOf(object value)` + - **接口说明**:获取参数索引。 + - **参数说明**: + - `value`:参数值。 + - **返回值**:参数索引。 + +- `public void Insert(int index, object value)` + - **接口说明**:插入参数。 + - **参数说明**: + - `index`:索引。 + - `value`:参数值。 + +- `public void Remove(object value)` + - **接口说明**:移除参数。 + - **参数说明**: + - `value`:参数值。 + +- `public void RemoveAt(int index)` + - **接口说明**:移除参数。 + - **参数说明**: + - `index`:索引。 + +- `public void RemoveAt(string parameterName)` + - **接口说明**:移除参数。 + - **参数说明**: + - `parameterName`:参数名。 + +- `public int Count` + - **接口说明**:获取参数数量。 + - **返回值**:参数数量。 + +- `public int IndexOf(string parameterName)` + - **接口说明**:获取参数索引。 + - **参数说明**: + - `parameterName`:参数名。 + - **返回值**:参数索引。 + +- `public bool Contains(string value)` + - **接口说明**:是否包含参数。 + - **参数说明**: + - `value`:参数名。 + - **返回值**:是否包含参数。 + +- `public void CopyTo(Array array, int index)` + - **接口说明**:复制参数。 + - **参数说明**: + - `array`:目标数组。 + - `index`:索引。 + +- `public IEnumerator GetEnumerator()` + - **接口说明**:获取枚举器。 + - **返回值**:枚举器。 + +- `public void AddRange(Array values)` + - **接口说明**:添加参数。 + - **参数说明**: + - `values`:参数数组。 + +`TDengineParameter` 继承了 `DbParameter` 接口,支持以下功能: + +- `public TDengineParameter(string name, object value)` + - **接口说明**:TDengineParameter 构造函数。 + - **参数说明**: + - `name`:参数名,需要以 @ 开头,如 @0、@1、@2 等。 + - `value`:参数值,需要 C# 列类型与 TDengine 列类型一一对应。 + +- `public string ParameterName` + - **接口说明**:获取或设置参数名。 + - **返回值**:参数名。 + +- `public object Value` + - **接口说明**:获取或设置参数值。 + - **返回值**:参数值。 + +#### 扩展接口 + +`ITDengineClient` 接口提供了扩展的参数绑定接口。 + +- `IStmt StmtInit(long reqId)` + - **接口说明**:初始化 statement 对象。 + - **参数说明**: + - `reqId`:请求 ID。 + - **返回值**:实现 IStmt 接口的对象。 + - **异常**:执行失败抛出 `TDengineError` 异常。 + +`IStmt` 接口提供了扩展的参数绑定接口。 + +- `void Prepare(string query)` + - **接口说明**:准备 statement。 + - **参数说明**: + - `query`:查询语句。 + - **异常**:执行失败抛出 `TDengineError` 异常。 + +- `bool IsInsert()` + - **接口说明**:判断是否为插入语句。 + - **返回值**:是否为插入语句。 + - **异常**:执行失败抛出 `TDengineError` 异常。 + +- `void SetTableName(string tableName)` + - **接口说明**:设置表名。 + - **参数说明**: + - `tableName`:表名。 + - **异常**:执行失败抛出 `TDengineError` 异常。 + +- `void SetTags(object[] tags)` + - **接口说明**:设置标签。 + - **参数说明**: + - `tags`:标签数组。 + - **异常**:执行失败抛出 `TDengineError` 异常。 + +- `TaosFieldE[] GetTagFields()` + - **接口说明**:获取标签属性。 + - **返回值**:标签属性数组。 + - **异常**:执行失败抛出 `TDengineError` 异常。 + +- `TaosFieldE[] GetColFields()` + - **接口说明**:获取列属性。 + - **返回值**:列属性数组。 + - **异常**:执行失败抛出 `TDengineError` 异常。 + +- `void BindRow(object[] row)` + - **接口说明**:绑定行。 + - **参数说明**: + - `row`:行数据数组。 + - **异常**:执行失败抛出 `TDengineError` 异常。 + +- `void BindColumn( TaosFieldE[] fields,params Array[] arrays)` + - **接口说明**:绑定全部列。 + - **参数说明**: + - `fields`:字段属性数组。 + - `arrays`:多列数据数组。 + - **异常**:执行失败抛出 `TDengineError` 异常。 + +- `void AddBatch()` + - **接口说明**:添加批处理。 + - **异常**:执行失败抛出 `TDengineError` 异常。 + +- `void Exec()` + - **接口说明**:执行参数绑定。 + - **异常**:执行失败抛出 `TDengineError` 异常。 + +- `long Affected()` + - **接口说明**:获取受影响的行数。 + - **返回值**:受影响的行数。 + - **异常**:执行失败抛出 `TDengineError` 异常。 + +- `IRows Result()` + - **接口说明**:获取结果。 + - **返回值**:结果对象。 + - **异常**:执行失败抛出 `TDengineError` 异常。 + +### 数据订阅 + +`ConsumerBuilder` 类提供了消费者构建相关接口,`ConsumeResult` 类提供了消费结果相关接口,`TopicPartitionOffset` 类提供了分区偏移量相关接口。`ReferenceDeserializer` 和 `DictionaryDeserializer` 提供了反序列化的支持。 + +#### 消费者 + +- `public ConsumerBuilder(IEnumerable> config)` + - **接口说明**:ConsumerBuilder 构造函数。 + - **参数说明**: + - `config`:消费配置。 + +创建消费者支持属性列表: + +- `useSSL`:是否使用 SSL 连接,默认为 false +- `token`:连接 TDengine cloud 的 token +- `ws.message.enableCompression`:是否启用 WebSocket 压缩,默认为 false +- `ws.autoReconnect`:是否自动重连,默认为 false +- `ws.reconnect.retry.count`:重连次数,默认为 3 +- `ws.reconnect.interval.ms`:重连间隔毫秒时间,默认为 2000 + +其他参数请参考:[Consumer 参数列表](../../develop/tmq/#数据订阅相关参数), 注意TDengine服务端自 3.2.0.0 版本开始消息订阅中的 auto.offset.reset 默认值发生变化。 + +- `public IConsumer Build()` + - **接口说明**:构建消费者。 + - **返回值**:消费者对象。 + +`IConsumer` 接口提供了消费者相关 API: + +- `ConsumeResult Consume(int millisecondsTimeout)` + - **接口说明**:消费消息。 + - **参数说明**: + - `millisecondsTimeout`:毫秒超时时间。 + - **返回值**:消费结果。 + - **异常**:执行失败抛出 `TDengineError` 异常。 + +- `List Assignment { get; }` + - **接口说明**:获取分配信息。 + - **返回值**:分配信息。 + - **异常**:执行失败抛出 `TDengineError` 异常。 + +- `List Subscription()` + - **接口说明**:获取订阅的主题。 + - **返回值**:主题列表。 + - **异常**:执行失败抛出 `TDengineError` 异常。 + +- `void Subscribe(IEnumerable topic)` + - **接口说明**:订阅主题列表。 + - **参数说明**: + - `topic`:主题列表。 + - **异常**:执行失败抛出 `TDengineError` 异常。 + +- `void Subscribe(string topic)` + - **接口说明**:订阅单个主题。 + - **参数说明**: + - `topic`:主题。 + - **异常**:执行失败抛出 `TDengineError` 异常。 + +- `void Unsubscribe()` + - **接口说明**:取消订阅。 + - **异常**:执行失败抛出 `TDengineError` 异常。 + +- `void Commit(ConsumeResult consumerResult)` + - **接口说明**:提交消费结果。 + - **参数说明**: + - `consumerResult`:消费结果。 + - **异常**:执行失败抛出 `TDengineError` 异常。 + +- `List Commit()` + - **接口说明**:提交全部消费结果。 + - **返回值**:分区偏移量。 + - **异常**:执行失败抛出 `TDengineError` 异常。 + +- `void Commit(IEnumerable offsets)` + - **接口说明**:提交消费结果。 + - **参数说明**: + - `offsets`:分区偏移量。 + - **异常**:执行失败抛出 `TDengineError` 异常。 + +- `void Seek(TopicPartitionOffset tpo)` + - **接口说明**:跳转到分区偏移量。 + - **参数说明**: + - `tpo`:分区偏移量。 + - **异常**:执行失败抛出 `TDengineError` 异常。 + +- `List Committed(TimeSpan timeout)` + - **接口说明**:获取分区偏移量。 + - **参数说明**: + - `timeout`:超时时间(未使用)。 + - **返回值**:分区偏移量。 + - **异常**:执行失败抛出 `TDengineError` 异常。 + +- `List Committed(IEnumerable partitions, TimeSpan timeout)` + - **接口说明**:获取指定分区偏移量。 + - **参数说明**: + - `partitions`:分区列表。 + - `timeout`:超时时间(未使用)。 + - **返回值**:分区偏移量。 + - **异常**:执行失败抛出 `TDengineError` 异常。 + +- `Offset Position(TopicPartition partition)` + - **接口说明**:获取消费位置。 + - **参数说明**: + - `partition`:分区。 + - **返回值**:偏移量。 + - **异常**:执行失败抛出 `TDengineError` 异常。 + +- `void Close()` + - **接口说明**:关闭消费者。 + +#### 消费记录 + +`ConsumeResult` 类提供了消费结果相关接口: + +- `public List> Message` + - **接口说明**:获取消息列表。 + - **返回值**:消息列表。 + +`TmqMessage` 类提供了消息具体内容: + +```csharp + public class TmqMessage + { + public string TableName { get; set; } + public TValue Value { get; set; } + } +``` + +- `TableName`:表名 +- `Value`:消息内容 + +#### 分区信息 + +从 `ConsumeResult` 获取 `TopicPartitionOffset`: + +```csharp +public TopicPartitionOffset TopicPartitionOffset +``` + +`TopicPartitionOffset` 类提供了获取分区信息的接口: + +- `public string Topic { get; }` + - **接口说明**:获取主题。 + - **返回值**:主题。 + +- `public Partition Partition { get; }` + - **接口说明**:获取分区。 + - **返回值**:分区。 + +- `public Offset Offset { get; }` + - **接口说明**:获取偏移量。 + - **返回值**:偏移量。 + +- `public TopicPartition TopicPartition` + - **接口说明**:获取主题分区。 + - **返回值**:主题分区。 + +- `public string ToString()` + - **接口说明**:转换为字符串。 + - **返回值**:字符串信息。 + +#### 偏移量元数据 + +`Offset` 类提供了偏移量相关接口: + +- `public long Value` + - **接口说明**:获取偏移量值。 + - **返回值**:偏移量值。 + +#### 反序列化 + +C# 驱动提供了两个反序列化类:`ReferenceDeserializer` 和 `DictionaryDeserializer`。它们都实现了 `IDeserializer` 接口。 + +ReferenceDeserializer 用来将消费到的一条记录反序列化为一个对象,需要保证对象类的属性名与消费到的数据的列名能够对应,且类型能够匹配。 + +DictionaryDeserializer 则会将消费到的一行数据反序列化为一个 `Dictionary` 对象,其 key 为列名,值为对象。 + +ReferenceDeserializer 和 DictionaryDeserializer 的接口不会被用户直接调用,请参考使用样例。 \ No newline at end of file From 5ab0b112239da41c8630226e14b335a96a8cac9a Mon Sep 17 00:00:00 2001 From: sheyanjie-qq <249478495@qq.com> Date: Thu, 1 Aug 2024 14:26:55 +0800 Subject: [PATCH 07/14] mod sample code --- .../com/taos/example/JNIConnectExample.java | 6 +- .../com/taos/example/RESTConnectExample.java | 6 +- .../com/taos/example/WSConnectExample.java | 6 +- docs/zh/08-develop/01-connect/index.md | 8 +- docs/zh/08-develop/02-sql.md | 7 +- docs/zh/08-develop/04-schemaless.md | 6 ++ docs/zh/08-develop/05-stmt.md | 9 +- docs/zh/08-develop/07-tmq.md | 6 +- docs/zh/14-reference/05-connector/14-java.mdx | 2 +- .../com/taosdata/example/AbsConsumerLoop.java | 17 ++-- .../taosdata/example/AbsConsumerLoopFull.java | 4 +- .../taosdata/example/AbsWsConsumerLoop.java | 5 +- .../taosdata/example/ConsumerOffsetSeek.java | 6 +- .../com/taosdata/example/JdbcCreatDBDemo.java | 7 +- .../taosdata/example/JdbcInsertDataDemo.java | 10 +-- .../com/taosdata/example/JdbcQueryDemo.java | 11 ++- .../com/taosdata/example/JdbcReqIdDemo.java | 16 ++-- .../example/ParameterBindingBasicDemo.java | 49 +++-------- .../example/ParameterBindingBatchDemo.java | 83 +++++++++++++++++++ .../taosdata/example/SchemalessJniTest.java | 11 ++- .../taosdata/example/SchemalessWsTest.java | 7 +- .../example/WSParameterBindingBasicDemo.java | 3 +- 22 files changed, 171 insertions(+), 114 deletions(-) create mode 100644 examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ParameterBindingBatchDemo.java diff --git a/docs/examples/java/src/main/java/com/taos/example/JNIConnectExample.java b/docs/examples/java/src/main/java/com/taos/example/JNIConnectExample.java index 8905150a0a..8b9f27c5ab 100644 --- a/docs/examples/java/src/main/java/com/taos/example/JNIConnectExample.java +++ b/docs/examples/java/src/main/java/com/taos/example/JNIConnectExample.java @@ -20,15 +20,13 @@ public static void main(String[] args) throws SQLException { connProps.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); try (Connection conn = DriverManager.getConnection(jdbcUrl, connProps)) { - System.out.println("Connected"); + System.out.println("Connected to " + jdbcUrl + " successfully."); // you can use the connection for execute SQL here } catch (SQLException ex) { // handle any errors, please refer to the JDBC specifications for detailed exceptions info - System.out.println("SQLState: " + ex.getSQLState()); - System.out.println("Error Code: " + ex.getErrorCode()); - System.out.println("Message: " + ex.getMessage()); + System.out.println("Failed to connect to " + jdbcUrl + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); } } // ANCHOR_END: main diff --git a/docs/examples/java/src/main/java/com/taos/example/RESTConnectExample.java b/docs/examples/java/src/main/java/com/taos/example/RESTConnectExample.java index cd129db699..22bf1d61f4 100644 --- a/docs/examples/java/src/main/java/com/taos/example/RESTConnectExample.java +++ b/docs/examples/java/src/main/java/com/taos/example/RESTConnectExample.java @@ -9,15 +9,13 @@ public class RESTConnectExample { public static void main(String[] args) throws SQLException { String jdbcUrl = "jdbc:TAOS-RS://localhost:6041?user=root&password=taosdata"; try (Connection conn = DriverManager.getConnection(jdbcUrl)){ - System.out.println("Connected"); + System.out.println("Connected to " + jdbcUrl + " successfully."); // you can use the connection for execute SQL here } catch (SQLException ex) { // handle any errors, please refer to the JDBC specifications for detailed exceptions info - System.out.println("SQLState: " + ex.getSQLState()); - System.out.println("Error Code: " + ex.getErrorCode()); - System.out.println("Message: " + ex.getMessage()); + System.out.println("Failed to connect to " + jdbcUrl + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); } } // ANCHOR_END: main diff --git a/docs/examples/java/src/main/java/com/taos/example/WSConnectExample.java b/docs/examples/java/src/main/java/com/taos/example/WSConnectExample.java index 3f417841b2..b355a28f6f 100644 --- a/docs/examples/java/src/main/java/com/taos/example/WSConnectExample.java +++ b/docs/examples/java/src/main/java/com/taos/example/WSConnectExample.java @@ -21,15 +21,13 @@ public static void main(String[] args) throws SQLException { connProps.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); try (Connection conn = DriverManager.getConnection(jdbcUrl, connProps)){ - System.out.println("Connected"); + System.out.println("Connected to " + jdbcUrl + " successfully."); // you can use the connection for execute SQL here } catch (SQLException ex) { // handle any errors, please refer to the JDBC specifications for detailed exceptions info - System.out.println("SQLState: " + ex.getSQLState()); - System.out.println("Error Code: " + ex.getErrorCode()); - System.out.println("Message: " + ex.getMessage()); + System.out.println("Failed to connect to " + jdbcUrl + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); } } // ANCHOR_END: main diff --git a/docs/zh/08-develop/01-connect/index.md b/docs/zh/08-develop/01-connect/index.md index 29e363c019..08a39ac815 100644 --- a/docs/zh/08-develop/01-connect/index.md +++ b/docs/zh/08-develop/01-connect/index.md @@ -294,7 +294,7 @@ URL 和 Properties 的详细参数说明和如何使用详见 [API 说明](../..
### Websocket 连接 -各语言连接器建立 Websocket 连接代码样例。 +下面是各语言连接器建立 Websocket 连接代码样例。演示了如何使用 Websocket 连接方式连接到 TDengine 数据库,并对连接设定一些参数。整个过程主要涉及到数据库连接的建立和异常处理。 @@ -334,7 +334,8 @@ URL 和 Properties 的详细参数说明和如何使用详见 [API 说明](../.. ### 原生连接 -各语言连接器建立原生连接代码样例。 +下面是各语言连接器建立原生连接代码样例。演示了如何使用原生连接方式连接到 TDengine 数据库,并对连接设定一些参数。整个过程主要涉及到数据库连接的建立和异常处理。 + ```java @@ -366,7 +367,8 @@ URL 和 Properties 的详细参数说明和如何使用详见 [API 说明](../.. ### REST 连接 -各语言连接器建立 REST 连接代码样例。 +下面是各语言连接器建立 RESt 连接代码样例。演示了如何使用 REST 连接方式连接到 TDengine 数据库。整个过程主要涉及到数据库连接的建立和异常处理。 + ```java diff --git a/docs/zh/08-develop/02-sql.md b/docs/zh/08-develop/02-sql.md index eec1bcd70b..105b42d120 100644 --- a/docs/zh/08-develop/02-sql.md +++ b/docs/zh/08-develop/02-sql.md @@ -12,7 +12,8 @@ TDengine 对 SQL 语言提供了全面的支持,允许用户以熟悉的 SQL 下面介绍使用各语言连接器通过执行 SQL 完成建库、建表、写入数据和查询数据。 ## 建库和表 -以智能电表为例,展示如何使用连接器执行 SQL 来创建数据库和表。 +下面以智能电表为例,展示使用各语言连接器如何执行 SQL 命令创建一个名为 `power` 的数据库,然后使用 `power` 数据库为默认数据库。 +接着创建一个名为 `meters` 的超级表(STABLE),其表结构包含时间戳、电流、电压、相位等列,以及分组 ID 和位置作为标签。 @@ -40,7 +41,7 @@ TDengine 对 SQL 语言提供了全面的支持,允许用户以熟悉的 SQL ## 插入数据 -以智能电表为例,展示如何使用连接器执行 SQL 来插入数据。 +下面以智能电表为例,展示如何使用连接器执行 SQL 来插入数据到 `power` 数据库的 `meters` 超级表。样例使用 TDengine 自动建表 SQL 语法,写入 d1001 子表中 3 条数据,写入 d1002 子表中 1 条数据,然后打印出实际插入数据条数。 @@ -70,7 +71,7 @@ NOW 为系统内部函数,默认为客户端所在计算机当前时间。 NOW ## 查询数据 -以智能电表为例,展示如何使用各语言连接器执行 SQL 来查询数据,并将获取到的结果打印出来。 +下面以智能电表为例,展示如何使用各语言连接器执行 SQL 来查询数据,从 `power` 数据库 `meters` 超级表中查询最多 100 行数据,并将获取到的结果按行打印出来。 diff --git a/docs/zh/08-develop/04-schemaless.md b/docs/zh/08-develop/04-schemaless.md index 816b3aa170..734e9558a2 100644 --- a/docs/zh/08-develop/04-schemaless.md +++ b/docs/zh/08-develop/04-schemaless.md @@ -153,6 +153,12 @@ st,t1=3,t2=4,t3=t3 c1=3i64,c6="passit" 1626006833640000000 ## 无模式写入示例 下面以智能电表为例,介绍各语言连接器使用无模式写入接口写入数据的代码样例,包含了三种协议: InfluxDB 的行协议、OpenTSDB 的 TELNET 行协议和 OpenTSDB 的 JSON 格式协议。 +:::note +- 因为无模式写入自动建表规则与之前执行 SQL 样例中不同,因此运行代码样例前请确保 `meters`、`metric_telnet` 和 `metric_json` 表不存在。 +- OpenTSDB 的 TELNET 行协议和 OpenTSDB 的 JSON 格式协议只支持一个数据列,因此我们采用了其他示例。 + +::: + ### Websocket 连接 diff --git a/docs/zh/08-develop/05-stmt.md b/docs/zh/08-develop/05-stmt.md index 214984c86c..132a1b8850 100644 --- a/docs/zh/08-develop/05-stmt.md +++ b/docs/zh/08-develop/05-stmt.md @@ -13,7 +13,14 @@ import TabItem from "@theme/TabItem"; - 预编译:当使用参数绑定时,SQL 语句可以被预编译并缓存,后续使用不同的参数值执行时,可以直接使用预编译的版本,提高执行效率。 - 减少网络开销:参数绑定还可以减少发送到数据库的数据量,因为只需要发送参数值而不是完整的 SQL 语句,特别是在执行大量相似的插入或更新操作时,这种差异尤为明显。 -下面我们继续以智能电表为例,展示各语言连接器使用参数绑定高效写入的功能。 +下面我们继续以智能电表为例,展示各语言连接器使用参数绑定高效写入的功能: +1. 准备一个参数化的 SQL 插入语句,用于向超级表 `meters` 中插入数据。这个语句允许动态地指定子表名、标签和列值。 +2. 循环生成多个子表及其对应的数据行。对于每个子表: + - 设置子表的名称和标签值(分组 ID 和位置)。 + - 生成多行数据,每行包括一个时间戳、随机生成的电流、电压和相位值。 + - 执行批量插入操作,将这些数据行插入到对应的子表中。 +3. 最后打印实际插入表中的行数。 + ## Websocket 连接 diff --git a/docs/zh/08-develop/07-tmq.md b/docs/zh/08-develop/07-tmq.md index f548126e49..16a538757f 100644 --- a/docs/zh/08-develop/07-tmq.md +++ b/docs/zh/08-develop/07-tmq.md @@ -78,7 +78,8 @@ Java 连接器创建消费者的参数为 Properties, 可以设置的参数列 ### Websocket 连接 -介绍各语言连接器使用 Websocket 连接方式创建消费者。 +介绍各语言连接器使用 Websocket 连接方式创建消费者。指定连接的服务器地址,设置自动提交,从最新消息开始消费,指定 `group.id` 和 `client.id` 等信息。有的语言的连接器还支持反序列化参数。 + @@ -126,7 +127,8 @@ Java 连接器创建消费者的参数为 Properties, 可以设置的参数列 ### 原生连接 -介绍各语言连接器使用原生连接方式创建消费者。 +介绍各语言连接器使用原生连接方式创建消费者。指定连接的服务器地址,设置自动提交,从最新消息开始消费,指定 `group.id` 和 `client.id` 等信息。有的语言的连接器还支持反序列化参数。 + diff --git a/docs/zh/14-reference/05-connector/14-java.mdx b/docs/zh/14-reference/05-connector/14-java.mdx index acb1dee674..33f63916d2 100644 --- a/docs/zh/14-reference/05-connector/14-java.mdx +++ b/docs/zh/14-reference/05-connector/14-java.mdx @@ -1365,7 +1365,7 @@ JDBC 标准不支持数据订阅,因此本章所有接口都是扩展接口。 | reconnectIntervalMs | 自动重连重试间隔,单位毫秒。仅在 enableCompression 为 true 时生效。 | 2000 ms | | reconnectRetryCount | 自动重连重试次数。仅在 enableCompression 为 true 时生效。 | 3 | -其他参数请参考:[Consumer 参数列表](../../develop/tmq/#数据订阅相关参数), 注意TDengine服务端自 3.2.0.0 版本开始消息订阅中的 auto.offset.reset 默认值发生变化。 +其他参数请参考:[Consumer 参数列表](../../../develop/tmq/#创建参数), 注意TDengine服务端自 3.2.0.0 版本开始消息订阅中的 auto.offset.reset 默认值发生变化。 - `public void subscribe(Collection topics) throws SQLException` - **接口说明**:订阅一组主题。 diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoop.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoop.java index 62e3939573..90e6a950cd 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoop.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoop.java @@ -39,8 +39,7 @@ try { this.consumer = new TaosConsumer<>(config); } catch (SQLException ex) { // handle any errors, please refer to the JDBC specifications for detailed exceptions info - System.out.println("Error Code: " + ex.getErrorCode()); - System.out.println("Message: " + ex.getMessage()); + System.out.println("Failed to create jni consumer with " + config.getProperty("bootstrap.servers") + " ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); throw new SQLException("Failed to create consumer", ex); } // ANCHOR_END: create_consumer @@ -66,9 +65,8 @@ try { } } catch (SQLException ex){ // handle any errors, please refer to the JDBC specifications for detailed exceptions info - System.out.println("Error Code: " + ex.getErrorCode()); - System.out.println("Message: " + ex.getMessage()); - + System.out.println("Failed to poll data; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + throw new SQLException("Failed to poll data", ex); } finally { consumer.close(); shutdownLatch.countDown(); @@ -94,9 +92,8 @@ try { } } catch (SQLException ex){ // handle any errors, please refer to the JDBC specifications for detailed exceptions info - System.out.println("Error Code: " + ex.getErrorCode()); - System.out.println("Message: " + ex.getMessage()); - + System.out.println("Failed to execute consumer functions. ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + throw new SQLException("Failed to execute consumer functions", ex); } finally { consumer.close(); shutdownLatch.countDown(); @@ -110,8 +107,8 @@ try { consumer.unsubscribe(); } catch (SQLException ex){ // handle any errors, please refer to the JDBC specifications for detailed exceptions info - System.out.println("Error Code: " + ex.getErrorCode()); - System.out.println("Message: " + ex.getMessage()); + System.out.println("Failed to unsubscribe consumer. ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + throw new SQLException("Failed to unsubscribe consumer", ex); } finally { consumer.close(); } diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoopFull.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoopFull.java index af3537ef0e..bd8f1799f6 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoopFull.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoopFull.java @@ -38,8 +38,8 @@ public abstract class AbsConsumerLoopFull { try { this.consumer = new TaosConsumer<>(config); } catch (SQLException ex) { - // handle exception - System.out.println("SQLException: " + ex.getMessage()); + // handle any errors, please refer to the JDBC specifications for detailed exceptions info + System.out.println("Failed to create jni consumer, host : " + config.getProperty("bootstrap.servers") + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); throw new SQLException("Failed to create consumer", ex); } diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsWsConsumerLoop.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsWsConsumerLoop.java index 98ff5657d8..690c05841c 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsWsConsumerLoop.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsWsConsumerLoop.java @@ -39,13 +39,12 @@ try { this.consumer = new TaosConsumer<>(config); } catch (SQLException ex) { // handle any errors, please refer to the JDBC specifications for detailed exceptions info - System.out.println("Error Code: " + ex.getErrorCode()); - System.out.println("Message: " + ex.getMessage()); + System.out.println("Failed to create ws consumer with " + config.getProperty("bootstrap.servers") + " ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); throw new SQLException("Failed to create consumer", ex); } // ANCHOR_END: create_consumer - this.topics = Collections.singletonList("topic_speed"); + this.topics = Collections.singletonList("topic_meters"); this.shutdown = new AtomicBoolean(false); this.shutdownLatch = new CountDownLatch(1); } diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ConsumerOffsetSeek.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ConsumerOffsetSeek.java index 3b1ff88b28..b9463d30f7 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ConsumerOffsetSeek.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ConsumerOffsetSeek.java @@ -54,9 +54,9 @@ try (TaosConsumer consumer = new TaosConsumer<>(conf // you can handle data here } } catch (SQLException ex) { - // handle exception - System.out.println("SQLException: " + ex.getMessage()); - throw new SQLException("Failed to create consumer", ex); + // handle any errors, please refer to the JDBC specifications for detailed exceptions info + System.out.println("Failed to execute consumer functions. server: " + config.getProperty("bootstrap.servers") + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + throw new SQLException("Failed to execute consumer functions", ex); } // ANCHOR_END: consumer_seek } diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcCreatDBDemo.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcCreatDBDemo.java index b2246e96cf..d02b3c8789 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcCreatDBDemo.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcCreatDBDemo.java @@ -15,7 +15,7 @@ public class JdbcCreatDBDemo { public static void main(String[] args) throws SQLException { -final String url = "jdbc:TAOS://" + host + ":6030/?user=" + user + "&password=" + password; +final String jdbcUrl = "jdbc:TAOS://" + host + ":6030/?user=" + user + "&password=" + password; // get connection Properties properties = new Properties(); @@ -24,7 +24,7 @@ properties.setProperty("locale", "en_US.UTF-8"); properties.setProperty("timezone", "UTC-8"); System.out.println("get connection starting..."); // ANCHOR: create_db_and_table -try (Connection connection = DriverManager.getConnection(url, properties); +try (Connection connection = DriverManager.getConnection(jdbcUrl, properties); Statement stmt = connection.createStatement()) { // create database @@ -44,8 +44,7 @@ try (Connection connection = DriverManager.getConnection(url, properties); } catch (SQLException ex) { // handle any errors, please refer to the JDBC specifications for detailed exceptions info - System.out.println("Error Code: " + ex.getErrorCode()); - System.out.println("Message: " + ex.getMessage()); + System.out.println("Failed to create db and table, url:" + jdbcUrl + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); } // ANCHOR_END: create_db_and_table diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcInsertDataDemo.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcInsertDataDemo.java index 76e16c9cee..7fc6d5137d 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcInsertDataDemo.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcInsertDataDemo.java @@ -15,7 +15,7 @@ public class JdbcInsertDataDemo { public static void main(String[] args) throws SQLException { -final String url = "jdbc:TAOS://" + host + ":6030/?user=" + user + "&password=" + password; +final String jdbcUrl = "jdbc:TAOS://" + host + ":6030/?user=" + user + "&password=" + password; // get connection Properties properties = new Properties(); @@ -24,7 +24,7 @@ properties.setProperty("locale", "en_US.UTF-8"); properties.setProperty("timezone", "UTC-8"); System.out.println("get connection starting..."); // ANCHOR: insert_data -try (Connection connection = DriverManager.getConnection(url, properties); +try (Connection connection = DriverManager.getConnection(jdbcUrl, properties); Statement stmt = connection.createStatement()) { // insert data, please make sure the database and table are created before @@ -39,11 +39,11 @@ try (Connection connection = DriverManager.getConnection(url, properties); "(NOW + 1a, 10.30000, 218, 0.25000) "; int affectedRows = stmt.executeUpdate(insertQuery); // you can check affectedRows here - System.out.println("insert " + affectedRows + " rows."); + System.out.println("inserted into " + affectedRows + " rows to power.meters successfully."); } catch (SQLException ex) { // handle any errors, please refer to the JDBC specifications for detailed exceptions info - System.out.println("Error Code: " + ex.getErrorCode()); - System.out.println("Message: " + ex.getMessage()); + System.out.println("Failed to insert data to power.meters, url:" + jdbcUrl + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + } // ANCHOR_END: insert_data } diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcQueryDemo.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcQueryDemo.java index fdbab204c2..30a835bb11 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcQueryDemo.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcQueryDemo.java @@ -15,7 +15,7 @@ public class JdbcQueryDemo { public static void main(String[] args) throws SQLException { -final String url = "jdbc:TAOS://" + host + ":6030/?user=" + user + "&password=" + password; +final String jdbcUrl = "jdbc:TAOS://" + host + ":6030/?user=" + user + "&password=" + password; // get connection Properties properties = new Properties(); @@ -24,10 +24,10 @@ properties.setProperty("locale", "en_US.UTF-8"); properties.setProperty("timezone", "UTC-8"); System.out.println("get connection starting..."); // ANCHOR: query_data -try (Connection connection = DriverManager.getConnection(url, properties); +try (Connection connection = DriverManager.getConnection(jdbcUrl, properties); Statement stmt = connection.createStatement(); // query data, make sure the database and table are created before - ResultSet resultSet = stmt.executeQuery("SELECT * FROM power.meters")) { + ResultSet resultSet = stmt.executeQuery("SELECT ts, current, location FROM power.meters limit 100")) { Timestamp ts; float current; @@ -39,12 +39,11 @@ try (Connection connection = DriverManager.getConnection(url, properties); location = resultSet.getString("location"); // you can check data here - System.out.printf("%s, %f, %s\n", ts, current, location); + System.out.printf("ts: %s, current: %f, location: %s %n", ts, current, location); } } catch (SQLException ex) { // handle any errors, please refer to the JDBC specifications for detailed exceptions info - System.out.println("Error Code: " + ex.getErrorCode()); - System.out.println("Message: " + ex.getMessage()); + System.out.println("Failed to query data from power.meters, url:" + jdbcUrl + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); } // ANCHOR_END: query_data } diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcReqIdDemo.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcReqIdDemo.java index 5fb7e9760e..cc557c18c5 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcReqIdDemo.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcReqIdDemo.java @@ -15,7 +15,7 @@ public class JdbcReqIdDemo { public static void main(String[] args) throws SQLException { -final String url = "jdbc:TAOS://" + host + ":6030/?user=" + user + "&password=" + password; +final String jdbcUrl = "jdbc:TAOS://" + host + ":6030/?user=" + user + "&password=" + password; // get connection Properties properties = new Properties(); @@ -25,17 +25,11 @@ properties.setProperty("timezone", "UTC-8"); System.out.println("get connection starting..."); // ANCHOR: with_reqid -try (Connection connection = DriverManager.getConnection(url, properties); +try (Connection connection = DriverManager.getConnection(jdbcUrl, properties); // Create a statement that allows specifying a request ID AbstractStatement aStmt = (AbstractStatement) connection.createStatement()) { - boolean hasResultSet = aStmt.execute("CREATE DATABASE IF NOT EXISTS power", 1L); - assert !hasResultSet; - - int rowsAffected = aStmt.executeUpdate("USE power", 2L); - assert rowsAffected == 0; - - try (ResultSet rs = aStmt.executeQuery("SELECT * FROM meters limit 1", 3L)) { + try (ResultSet rs = aStmt.executeQuery("SELECT ts, current, location FROM power.meters limit 1", 3L)) { while (rs.next()) { Timestamp timestamp = rs.getTimestamp(1); System.out.println("timestamp = " + timestamp); @@ -43,8 +37,8 @@ try (Connection connection = DriverManager.getConnection(url, properties); } } catch (SQLException ex) { // handle any errors, please refer to the JDBC specifications for detailed exceptions info - System.out.println("Error Code: " + ex.getErrorCode()); - System.out.println("Message: " + ex.getMessage()); + System.out.println("Failed to execute sql with reqId, url:" + jdbcUrl + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + } // ANCHOR_END: with_reqid } diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ParameterBindingBasicDemo.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ParameterBindingBasicDemo.java index d5f547b50f..469316efc7 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ParameterBindingBasicDemo.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ParameterBindingBasicDemo.java @@ -1,14 +1,9 @@ package com.taosdata.example; import com.taosdata.jdbc.TSDBPreparedStatement; -import com.taosdata.jdbc.utils.StringUtils; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.sql.Statement; +import java.sql.*; import java.util.ArrayList; -import java.util.List; import java.util.Random; // ANCHOR: para_bind @@ -29,7 +24,6 @@ public class ParameterBindingBasicDemo { String sql = "INSERT INTO ? USING meters TAGS(?,?) VALUES (?,?,?,?)"; try (TSDBPreparedStatement pstmt = conn.prepareStatement(sql).unwrap(TSDBPreparedStatement.class)) { - for (int i = 1; i <= numOfSubTable; i++) { // set table name pstmt.setTableName("d_bind_" + i); @@ -38,40 +32,23 @@ public class ParameterBindingBasicDemo { pstmt.setTagInt(0, i); pstmt.setTagString(1, "location_" + i); - // set column ts - ArrayList tsList = new ArrayList<>(); + // set columns long current = System.currentTimeMillis(); - for (int j = 0; j < numOfRow; j++) - tsList.add(current + j); - pstmt.setTimestamp(0, tsList); - - // set column current - ArrayList f1List = new ArrayList<>(); - for (int j = 0; j < numOfRow; j++) - f1List.add(random.nextFloat() * 30); - pstmt.setFloat(1, f1List); - - // set column voltage - ArrayList f2List = new ArrayList<>(); - for (int j = 0; j < numOfRow; j++) - f2List.add(random.nextInt(300)); - pstmt.setInt(2, f2List); - - // set column phase - ArrayList f3List = new ArrayList<>(); - for (int j = 0; j < numOfRow; j++) - f3List.add(random.nextFloat()); - pstmt.setFloat(3, f3List); - // add column - pstmt.columnDataAddBatch(); + for (int j = 0; j < numOfRow; j++) { + pstmt.setTimestamp(1, new Timestamp(current + j)); + pstmt.setFloat(2, random.nextFloat() * 30); + pstmt.setInt(3, random.nextInt(300)); + pstmt.setFloat(4, random.nextFloat()); + pstmt.addBatch(); + } + int [] exeResult = pstmt.executeBatch(); + // you can check exeResult here + System.out.println("insert " + exeResult.length + " rows."); } - // execute column - pstmt.columnDataExecuteBatch(); } } catch (SQLException ex) { // handle any errors, please refer to the JDBC specifications for detailed exceptions info - System.out.println("Error Code: " + ex.getErrorCode()); - System.out.println("Message: " + ex.getMessage()); + System.out.println("Failed to insert to table meters using stmt, url: " + jdbcUrl + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); } } diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ParameterBindingBatchDemo.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ParameterBindingBatchDemo.java new file mode 100644 index 0000000000..60d76eee4f --- /dev/null +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ParameterBindingBatchDemo.java @@ -0,0 +1,83 @@ +package com.taosdata.example; + +import com.taosdata.jdbc.TSDBPreparedStatement; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.Random; + +// ANCHOR: para_bind +public class ParameterBindingBatchDemo { + + // modify host to your own + private static final String host = "127.0.0.1"; + private static final Random random = new Random(System.currentTimeMillis()); + private static final int numOfSubTable = 10, numOfRow = 10; + + public static void main(String[] args) throws SQLException { + + String jdbcUrl = "jdbc:TAOS://" + host + ":6030/"; + try (Connection conn = DriverManager.getConnection(jdbcUrl, "root", "taosdata")) { + + init(conn); + + String sql = "INSERT INTO ? USING meters TAGS(?,?) VALUES (?,?,?,?)"; + + try (TSDBPreparedStatement pstmt = conn.prepareStatement(sql).unwrap(TSDBPreparedStatement.class)) { + + for (int i = 1; i <= numOfSubTable; i++) { + // set table name + pstmt.setTableName("d_bind_" + i); + + // set tags + pstmt.setTagInt(0, i); + pstmt.setTagString(1, "location_" + i); + + // set column ts + ArrayList tsList = new ArrayList<>(); + long current = System.currentTimeMillis(); + for (int j = 0; j < numOfRow; j++) + tsList.add(current + j); + pstmt.setTimestamp(0, tsList); + + // set column current + ArrayList f1List = new ArrayList<>(); + for (int j = 0; j < numOfRow; j++) + f1List.add(random.nextFloat() * 30); + pstmt.setFloat(1, f1List); + + // set column voltage + ArrayList f2List = new ArrayList<>(); + for (int j = 0; j < numOfRow; j++) + f2List.add(random.nextInt(300)); + pstmt.setInt(2, f2List); + + // set column phase + ArrayList f3List = new ArrayList<>(); + for (int j = 0; j < numOfRow; j++) + f3List.add(random.nextFloat()); + pstmt.setFloat(3, f3List); + // add column + pstmt.columnDataAddBatch(); + } + // execute column + pstmt.columnDataExecuteBatch(); + } + } catch (SQLException ex) { + // handle any errors, please refer to the JDBC specifications for detailed exceptions info + System.out.println("Failed to insert to table meters using stmt, url: " + jdbcUrl + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + } + } + + private static void init(Connection conn) throws SQLException { + try (Statement stmt = conn.createStatement()) { + stmt.execute("CREATE DATABASE IF NOT EXISTS power"); + stmt.execute("USE power"); + stmt.execute("CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); + } + } +} +// ANCHOR_END: para_bind diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/SchemalessJniTest.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/SchemalessJniTest.java index 238ad35502..8f5fe0e7cf 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/SchemalessJniTest.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/SchemalessJniTest.java @@ -13,12 +13,12 @@ import java.sql.Statement; public class SchemalessJniTest { private static final String host = "127.0.0.1"; private static final String lineDemo = "meters,groupid=2,location=California.SanFrancisco current=10.3000002f64,voltage=219i32,phase=0.31f64 1626006833639"; - private static final String telnetDemo = "stb0_0 1707095283260 4 host=host0 interface=eth0"; - private static final String jsonDemo = "{\"metric\": \"meter_current\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}"; + private static final String telnetDemo = "metric_telnet 1707095283260 4 host=host0 interface=eth0"; + private static final String jsonDemo = "{\"metric\": \"metric_json\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}"; public static void main(String[] args) throws SQLException { - final String url = "jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata"; - try (Connection connection = DriverManager.getConnection(url)) { + final String jdbcUrl = "jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata"; + try (Connection connection = DriverManager.getConnection(jdbcUrl)) { init(connection); AbstractConnection conn = connection.unwrap(AbstractConnection.class); @@ -27,8 +27,7 @@ public class SchemalessJniTest { conn.write(jsonDemo, SchemalessProtocolType.JSON, SchemalessTimestampType.NOT_CONFIGURED); } catch (SQLException ex) { // handle any errors, please refer to the JDBC specifications for detailed exceptions info - System.out.println("Error Code: " + ex.getErrorCode()); - System.out.println("Message: " + ex.getMessage()); + System.out.println("Failed to insert data with schemaless, host:" + host + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); } } diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/SchemalessWsTest.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/SchemalessWsTest.java index ed5444a4ec..922781af56 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/SchemalessWsTest.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/SchemalessWsTest.java @@ -13,8 +13,8 @@ import java.sql.Statement; public class SchemalessWsTest { private static final String host = "127.0.0.1"; private static final String lineDemo = "meters,groupid=2,location=California.SanFrancisco current=10.3000002f64,voltage=219i32,phase=0.31f64 1626006833639"; - private static final String telnetDemo = "stb0_0 1707095283260 4 host=host0 interface=eth0"; - private static final String jsonDemo = "{\"metric\": \"meter_current\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}"; + private static final String telnetDemo = "metric_telnet 1707095283260 4 host=host0 interface=eth0"; + private static final String jsonDemo = "{\"metric\": \"metric_json\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}"; public static void main(String[] args) throws SQLException { final String url = "jdbc:TAOS-RS://" + host + ":6041?user=root&password=taosdata&batchfetch=true"; @@ -27,8 +27,7 @@ public class SchemalessWsTest { conn.write(jsonDemo, SchemalessProtocolType.JSON, SchemalessTimestampType.SECONDS); } catch (SQLException ex) { // handle any errors, please refer to the JDBC specifications for detailed exceptions info - System.out.println("Error Code: " + ex.getErrorCode()); - System.out.println("Message: " + ex.getMessage()); + System.out.println("Failed to insert data with schemaless, host:" + host + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); } } diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WSParameterBindingBasicDemo.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WSParameterBindingBasicDemo.java index 9501d4adab..9eca3c973a 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WSParameterBindingBasicDemo.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WSParameterBindingBasicDemo.java @@ -49,8 +49,7 @@ public class WSParameterBindingBasicDemo { } } catch (SQLException ex) { // handle any errors, please refer to the JDBC specifications for detailed exceptions info - System.out.println("Error Code: " + ex.getErrorCode()); - System.out.println("Message: " + ex.getMessage()); + System.out.println("Failed to insert to table meters using stmt, url: " + jdbcUrl + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); } } From f399771a2f0124c7fcde508178238886fecf05f1 Mon Sep 17 00:00:00 2001 From: sheyanjie-qq <249478495@qq.com> Date: Thu, 1 Aug 2024 15:15:10 +0800 Subject: [PATCH 08/14] mod reference --- docs/zh/14-reference/05-connector/14-java.mdx | 373 +++++++++--------- docs/zh/14-reference/05-connector/20-go.mdx | 2 +- .../taosdata/example/AbsWsConsumerLoop.java | 4 +- 3 files changed, 182 insertions(+), 197 deletions(-) diff --git a/docs/zh/14-reference/05-connector/14-java.mdx b/docs/zh/14-reference/05-connector/14-java.mdx index 33f63916d2..322c2091ac 100644 --- a/docs/zh/14-reference/05-connector/14-java.mdx +++ b/docs/zh/14-reference/05-connector/14-java.mdx @@ -212,17 +212,14 @@ TDengine 的 JDBC URL 规范格式为: **注意**:使用 JDBC 原生连接,taos-jdbcdriver 需要依赖客户端驱动(Linux 下是 libtaos.so;Windows 下是 taos.dll;macOS 下是 libtaos.dylib)。 对于原生连接 url 中支持的配置参数如下: - -| 属性 | 描述 | 默认值 | -|------------------|--------------------------------------------------------------------------------------------------------|-----------------| -| user | 登录 TDengine 用户名 | 'root' | -| password | 用户登录密码 | 'taosdata' | -| cfgdir | 客户端配置文件目录路径,Linux OS 上默认值 `/etc/taos`,Windows OS 上默认值 `C:/TDengine/cfg` | 系统依赖 | -| charset | 客户端使用的字符集 | 系统字符集 | -| locale | 客户端语言环境 | 系统当前 locale | -| timezone | 客户端使用的时区 | 系统当前时区 | -| batchfetch | 在执行查询时批量拉取结果集;false:逐行拉取结果集。开启批量拉取可以有效的提升查询性能 | true | -| batchErrorIgnore | true:在执行 Statement 的 executeBatch 时,如果中间有一条 SQL 执行失败将继续执行下面的 SQL。false:不再执行失败 SQL 后的任何语句 | false | +- user:登录 TDengine 用户名,默认值 'root'。 +- password:用户登录密码,默认值 'taosdata'。 +- cfgdir:客户端配置文件目录路径,Linux OS 上默认值 `/etc/taos`,Windows OS 上默认值 `C:/TDengine/cfg`。 +- charset:客户端使用的字符集,默认值为系统字符集。 +- locale:客户端语言环境,默认值系统当前 locale。 +- timezone:客户端使用的时区,默认值为系统当前时区。 +- batchfetch: true:在执行查询时批量拉取结果集;false:逐行拉取结果集。默认值为:true。开启批量拉取同时获取一批数据在查询数据量较大时批量拉取可以有效的提升查询性能。 +- batchErrorIgnore:true:在执行 Statement 的 executeBatch 时,如果中间有一条 SQL 执行失败将继续执行下面的 SQL。false:不再执行失败 SQL 后的任何语句。默认值为:false。 JDBC 原生连接的使用请参见[视频教程](https://www.taosdata.com/blog/2020/11/11/1955.html)。 @@ -244,20 +241,16 @@ TDengine 中,只要保证 firstEp 和 secondEp 中一个节点有效,就可 3. 使用 6041 作为连接端口。 对于 Websocket 和 REST 连接,url 中的配置参数如下: - -| 属性 | 描述 | 默认值 | -|-------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------| -| user | 登录 TDengine 用户名 | 'root' | -| password | 用户登录密码 | 'taosdata' | -| batchfetch | true:在执行查询时批量拉取结果集;false:逐行拉取结果集。逐行拉取结果集使用 HTTP 方式进行数据传输。JDBC REST 连接支持批量拉取数据功能。taos-jdbcdriver 与 TDengine 之间通过 WebSocket 连接进行数据传输,提升查询性能。 | false | -| charset | 当开启批量拉取数据时,指定解析字符串数据的字符集。 | | -| batchErrorIgnore | true:在执行 Statement 的 executeBatch 时,如果中间有一条 SQL 执行失败,继续执行下面的 SQL。false:不再执行失败 SQL 后的任何语句。 | false | -| httpConnectTimeout| 连接超时时间,单位 ms | 60000 | -| httpSocketTimeout | socket 超时时间,单位 ms。仅在 batchfetch 设置为 false 时生效。 | 60000 | -| messageWaitTimeout| 消息超时时间, 单位 ms。仅在 batchfetch 设置为 true 时生效。 | 60000 | -| useSSL | 连接中是否使用 SSL。 | | -| httpPoolSize | REST 并发请求大小 | 20 | - +- user:登录 TDengine 用户名,默认值 'root'。 +- password:用户登录密码,默认值 'taosdata'。 +- batchfetch: true:在执行查询时批量拉取结果集;false:逐行拉取结果集。默认值为:false。逐行拉取结果集使用 HTTP 方式进行数据传输。JDBC REST 连接支持批量拉取数据功能。taos-jdbcdriver 与 TDengine 之间通过 WebSocket 连接进行数据传输。相较于 HTTP,WebSocket 可以使 JDBC REST 连接支持大数据量查询,并提升查询性能。 +- charset: 当开启批量拉取数据时,指定解析字符串数据的字符集。 +- batchErrorIgnore:true:在执行 Statement 的 executeBatch 时,如果中间有一条 SQL 执行失败,继续执行下面的 SQL 了。false:不再执行失败 SQL 后的任何语句。默认值为:false。 +- httpConnectTimeout: 连接超时时间,单位 ms, 默认值为 60000。 +- httpSocketTimeout: socket 超时时间,单位 ms,默认值为 60000。仅在 batchfetch 设置为 false 时生效。 +- messageWaitTimeout: 消息超时时间, 单位 ms, 默认值为 60000。 仅在 batchfetch 设置为 true 时生效。 +- useSSL: 连接中是否使用 SSL。 +- httpPoolSize: REST 并发请求大小,默认 20。 **注意**:部分配置项(比如:locale、timezone)在 REST 连接中不生效。 @@ -274,31 +267,27 @@ TDengine 中,只要保证 firstEp 和 secondEp 中一个节点有效,就可 > **注意**:应用中设置的 client parameter 为进程级别的,即如果要更新 client 的参数,需要重启应用。这是因为 client parameter 是全局参数,仅在应用程序的第一次设置生效。 -properties 中的配置参数如下(**注意**:属性使用需要加上类名,如 `TSDBDriver.PROPERTY_KEY_USER` ): - -| 属性 | 描述 | 默认值 | -|-------------------------------------------|------------------------------------------------------------------------------------------------------------------------------|----------------------| -| PROPERTY_KEY_USER | 登录 TDengine 用户名 | 'root' | -| PROPERTY_KEY_PASSWORD | 用户登录密码 | 'taosdata' | -| PROPERTY_KEY_BATCH_LOAD | 在执行查询时批量拉取结果集;false:逐行拉取结果集 | false | -| PROPERTY_KEY_BATCH_ERROR_IGNORE | 在执行 Statement 的 executeBatch 时,如果中间有一条 SQL 执行失败,继续执行下面的 SQL。false:不再执行失败 SQL 后的任何语句。 | false | -| PROPERTY_KEY_CONFIG_DIR | 仅在使用 JDBC 原生连接时生效。客户端配置文件目录路径 | Linux: `/etc/taos`, Windows: `C:/TDengine/cfg` | -| PROPERTY_KEY_CHARSET | 客户端使用的字符集 | 系统字符集 | -| PROPERTY_KEY_LOCALE | 仅在使用 JDBC 原生连接时生效。客户端语言环境 | 系统当前 locale | -| PROPERTY_KEY_TIME_ZONE | 仅在使用 JDBC 原生连接时生效。客户端使用的时区 | 系统当前时区 | -| HTTP_CONNECT_TIMEOUT | 连接超时时间,单位 ms。仅在 REST 连接时生效。 | 60000 | -| HTTP_SOCKET_TIMEOUT | socket 超时时间,单位 ms。仅在 REST 连接且 batchfetch 设置为 false 时生效。 | 60000 | -| PROPERTY_KEY_MESSAGE_WAIT_TIMEOUT | 消息超时时间, 单位 ms。仅在 REST 连接且 batchfetch 设置为 true 时生效。 | 60000 | -| PROPERTY_KEY_USE_SSL | 连接中是否使用 SSL。仅在 REST 连接时生效。 | | -| HTTP_POOL_SIZE | REST 并发请求大小 | 20 | -| PROPERTY_KEY_ENABLE_COMPRESSION | 传输过程是否启用压缩。仅在使用 REST/Websocket 连接时生效。 | false | -| PROPERTY_KEY_ENABLE_AUTO_RECONNECT | 是否启用自动重连。仅在使用 Websocket 连接时生效。 | false | -| PROPERTY_KEY_RECONNECT_INTERVAL_MS | 自动重连重试间隔,单位毫秒。仅在 PROPERTY_KEY_ENABLE_AUTO_RECONNECT 为 true 时生效。 | 2000 | -| PROPERTY_KEY_RECONNECT_RETRY_COUNT | 自动重连重试次数。仅在 PROPERTY_KEY_ENABLE_AUTO_RECONNECT 为 true 时生效。 | 3 | -| PROPERTY_KEY_DISABLE_SSL_CERT_VALIDATION | 关闭 SSL 证书验证。仅在使用 Websocket 连接时生效。 | false | - +properties 中的配置参数如下: +- TSDBDriver.PROPERTY_KEY_USER:登录 TDengine 用户名,默认值 'root'。 +- TSDBDriver.PROPERTY_KEY_PASSWORD:用户登录密码,默认值 'taosdata'。 +- TSDBDriver.PROPERTY_KEY_BATCH_LOAD: true:在执行查询时批量拉取结果集;false:逐行拉取结果集。默认值为:false。 +- TSDBDriver.PROPERTY_KEY_BATCH_ERROR_IGNORE:true:在执行 Statement 的 executeBatch 时,如果中间有一条 SQL 执行失败,继续执行下面的 sq 了。false:不再执行失败 SQL 后的任何语句。默认值为:false。 +- TSDBDriver.PROPERTY_KEY_CONFIG_DIR:仅在使用 JDBC 原生连接时生效。客户端配置文件目录路径,Linux OS 上默认值 `/etc/taos`,Windows OS 上默认值 `C:/TDengine/cfg`。 +- TSDBDriver.PROPERTY_KEY_CHARSET:客户端使用的字符集,默认值为系统字符集。 +- TSDBDriver.PROPERTY_KEY_LOCALE:仅在使用 JDBC 原生连接时生效。 客户端语言环境,默认值系统当前 locale。 +- TSDBDriver.PROPERTY_KEY_TIME_ZONE:仅在使用 JDBC 原生连接时生效。 客户端使用的时区,默认值为系统当前时区。因为历史的原因,我们只支持POSIX标准的部分规范,如UTC-8(代表中国上上海), GMT-8,Asia/Shanghai 这几种形式。 +- TSDBDriver.HTTP_CONNECT_TIMEOUT: 连接超时时间,单位 ms, 默认值为 60000。仅在 REST 连接时生效。 +- TSDBDriver.HTTP_SOCKET_TIMEOUT: socket 超时时间,单位 ms,默认值为 60000。仅在 REST 连接且 batchfetch 设置为 false 时生效。 +- TSDBDriver.PROPERTY_KEY_MESSAGE_WAIT_TIMEOUT: 消息超时时间, 单位 ms, 默认值为 60000。 仅在 REST 连接且 batchfetch 设置为 true 时生效。 +- TSDBDriver.PROPERTY_KEY_USE_SSL: 连接中是否使用 SSL。仅在 REST 连接时生效。 +- TSDBDriver.HTTP_POOL_SIZE: REST 并发请求大小,默认 20。 +- TSDBDriver.PROPERTY_KEY_ENABLE_COMPRESSION: 传输过程是否启用压缩。仅在使用 REST/Websocket 连接时生效。true: 启用,false: 不启用。默认为 false。 +- TSDBDriver.PROPERTY_KEY_ENABLE_AUTO_RECONNECT: 是否启用自动重连。仅在使用 Websocket 连接时生效。true: 启用,false: 不启用。默认为 false。 > **注意**:启用自动重连仅对简单执行 SQL 语句以及 无模式写入、数据订阅有效。对于参数绑定无效。自动重连仅对连接建立时通过参数指定数据库有效,对后面的 `use db` 语句切换数据库无效。 +- TSDBDriver.PROPERTY_KEY_RECONNECT_INTERVAL_MS: 自动重连重试间隔,单位毫秒,默认值 2000。仅在 PROPERTY_KEY_ENABLE_AUTO_RECONNECT 为 true 时生效。 +- TSDBDriver.PROPERTY_KEY_RECONNECT_RETRY_COUNT: 自动重连重试次数,默认值 3,仅在 PROPERTY_KEY_ENABLE_AUTO_RECONNECT 为 true 时生效。 +- TSDBDriver.PROPERTY_KEY_DISABLE_SSL_CERT_VALIDATION: 关闭 SSL 证书验证 。仅在使用 Websocket 连接时生效。true: 启用,false: 不启用。默认为 false。 此外对 JDBC 原生连接,通过指定 URL 和 Properties 还可以指定其他参数,比如日志级别、SQL 长度等。更多详细配置请参考[客户端配置](../../reference/config/)。 @@ -315,142 +304,142 @@ properties 中的配置参数如下(**注意**:属性使用需要加上类 #### 接口说明 - `Connection connect(String url, java.util.Properties info) throws SQLException` - - **接口说明**:连接 TDengine 数据库 + - **接口说明**:连接 TDengine 数据库。 - **参数说明**: - - `url`:连接地址 url,详见上文 URL 规范 - - `info`:连接属性,详见上文 Properties 章节 - - **返回值**:连接对象 - - **异常**:连接失败抛出 `SQLException` 异常 + - `url`:连接地址 url,详见上文 URL 规范。 + - `info`:连接属性,详见上文 Properties 章节。 + - **返回值**:连接对象。 + - **异常**:连接失败抛出 `SQLException` 异常。 - `boolean acceptsURL(String url) throws SQLException` - - **接口说明**:判断驱动是否支持 url + - **接口说明**:判断驱动是否支持 url。 - **参数说明**: - - `url`:连接地址 url - - **返回值**:`true`:支持,`false`:不支持 - - **异常**:url 非法抛出 `SQLException` 异常 + - `url`:连接地址 url。 + - **返回值**:`true`:支持,`false`:不支持。 + - **异常**:url 非法抛出 `SQLException` 异常。 - `DriverPropertyInfo[] getPropertyInfo(String url, java.util.Properties info) throws SQLException` - - **接口说明**:获取尝试连接数据库时可能需要的所有属性的详细信息。这些属性信息被封装在 DriverPropertyInfo 对象数组中返回。每个 DriverPropertyInfo 对象包含了一个数据库连接属性的详细信息,比如属性名、属性值、描述等 + - **接口说明**:获取尝试连接数据库时可能需要的所有属性的详细信息。这些属性信息被封装在 DriverPropertyInfo 对象数组中返回。每个 DriverPropertyInfo 对象包含了一个数据库连接属性的详细信息,比如属性名、属性值、描述等。 - **参数说明**: - - `url`:一个 String 类型的参数,表示数据库的 URL - - `info`:一个 java.util.Properties 类型的参数,包含了尝试连接时用户可能提供的属性列表 - - **返回值**:返回值类型为 `DriverPropertyInfo[]`,即 `DriverPropertyInfo` 对象的数组。每个 `DriverPropertyInfo` 对象包含了一个特定的数据库连接属性的详细信息 - - **异常**:如果在获取属性信息的过程中发生数据库访问错误或其他错误,将抛出 `SQLException` 异常 + - `url`:一个 String 类型的参数,表示数据库的 URL。 + - `info`:一个 java.util.Properties 类型的参数,包含了尝试连接时用户可能提供的属性列表。 + - **返回值**:返回值类型为 `DriverPropertyInfo[]`,即 `DriverPropertyInfo` 对象的数组。每个 `DriverPropertyInfo` 对象包含了一个特定的数据库连接属性的详细信息。 + - **异常**:如果在获取属性信息的过程中发生数据库访问错误或其他错误,将抛出 `SQLException` 异常。 - `int getMajorVersion()` - - **接口说明**:获取 JDBC 驱动程序的主版本号 + - **接口说明**:获取 JDBC 驱动程序的主版本号。 - `int getMinorVersion()` - - **接口说明**:获取 JDBC 驱动程序的次版本号 + - **接口说明**:获取 JDBC 驱动程序的次版本号。 ### 数据库元数据 `DatabaseMetaData` 是 JDBC API 的一部分,它提供了关于数据库的元数据的详细信息,元数据意味着关于数据库数据的数据。通过 `DatabaseMetaData` 接口,可以查询数据库服务器的详细信息,比如数据库产品名称、版本、已安装的功能、表、视图、存储过程的列表等。这对于了解和适应不同数据库的特性非常有用。 - `String getURL() throws SQLException` - - **接口说明**:获取用于连接数据库的 URL - - **返回值**:连接数据库的 URL - - **异常**:获取失败将抛出 `SQLException` 异常 + - **接口说明**:获取用于连接数据库的 URL。 + - **返回值**:连接数据库的 URL。 + - **异常**:获取失败将抛出 `SQLException` 异常。 - `String getUserName() throws SQLException` - - **接口说明**:获取用于连接获取数据库的用户名 - - **返回值**:连接数据库的用户名 - - **异常**:获取失败将抛出 `SQLException` 异常 + - **接口说明**:获取用于连接获取数据库的用户名。 + - **返回值**:连接数据库的用户名。 + - **异常**:获取失败将抛出 `SQLException` 异常。 - `String getDriverName() throws SQLException` - - **接口说明**:获取 JDBC 驱动程序的名称 - - **返回值**:驱动名称字符串 - - **异常**:获取失败将抛出 `SQLException` 异常 + - **接口说明**:获取 JDBC 驱动程序的名称。 + - **返回值**:驱动名称字符串。 + - **异常**:获取失败将抛出 `SQLException` 异常。 - `String getDriverVersion() throws SQLException` - - **接口说明**:获取 JDBC 驱动版本 - - **返回值**:驱动版本字符串 - - **异常**:获取失败将抛出 `SQLException` 异常 + - **接口说明**:获取 JDBC 驱动版本。 + - **返回值**:驱动版本字符串。 + - **异常**:获取失败将抛出 `SQLException` 异常。 - `int getDriverMajorVersion()` - - **接口说明**:获取 JDBC 驱动主版本号 + - **接口说明**:获取 JDBC 驱动主版本号。 - `int getDriverMinorVersion()` - - **接口说明**:获取 JDBC 驱动次版本号 + - **接口说明**:获取 JDBC 驱动次版本号。 - `String getDatabaseProductName() throws SQLException` - - **接口说明**:获取数据库产品的名称 + - **接口说明**:获取数据库产品的名称。 - `String getDatabaseProductVersion() throws SQLException` - - **接口说明**:获取数据库产品的版本号 + - **接口说明**:获取数据库产品的版本号。 - `String getIdentifierQuoteString() throws SQLException` - - **接口说明**:获取用于引用 SQL 标识符的字符串 + - **接口说明**:获取用于引用 SQL 标识符的字符串。 - `String getSQLKeywords() throws SQLException` - - **接口说明**:获取数据库特有的 SQL 关键字列表 + - **接口说明**:获取数据库特有的 SQL 关键字列表。 - `String getNumericFunctions() throws SQLException` - - **接口说明**:获取数据库支持的数值函数名称列表 + - **接口说明**:获取数据库支持的数值函数名称列表。 - `String getStringFunctions() throws SQLException` - - **接口说明**:获取数据库支持的字符串函数名称列表 + - **接口说明**:获取数据库支持的字符串函数名称列表。 - `String getSystemFunctions() throws SQLException` - - **接口说明**:获取数据库支持的系统函数名称列表 + - **接口说明**:获取数据库支持的系统函数名称列表。 - `String getTimeDateFunctions() throws SQLException` - - **接口说明**:获取数据库支持的时间日期函数名称列表 + - **接口说明**:获取数据库支持的时间日期函数名称列表。 - `String getCatalogTerm() throws SQLException` - - **接口说明**:获取数据库中目录的术语 + - **接口说明**:获取数据库中目录的术语。 - `String getCatalogSeparator() throws SQLException` - - **接口说明**:获取用于分隔目录和表名的分隔符 + - **接口说明**:获取用于分隔目录和表名的分隔符。 - `int getDefaultTransactionIsolation() throws SQLException` - - **接口说明**:获取数据库的默认事务隔离级别 + - **接口说明**:获取数据库的默认事务隔离级别。 - `boolean supportsTransactionIsolationLevel(int level) throws SQLException` - - **接口说明**:判断数据库是否支持给定的事务隔离级别 + - **接口说明**:判断数据库是否支持给定的事务隔离级别。 - **参数说明**: - - `level`:事务隔离级别 - - **返回值**:`true`:支持,`false`:不支持 - - **异常**:操作失败抛出 `SQLException` 异常 + - `level`:事务隔离级别。 + - **返回值**:`true`:支持,`false`:不支持。 + - **异常**:操作失败抛出 `SQLException` 异常。 - `ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types) throws SQLException` - - **接口说明**:获取数据库中匹配指定模式的表信息 + - **接口说明**:获取数据库中匹配指定模式的表信息。 - **参数说明**: - - `catalog`:目录名称;`null` 表示不指定目录 - - `schemaPattern`:模式名称的模式;null 表示不指定模式 - - `tableNamePattern`:表名称的模式 - - `types`:表类型列表,返回指定类型的表 - - **返回值**:包含表信息的 `ResultSet` - - **异常**:操作失败抛出 `SQLException` 异常 + - `catalog`:目录名称;`null` 表示不指定目录。 + - `schemaPattern`:模式名称的模式;null 表示不指定模式。 + - `tableNamePattern`:表名称的模式。 + - `types`:表类型列表,返回指定类型的表。 + - **返回值**:包含表信息的 `ResultSet`。 + - **异常**:操作失败抛出 `SQLException` 异常。 - `ResultSet getCatalogs() throws SQLException` - - **接口说明**:获取数据库中所有目录的信息 - - **返回值**:包含目录信息的 `ResultSet` - - **异常**:操作失败抛出 `SQLException` 异常 + - **接口说明**:获取数据库中所有目录的信息。 + - **返回值**:包含目录信息的 `ResultSet`。 + - **异常**:操作失败抛出 `SQLException` 异常。 - `ResultSet getTableTypes() throws SQLException` - - **接口说明**:获取数据库支持的表类型 - - **返回值**:包含表类型的 `ResultSet` - - **异常**:操作失败抛出 `SQLException` 异常 + - **接口说明**:获取数据库支持的表类型。 + - **返回值**:包含表类型的 `ResultSet`。 + - **异常**:操作失败抛出 `SQLException` 异常。 - `ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException` - - **接口说明**:获取指定表中匹配指定模式的列信息 + - **接口说明**:获取指定表中匹配指定模式的列信息。 - **参数说明**: - - `catalog`:目录名称;`null` 表示不指定目录 - - `schemaPattern`:模式名称的模式;`null` 表示不指定模式 - - `tableNamePattern`:表名称的模式 - - `columnNamePattern`:列名称的模式 - - **返回值**:包含列信息的 `ResultSet` - - **异常**:操作失败抛出 `SQLException` 异常 + - `catalog`:目录名称;`null` 表示不指定目录。 + - `schemaPattern`:模式名称的模式;`null` 表示不指定模式。 + - `tableNamePattern`:表名称的模式。 + - `columnNamePattern`:列名称的模式。 + - **返回值**:包含列信息的 `ResultSet`。 + - **异常**:操作失败抛出 `SQLException` 异常。 - `ResultSet getPrimaryKeys(String catalog, String schema, String table) throws SQLException` - - **接口说明**:获取指定表的主键信息 + - **接口说明**:获取指定表的主键信息。 - **参数说明**: - - `catalog`:目录名称;`null` 表示不指定目录 - - `schema`:模式名称;`null` 表示不指定模式 - - `table`:表名称 - - **返回值**:包含主键信息的 `ResultSet` - - **异常**:操作失败抛出 `SQLException` 异常 + - `catalog`:目录名称;`null` 表示不指定目录。 + - `schema`:模式名称;`null` 表示不指定模式。 + - `table`:表名称。 + - **返回值**:包含主键信息的 `ResultSet`。 + - **异常**:操作失败抛出 `SQLException` 异常。 - `Connection getConnection() throws SQLException` - **接口说明**:获取数据库连接。 @@ -615,7 +604,7 @@ JDBC 驱动支持创建连接,返回支持 JDBC 标准的 `Connection` 接口 注:下面 abstract 类型接口会被具体实现类实现,因此建立连接后得到连接对象可以直接调用。 -- `public abstract void write(String[] lines, SchemalessProtocolType protocolType, SchemalessTimestampType timestampType, Integer ttl, Long reqId) throws SQLException` +- `abstract void write(String[] lines, SchemalessProtocolType protocolType, SchemalessTimestampType timestampType, Integer ttl, Long reqId) throws SQLException` - **接口说明**:以指定的协议类型、时间戳类型、TTL(生存时间)和请求 ID 写入多行数据。 - **参数说明**: - `lines`:待写入的数据行数组。 @@ -624,28 +613,28 @@ JDBC 驱动支持创建连接,返回支持 JDBC 标准的 `Connection` 接口 - `ttl`:数据的生存时间,单位天。 - `reqId`:请求 ID。 - **异常**:操作失败抛出 SQLException 异常。 -- `public void write(String[] lines, SchemalessProtocolType protocolType, SchemalessTimestampType timestampType) throws SQLException` +- `void write(String[] lines, SchemalessProtocolType protocolType, SchemalessTimestampType timestampType) throws SQLException` - **接口说明**:以指定的协议类型和时间戳类型写入多行数据。 - **参数说明**: - `lines`:待写入的数据行数组。 - `protocolType`:协议类型:支持 LINE, TELNET, JSON 三种。 - `timestampType`:时间戳类型,支持 HOURS,MINUTES,SECONDS,MILLI_SECONDS,MICRO_SECONDS 和 NANO_SECONDS。 - **异常**:操作失败抛出 SQLException 异常。 -- `public void write(String line, SchemalessProtocolType protocolType, SchemalessTimestampType timestampType) throws SQLException` +- `void write(String line, SchemalessProtocolType protocolType, SchemalessTimestampType timestampType) throws SQLException` - **接口说明**:以指定的协议类型和时间戳类型写入单行数据。 - **参数说明**: - `line`:待写入的数据行。 - `protocolType`:协议类型:支持 LINE, TELNET, JSON 三种。 - `timestampType`:时间戳类型,支持 HOURS,MINUTES,SECONDS,MILLI_SECONDS,MICRO_SECONDS 和 NANO_SECONDS。 - **异常**:操作失败抛出 SQLException 异常。 -- `public void write(List lines, SchemalessProtocolType protocolType, SchemalessTimestampType timestampType) throws SQLException` +- `void write(List lines, SchemalessProtocolType protocolType, SchemalessTimestampType timestampType) throws SQLException` - **接口说明**:以指定的协议类型和时间戳类型写入多行数据(使用列表)。 - **参数说明**: - `lines`:待写入的数据行列表。 - `protocolType`:协议类型:支持 LINE, TELNET, JSON 三种。 - `timestampType`:时间戳类型,支持 HOURS,MINUTES,SECONDS,MILLI_SECONDS,MICRO_SECONDS 和 NANO_SECONDS。 - **异常**:操作失败抛出 SQLException 异常。 -- `public int writeRaw(String line, SchemalessProtocolType protocolType, SchemalessTimestampType timestampType) throws SQLException` +- `int writeRaw(String line, SchemalessProtocolType protocolType, SchemalessTimestampType timestampType) throws SQLException` - **接口说明**:以指定的协议类型和时间戳类型写入多行回车符分割的原始数据,回车符分割,并返回操作结果。 - **参数说明**: - `line`:待写入的原始数据。 @@ -653,7 +642,7 @@ JDBC 驱动支持创建连接,返回支持 JDBC 标准的 `Connection` 接口 - `timestampType`:时间戳类型,支持 HOURS,MINUTES,SECONDS,MILLI_SECONDS,MICRO_SECONDS 和 NANO_SECONDS。 - **返回值**:操作结果。 - **异常**:操作失败抛出 SQLException 异常。 -- `public abstract int writeRaw(String line, SchemalessProtocolType protocolType, SchemalessTimestampType timestampType, Integer ttl, Long reqId) throws SQLException` +- `abstract int writeRaw(String line, SchemalessProtocolType protocolType, SchemalessTimestampType timestampType, Integer ttl, Long reqId) throws SQLException` - **接口说明**:以指定的协议类型、时间戳类型、TTL(生存时间)和请求 ID 写入多行回车符分割的原始数据,并返回操作结果。 - **参数说明**: - `line`:待写入的原始数据。 @@ -1270,35 +1259,35 @@ ParameterMetaData 提供了参数元数据接口: #### 扩展接口 -- `public void setTableName(String name) throws SQLException` +- `void setTableName(String name) throws SQLException` - **接口说明**:设置当前操作的表名。 - **参数说明**: - `name`:一个 String 类型的参数,表示要绑定的表名。 -- `public void setTagNull(int index, int type)` +- `void setTagNull(int index, int type)` - **接口说明**:为指定索引的标签设置 null 值。 - **参数说明**: - `index`:标签的索引位置。 - `type`:标签的数据类型。 -- `public void setTagBoolean(int index, boolean value)` +- `void setTagBoolean(int index, boolean value)` - **接口说明**:为指定索引的标签设置布尔值。 - **参数说明**: - `index`:标签的索引位置。 - `value`:要设置的布尔值。 - 下面接口除了要设置的值类型不同外,其余同 setTagBoolean,不再赘述: - - `public void setTagInt(int index, int value)` - - `public void setTagByte(int index, byte value)` - - `public void setTagShort(int index, short value)` - - `public void setTagLong(int index, long value)` - - `public void setTagTimestamp(int index, long value)` - - `public void setTagFloat(int index, float value)` - - `public void setTagDouble(int index, double value)` - - `public void setTagString(int index, String value)` - - `public void setTagNString(int index, String value)` - - `public void setTagJson(int index, String value)` - - `public void setTagVarbinary(int index, byte[] value)` - - `public void setTagGeometry(int index, byte[] value)` + - `void setTagInt(int index, int value)` + - `void setTagByte(int index, byte value)` + - `void setTagShort(int index, short value)` + - `void setTagLong(int index, long value)` + - `void setTagTimestamp(int index, long value)` + - `void setTagFloat(int index, float value)` + - `void setTagDouble(int index, double value)` + - `void setTagString(int index, String value)` + - `void setTagNString(int index, String value)` + - `void setTagJson(int index, String value)` + - `void setTagVarbinary(int index, byte[] value)` + - `void setTagGeometry(int index, byte[] value)` -- `public void setInt(int columnIndex, ArrayList list) throws SQLException` +- `void setInt(int columnIndex, ArrayList list) throws SQLException` - **接口说明**:为指定列索引设置批量整型值。 - **参数说明**: - `columnIndex`:列的索引位置。 @@ -1306,14 +1295,14 @@ ParameterMetaData 提供了参数元数据接口: - **异常**: - 如果操作过程中发生错误,将抛出 SQLException 异常。 - 下面接口除了要设置的值类型不同外,其余同 setInt: - - `public void setFloat(int columnIndex, ArrayList list) throws SQLException` - - `public void setTimestamp(int columnIndex, ArrayList list) throws SQLException` - - `public void setLong(int columnIndex, ArrayList list) throws SQLException` - - `public void setDouble(int columnIndex, ArrayList list) throws SQLException` - - `public void setBoolean(int columnIndex, ArrayList list) throws SQLException` - - `public void setByte(int columnIndex, ArrayList list) throws SQLException` - - `public void setShort(int columnIndex, ArrayList list) throws SQLException` -- `public void setString(int columnIndex, ArrayList list, int size) throws SQLException` + - `void setFloat(int columnIndex, ArrayList list) throws SQLException` + - `void setTimestamp(int columnIndex, ArrayList list) throws SQLException` + - `void setLong(int columnIndex, ArrayList list) throws SQLException` + - `void setDouble(int columnIndex, ArrayList list) throws SQLException` + - `void setBoolean(int columnIndex, ArrayList list) throws SQLException` + - `void setByte(int columnIndex, ArrayList list) throws SQLException` + - `void setShort(int columnIndex, ArrayList list) throws SQLException` +- `void setString(int columnIndex, ArrayList list, int size) throws SQLException` - **接口说明**:为指定列索引设置字符串值列表。 - **参数说明**: - `columnIndex`:列的索引位置。 @@ -1322,9 +1311,9 @@ ParameterMetaData 提供了参数元数据接口: - **异常**: - 如果操作过程中发生错误,将抛出 SQLException 异常。 - 下面接口除了要设置的值类型不同外,其余同 setString: - - `public void setVarbinary(int columnIndex, ArrayList list, int size) throws SQLException` - - `public void setGeometry(int columnIndex, ArrayList list, int size) throws SQLException` - - `public void setNString(int columnIndex, ArrayList list, int size) throws SQLException` + - `void setVarbinary(int columnIndex, ArrayList list, int size) throws SQLException` + - `void setGeometry(int columnIndex, ArrayList list, int size) throws SQLException` + - `void setNString(int columnIndex, ArrayList list, int size) throws SQLException` - `void columnDataAddBatch() throws SQLException` - **接口说明**:将 `setInt(int columnIndex, ArrayList list)` 等数组形式接口设置的数据添加到当前 PrepareStatement 对象的批处理中。 - **异常**: @@ -1348,97 +1337,93 @@ JDBC 标准不支持数据订阅,因此本章所有接口都是扩展接口。 - **异常**:如果创建失败,抛出 SQLException 异常。 创建消费者支持属性列表: +- td.connect.type: 连接方式。jni:表示使用动态库连接的方式,ws/WebSocket:表示使用 WebSocket 进行数据通信。默认为 jni 方式。 +- bootstrap.servers: TDengine 服务端所在的`ip:port`,如果使用 WebSocket 连接,则为 taosAdapter 所在的`ip:port`。 +- enable.auto.commit: 是否允许自动提交。 +- group.id: consumer: 所在的 group。 +- value.deserializer: 结果集反序列化方法,可以继承 `com.taosdata.jdbc.tmq.ReferenceDeserializer`,并指定结果集 bean,实现反序列化。也可以继承 `com.taosdata.jdbc.tmq.Deserializer`,根据 SQL 的 resultSet 自定义反序列化方式。 +- httpConnectTimeout: 创建连接超时参数,单位 ms,默认为 5000 ms。仅在 WebSocket 连接下有效。 +- messageWaitTimeout: 数据传输超时参数,单位 ms,默认为 10000 ms。仅在 WebSocket 连接下有效。 +- httpPoolSize: 同一个连接下最大并行请求数。仅在 WebSocket 连接下有效。 +- TSDBDriver.PROPERTY_KEY_ENABLE_COMPRESSION: 传输过程是否启用压缩。仅在使用 Websocket 连接时生效。true: 启用,false: 不启用。默认为 false。 +- TSDBDriver.PROPERTY_KEY_ENABLE_AUTO_RECONNECT: 是否启用自动重连。仅在使用 Websocket 连接时生效。true: 启用,false: 不启用。默认为 false。 +- TSDBDriver.PROPERTY_KEY_RECONNECT_INTERVAL_MS: 自动重连重试间隔,单位毫秒,默认值 2000。仅在 PROPERTY_KEY_ENABLE_AUTO_RECONNECT 为 true 时生效。 +- TSDBDriver.PROPERTY_KEY_RECONNECT_RETRY_COUNT: 自动重连重试次数,默认值 3,仅在 PROPERTY_KEY_ENABLE_AUTO_RECONNECT 为 true 时生效。 - -| 属性 | 描述 | 默认值 | -| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | -| td.connect.type | 连接方式。jni:表示使用动态库连接的方式,ws/WebSocket:表示使用 WebSocket 进行数据通信。 | jni | -| bootstrap.servers | TDengine 服务端所在的ip:port,如果使用 WebSocket 连接,则为 taosAdapter 所在的ip:port。 | | -| enable.auto.commit | 是否允许自动提交。 | | -| group.id | consumer 所在的 group。 | | -| value.deserializer | 结果集反序列化方法。可以继承 com.taosdata.jdbc.tmq.ReferenceDeserializer,并指定结果集 bean,实现反序列化。也可以继承 com.taosdata.jdbc.tmq.Deserializer,根据 SQL 的 resultSet 自定义反序列化方式。 | | -| httpConnectTimeout | 创建连接超时参数,单位 ms。仅在 WebSocket 连接下有效。 | 5000 ms | -| messageWaitTimeout | 数据传输超时参数,单位 ms。仅在 WebSocket 连接下有效。 | 10000 ms | -| httpPoolSize | 同一个连接下最大并行请求数。仅在 WebSocket 连接下有效。 | | -| enableCompression | 传输过程是否启用压缩。仅在使用 Websocket 连接时生效。true: 启用,false: 不启用。 | false | -| enableAutoReconnect | 是否启用自动重连。仅在使用 Websocket 连接时生效。true: 启用,false: 不启用。 | false | -| reconnectIntervalMs | 自动重连重试间隔,单位毫秒。仅在 enableCompression 为 true 时生效。 | 2000 ms | -| reconnectRetryCount | 自动重连重试次数。仅在 enableCompression 为 true 时生效。 | 3 | - 其他参数请参考:[Consumer 参数列表](../../../develop/tmq/#创建参数), 注意TDengine服务端自 3.2.0.0 版本开始消息订阅中的 auto.offset.reset 默认值发生变化。 -- `public void subscribe(Collection topics) throws SQLException` +- `void subscribe(Collection topics) throws SQLException` - **接口说明**:订阅一组主题。 - **参数说明**: - `topics`:一个 `Collection` 类型的参数,表示要订阅的主题列表。 - **异常**:如果在订阅过程中发生错误,将抛出 SQLException 异常。 -- `public void unsubscribe() throws SQLException` +- `void unsubscribe() throws SQLException` - **接口说明**:取消订阅所有主题。 - **异常**:如果在取消订阅过程中发生错误,将抛出 SQLException 异常。 -- `public Set subscription() throws SQLException` +- `Set subscription() throws SQLException` - **接口说明**:获取当前订阅的所有主题。 - **返回值**:返回值类型为 `Set`,即当前订阅的所有主题集合。 - **异常**:如果在获取订阅信息过程中发生错误,将抛出 SQLException 异常。 -- `public ConsumerRecords poll(Duration timeout) throws SQLException` +- `ConsumerRecords poll(Duration timeout) throws SQLException` - **接口说明**:轮询消息。 - **参数说明**: - `timeout`:一个 `Duration` 类型的参数,表示轮询的超时时间。 - **返回值**:返回值类型为 `ConsumerRecords`,即轮询到的消息记录。 - **异常**:如果在轮询过程中发生错误,将抛出 SQLException 异常。 -- `public void commitAsync() throws SQLException` +- `void commitAsync() throws SQLException` - **接口说明**:异步提交当前处理的消息的偏移量。 - **异常**:如果在提交过程中发生错误,将抛出 SQLException 异常。 -- `public void commitSync() throws SQLException` +- `void commitSync() throws SQLException` - **接口说明**:同步提交当前处理的消息的偏移量。 - **异常**:如果在提交过程中发生错误,将抛出 SQLException 异常。 -- `public void close() throws SQLException` +- `void close() throws SQLException` - **接口说明**:关闭消费者,释放资源。 - **异常**:如果在关闭过程中发生错误,将抛出 SQLException 异常。 -- `public void seek(TopicPartition partition, long offset) throws SQLException` +- `void seek(TopicPartition partition, long offset) throws SQLException` - **接口说明**:将给定分区的偏移量设置到指定的位置。 - **参数说明**: - `partition`:一个 `TopicPartition` 类型的参数,表示要操作的分区。 - `offset`:一个 `long` 类型的参数,表示要设置的偏移量。 - **异常**:如果在设置偏移量过程中发生错误,将抛出 SQLException 异常。 -- `public long position(TopicPartition tp) throws SQLException` +- `long position(TopicPartition tp) throws SQLException` - **接口说明**:获取给定分区当前的偏移量。 - **参数说明**: - `tp`:一个 `TopicPartition` 类型的参数,表示要查询的分区。 - **返回值**:返回值类型为 `long`,即给定分区当前的偏移量。 - **异常**:如果在获取偏移量过程中发生错误,将抛出 SQLException 异常。 -- `public Map beginningOffsets(String topic) throws SQLException` +- `Map beginningOffsets(String topic) throws SQLException` - **接口说明**:获取指定主题的每个分区的最早偏移量。 - **参数说明**: - `topic`:一个 `String` 类型的参数,表示要查询的主题。 - **返回值**:返回值类型为 `Map`,即指定主题的每个分区的最早偏移量。 - **异常**:如果在获取最早偏移量过程中发生错误,将抛出 SQLException 异常。 -- `public Map endOffsets(String topic) throws SQLException` +- `Map endOffsets(String topic) throws SQLException` - **接口说明**:获取指定主题的每个分区的最新偏移量。 - **参数说明**: - `topic`:一个 `String` 类型的参数,表示要查询的主题。 - **返回值**:返回值类型为 `Map`,即指定主题的每个分区的最新偏移量。 - **异常**:如果在获取最新偏移量过程中发生错误,将抛出 SQLException 异常。 -- `public void seekToBeginning(Collection partitions) throws SQLException` +- `void seekToBeginning(Collection partitions) throws SQLException` - **接口说明**:将一组分区的偏移量设置到最早的偏移量。 - **参数说明**: - `partitions`:一个 `Collection` 类型的参数,表示要操作的分区集合。 - **异常**:如果在设置偏移量过程中发生错误,将抛出 SQLException 异常。 -- `public void seekToEnd(Collection partitions) throws SQLException` +- `void seekToEnd(Collection partitions) throws SQLException` - **接口说明**:将一组分区的偏移量设置到最新的偏移量。 - **参数说明**: - `partitions`:一个 `Collection` 类型的参数,表示要操作的分区集合。 - **异常**:如果在设置偏移量过程中发生错误,将抛出 SQLException 异常。 -- `public Set assignment() throws SQLException` +- `Set assignment() throws SQLException` - **接口说明**:获取消费者当前分配的所有分区。 - **返回值**:返回值类型为 `Set`,即消费者当前分配的所有分区。 - **异常**:如果在获取分配的分区过程中发生错误,将抛出 SQLException 异常。 -- `public OffsetAndMetadata committed(TopicPartition partition) throws SQLException` +- `OffsetAndMetadata committed(TopicPartition partition) throws SQLException` - **接口说明**:获取指定分区最后提交的偏移量。 - **参数说明**: - `partition`:一个 `TopicPartition` 类型的参数,表示要查询的分区。 - **返回值**:返回值类型为 `OffsetAndMetadata`,即指定分区最后提交的偏移量。 - **异常**:如果在获取提交的偏移量过程中发生错误,将抛出 SQLException 异常。 -- `public Map committed(Set partitions) throws SQLException` +- `Map committed(Set partitions) throws SQLException` - **接口说明**:获取一组分区最后提交的偏移量。 - **参数说明**: - `partitions`:一个 `Set` 类型的参数,表示要查询的分区集合。 @@ -1451,19 +1436,19 @@ ConsumerRecords 类提供了消费记录信息,可以迭代 ConsumerRecord 对 ConsumerRecord 提供的接口: -- `public String getTopic()` +- `String getTopic()` - **接口说明**:获取消息的主题。 - **返回值**:返回值类型为 `String`,即消息的主题。 -- `public String getDbName()` +- `String getDbName()` - **接口说明**:获取数据库名称。 - **返回值**:返回值类型为 `String`,即数据库名称。 -- `public int getVGroupId()` +- `int getVGroupId()` - **接口说明**:获取虚拟组 ID。 - **返回值**:返回值类型为 `int`,即虚拟组 ID。 -- `public V value()` +- `V value()` - **接口说明**:获取消息的值。 - **返回值**:返回值类型为 `V`,即消息的值。 -- `public long getOffset()` +- `long getOffset()` - **接口说明**:获取消息的偏移量。 - **返回值**:返回值类型为 `long`,即消息的偏移量。 @@ -1471,15 +1456,15 @@ ConsumerRecord 提供的接口: TopicPartition 类提供了分区信息,包含消息主题和虚拟组 ID。 -- `public TopicPartition(String topic, int vGroupId)` +- `TopicPartition(String topic, int vGroupId)` - **接口说明**:构造一个新的 TopicPartition 实例,用于表示一个特定的主题和虚拟组 ID。 - **参数说明**: - `topic`:一个 `String` 类型的参数,表示消息的主题。 - `vGroupId`:一个 `int` 类型的参数,表示虚拟组 ID。 -- `public String getTopic()` +- `String getTopic()` - **接口说明**:获取此 TopicPartition 实例的主题。 - **返回值**:返回值类型为 `String`,即此 TopicPartition 实例的主题。 -- `public int getVGroupId()` +- `int getVGroupId()` - **接口说明**:获取此 TopicPartition 实例的虚拟组 ID。 - **返回值**:返回值类型为 `int`,即此 TopicPartition 实例的虚拟组 ID。 @@ -1487,10 +1472,10 @@ TopicPartition 类提供了分区信息,包含消息主题和虚拟组 ID。 OffsetAndMetadata 类提供了偏移量元数据信息。 -- `public long offset()` +- `long offset()` - **接口说明**:获取此 OffsetAndMetadata 实例中的偏移量。 - **返回值**:返回值类型为 `long`,即此 OffsetAndMetadata 实例中的偏移量。 -- `public String metadata()` +- `String metadata()` - **接口说明**:获取此 OffsetAndMetadata 实例中的元数据。 - **返回值**:返回值类型为 `String`,即此 OffsetAndMetadata 实例中的元数据。 diff --git a/docs/zh/14-reference/05-connector/20-go.mdx b/docs/zh/14-reference/05-connector/20-go.mdx index 0c3dfa6681..c53f681f06 100644 --- a/docs/zh/14-reference/05-connector/20-go.mdx +++ b/docs/zh/14-reference/05-connector/20-go.mdx @@ -1065,7 +1065,7 @@ type ConfigMap map[string]ConfigValue - `ws.reconnectIntervalMs`:WebSocket 重连间隔时间毫秒,默认 2000。 - `ws.reconnectRetryCount`:WebSocket 重连重试次数,默认 3。 -其他参数请参考:[Consumer 参数列表](../../develop/tmq/#数据订阅相关参数), 注意TDengine服务端自 3.2.0.0 版本开始消息订阅中的 auto.offset.reset 默认值发生变化。 +其他参数请参考:[Consumer 参数列表](../../../develop/tmq/#数据订阅相关参数), 注意TDengine服务端自 3.2.0.0 版本开始消息订阅中的 auto.offset.reset 默认值发生变化。 - `func (c *Consumer) Subscribe(topic string, rebalanceCb RebalanceCb) error` - **接口说明**:订阅主题。 diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsWsConsumerLoop.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsWsConsumerLoop.java index 690c05841c..60466629f6 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsWsConsumerLoop.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsWsConsumerLoop.java @@ -30,8 +30,8 @@ config.setProperty("auto.offset.reset", "latest"); config.setProperty("msg.with.table.name", "true"); config.setProperty("enable.auto.commit", "true"); config.setProperty("auto.commit.interval.ms", "1000"); -config.setProperty("group.id", "group2"); -config.setProperty("client.id", "1"); +config.setProperty("group.id", "group1"); +config.setProperty("client.id", "client1"); config.setProperty("value.deserializer", "com.taosdata.example.AbsConsumerLoopWs$ResultDeserializer"); config.setProperty("value.deserializer.encoding", "UTF-8"); From 78d4c6a13f29b7836fd054ff0a7fecdfcd51f414 Mon Sep 17 00:00:00 2001 From: menshibin Date: Thu, 1 Aug 2024 16:02:20 +0800 Subject: [PATCH 09/14] add nodejs interface --- .../14-reference/05-connector/30-python.mdx | 949 ++++++++---------- docs/zh/14-reference/05-connector/35-node.mdx | 276 +---- 2 files changed, 472 insertions(+), 753 deletions(-) diff --git a/docs/zh/14-reference/05-connector/30-python.mdx b/docs/zh/14-reference/05-connector/30-python.mdx index 366b85af4b..7f5897c021 100644 --- a/docs/zh/14-reference/05-connector/30-python.mdx +++ b/docs/zh/14-reference/05-connector/30-python.mdx @@ -99,507 +99,9 @@ TDengine 目前支持时间戳、数字、字符、布尔类型,与 Python 对 |NCHAR|str| |JSON|str| -## 安装步骤 +## 示例程序汇总 -### 安装前准备 - -1. 安装 Python。新近版本 taospy 包要求 Python 3.6.2+。早期版本 taospy 包要求 Python 3.7+。taos-ws-py 包要求 Python 3.7+。如果系统上还没有 Python 可参考 [Python BeginnersGuide](https://wiki.python.org/moin/BeginnersGuide/Download) 安装。 -2. 安装 [pip](https://pypi.org/project/pip/)。大部分情况下 Python 的安装包都自带了 pip 工具, 如果没有请参考 [pip documentation](https://pip.pypa.io/en/stable/installation/) 安装。 -3. 如果使用原生连接,还需[安装客户端驱动](../#安装客户端驱动)。客户端软件包含了 TDengine 客户端动态链接库(libtaos.so 或 taos.dll) 和 TDengine CLI。 - -### 使用 pip 安装 - -#### 卸载旧版本 - -如果以前安装过旧版本的 Python 连接器, 请提前卸载。 - -``` -pip3 uninstall taos taospy -``` - -:::note -较早的 TDengine 客户端软件包含了 Python 连接器。如果从客户端软件的安装目录安装了 Python 连接器,那么对应的 Python 包名是 `taos`。 所以上述卸载命令包含了 `taos`, 不存在也没关系。 - -::: - -#### 安装 `taospy` - - - - -安装最新版本 - -``` -pip3 install taospy -``` - -也可以指定某个特定版本安装。 - -``` -pip3 install taospy==2.3.0 -``` - - - - -``` -pip3 install git+https://github.com/taosdata/taos-connector-python.git -``` - - - - -#### 安装 `taos-ws-py`(可选) - -taos-ws-py 包提供了通过 WebSocket 连接 TDengine 的能力,可选安装 taos-ws-py 以获得 WebSocket 连接 TDengine 的能力。 - - -##### 和 taospy 同时安装 - -```bash -pip3 install taospy[ws] -``` - -##### 单独安装 - -```bash -pip3 install taos-ws-py -``` - -### 安装验证 - - - - -对于原生连接,需要验证客户端驱动和 Python 连接器本身是否都正确安装。如果能成功导入 `taos` 模块,则说明已经正确安装了客户端驱动和 Python 连接器。可在 Python 交互式 Shell 中输入: - -```python -import taos -``` - - - - -对于 REST 连接,只需验证是否能成功导入 `taosrest` 模块。可在 Python 交互式 Shell 中输入: - -```python -import taosrest -``` - - - - -对于 WebSocket 连接,只需验证是否能成功导入 `taosws` 模块。可在 Python 交互式 Shell 中输入: - -```python -import taosws -``` - - - - -:::tip -如果系统上有多个版本的 Python,则可能有多个 `pip` 命令。要确保使用的 `pip` 命令路径是正确的。上面我们用 `pip3` 命令安装,排除了使用 Python 2.x 版本对应的 `pip` 的可能性。但是如果系统上有多个 Python 3.x 版本,仍需检查安装路径是否正确。最简单的验证方式是,在命令再次输入 `pip3 install taospy`, 就会打印出 `taospy` 的具体安装位置,比如在 Windows 上: - -``` -C:\> pip3 install taospy -Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple -Requirement already satisfied: taospy in c:\users\username\appdata\local\programs\python\python310\lib\site-packages (2.3.0) -``` - -::: - -## 建立连接 - -### 连通性测试 - -在用连接器建立连接之前,建议先测试本地 TDengine CLI 到 TDengine 集群的连通性。 - - - - -请确保 TDengine 集群已经启动, 且集群中机器的 FQDN (如果启动的是单机版,FQDN 默认为 hostname)在本机能够解析, 可用 `ping` 命令进行测试: - -``` -ping -``` - -然后测试用 TDengine CLI 能否正常连接集群: - -``` -taos -h -p -``` - -上面的 FQDN 可以为集群中任意一个 dnode 的 FQDN, PORT 为这个 dnode 对应的 serverPort。 - - - - -对于 REST 连接, 除了确保集群已经启动,还要确保 taosAdapter 组件已经启动。可以使用如下 curl 命令测试: - -``` -curl -u root:taosdata http://:/rest/sql -d "select server_version()" -``` - -上面的 FQDN 为运行 taosAdapter 的机器的 FQDN, PORT 为 taosAdapter 配置的监听端口, 默认为 6041。 -如果测试成功,会输出服务器版本信息,比如: - -```json -{ - "code": 0, - "column_meta": [ - [ - "server_version()", - "VARCHAR", - 7 - ] - ], - "data": [ - [ - "3.0.0.0" - ] - ], - "rows": 1 -} -``` - - - - -对于 WebSocket 连接, 除了确保集群已经启动,还要确保 taosAdapter 组件已经启动。可以使用如下 curl 命令测试: - -``` -curl -i -N -d "show databases" -H "Authorization: Basic cm9vdDp0YW9zZGF0YQ==" -H "Connection: Upgrade" -H "Upgrade: websocket" -H "Host: :" -H "Origin: http://:" http://:/rest/sql -``` - -上面的 FQDN 为运行 taosAdapter 的机器的 FQDN, PORT 为 taosAdapter 配置的监听端口, 默认为 6041。 -如果测试成功,会输出服务器版本信息,比如: - -```json -HTTP/1.1 200 OK -Content-Type: application/json; charset=utf-8 -Date: Tue, 21 Mar 2023 09:29:17 GMT -Transfer-Encoding: chunked - -{"status":"succ","head":["server_version()"],"column_meta":[["server_version()",8,8]],"data":[["2.6.0.27"]],"rows":1} -``` - - - - -### 指定 Host 和 Properties 获取连接 - -以下示例代码假设 TDengine 安装在本机, 且 FQDN 和 serverPort 都使用了默认配置。 - - - - -```python -{{#include docs/examples/python/connect_native_reference.py}} -``` - -`connect` 函数的所有参数都是可选的关键字参数。下面是连接参数的具体说明: - -- `host` : 要连接的节点的 FQDN。 没有默认值。如果不同提供此参数,则会连接客户端配置文件中的 firstEP。 -- `user` :TDengine 用户名。 默认值是 root。 -- `password` : TDengine 用户密码。 默认值是 taosdata。 -- `port` : 要连接的数据节点的起始端口,即 serverPort 配置。默认值是 6030。只有在提供了 host 参数的时候,这个参数才生效。 -- `config` : 客户端配置文件路径。 在 Windows 系统上默认是 `C:\TDengine\cfg`。 在 Linux/macOS 系统上默认是 `/etc/taos/`。 -- `timezone` : 查询结果中 TIMESTAMP 类型的数据,转换为 python 的 datetime 对象时使用的时区。默认为本地时区。 - -:::warning -`config` 和 `timezone` 都是进程级别的配置。建议一个进程建立的所有连接都使用相同的参数值。否则可能产生无法预知的错误。 -::: - -:::tip -`connect` 函数返回 `taos.TaosConnection` 实例。 在客户端多线程的场景下,推荐每个线程申请一个独立的连接实例,而不建议多线程共享一个连接。 - -::: - - - - -```python -{{#include docs/examples/python/connect_rest_examples.py:connect}} -``` - -`connect()` 函数的所有参数都是可选的关键字参数。下面是连接参数的具体说明: - -- `url`: taosAdapter REST 服务的 URL。默认是 \。 -- `user`: TDengine 用户名。默认是 root。 -- `password`: TDengine 用户密码。默认是 taosdata。 -- `timeout`: HTTP 请求超时时间。单位为秒。默认为 `socket._GLOBAL_DEFAULT_TIMEOUT`。 一般无需配置。 - - - - - -```python -{{#include docs/examples/python/connect_websocket_examples.py:connect}} -``` - -`connect()` 函数参数为连接 url,协议为 `taosws` 或 `ws` - - - - -### 配置参数的优先级 - -如果配置参数在参数和客户端配置文件中有重复,则参数的优先级由高到低分别如下: - -1. 连接参数 -2. 使用原生连接时,TDengine 客户端驱动的配置文件 taos.cfg - -## 使用示例 - -### 创建数据库和表 - - - - -```python -{{#include docs/examples/python/create_db_native.py}} -``` - - - - - -```python -{{#include docs/examples/python/create_db_rest.py}} -``` - - - - - -```python -{{#include docs/examples/python/create_db_ws.py}} -``` - - - - -### 插入数据 - - - - -```python -{{#include docs/examples/python/insert_native.py:insert}} -``` - - - - - -```python -{{#include docs/examples/python/insert_rest.py:insert}} -``` - - - - - -```python -{{#include docs/examples/python/insert_ws.py:insert}} -``` - - - - -> NOW 为系统内部函数,默认为客户端所在计算机当前时间。 -> `NOW + 1s` 代表客户端当前时间往后加 1 秒,数字后面代表时间单位:a(毫秒),s(秒),m(分),h(小时),d(天),w(周),n(月),y(年)。 - -### 查询数据 - - - - -`TaosConnection` 类的 `query` 方法可以用来查询数据,返回 `TaosResult` 类型的结果数据。 - -```python -{{#include docs/examples/python/insert_native.py:query}} -``` - -:::tip -查询结果只能获取一次。比如上面的示例中 `fetch_all()` 和 `fetch_all_into_dict()` 只能用一个。重复获取得到的结果为空列表。 -::: - - - - - -RestClient 类是对于 REST API 的直接封装。它只包含一个 sql() 方法用于执行任意 SQL 语句, 并返回执行结果。 - -```python -{{#include docs/examples/python/insert_rest.py:query}} -``` - -对于 `sql()` 方法更详细的介绍, 请参考 [RestClient](https://docs.taosdata.com/api/taospy/taosrest/restclient.html)。 - - - - - -`TaosConnection` 类的 `query` 方法可以用来查询数据,返回 `TaosResult` 类型的结果数据。 - -```python -{{#include docs/examples/python/insert_ws.py:query}} -``` - - - - -### 执行带有 reqId 的 SQL - - - - - - -类似上文介绍的使用方法,增加 `req_id` 参数。 - -```python -{{#include docs/examples/python/insert_native.py:req_id}} -``` - - - - -类似上文介绍的使用方法,增加 `req_id` 参数。 - -```python -{{#include docs/examples/python/insert_rest.py:req_id}} -``` - - - - - -类似上文介绍的使用方法,增加 `req_id` 参数。 - -```python -{{#include docs/examples/python/insert_ws.py:req_id}} -``` - - - - -### 通过参数绑定写入数据 - -TDengine 的 Python 连接器支持参数绑定风格的 Prepare API 方式写入数据,和大多数数据库类似,目前仅支持用 `?` 来代表待绑定的参数。 - - - - -```python -{{#include docs/examples/python/stmt_native.py:stmt}} -``` - - - - -```python -{{#include docs/examples/python/stmt_ws.py:stmt}} -``` - - - -### 无模式写入 - -连接器支持无模式写入功能。 - - - - -```python -{{#include docs/examples/python/schemaless_native.py}} -``` - - - - - -```python -{{#include docs/examples/python/schemaless_ws.py}} -``` - - - - -### 执行带有 reqId 的无模式写入 - -连接器的 `schemaless_insert` 和 `schemaless_insert_raw` 方法支持 `req_id` 可选参数,此 `req_id` 可用于请求链路追踪。 - -```python -conn.schemaless_insert( - lines=lineDemo, - protocol=taos.SmlProtocol.LINE_PROTOCOL, - precision=taos.SmlPrecision.NANO_SECONDS, - req_id=1, -) -``` - -### 数据订阅 - -连接器支持数据订阅功能,数据订阅功能请参考 [数据订阅文档](../../develop/tmq/)。 - -#### 创建 Topic - -```python -{{#include docs/examples/python/tmq_native.py:create_topic}} -``` - -#### 创建 Consumer - -```python -{{#include docs/examples/python/tmq_native.py:create_consumer}} -``` - -#### 订阅 topics - -```python -{{#include docs/examples/python/tmq_native.py:subscribe}} -``` - -#### 消费数据 - -```python -{{#include docs/examples/python/tmq_native.py:consume}} -``` - -#### 获取消费进度 - -Consumer API 的 `assignment` 方法用于获取 Consumer 订阅的所有 topic 的消费进度,返回结果类型为 TopicPartition 列表。 - -```python -{{#include docs/examples/python/tmq_native.py:assignment}} -``` - -Consumer API 的 `seek` 方法用于重置 Consumer 的消费进度到指定位置,方法参数类型为 TopicPartition。 - -```python -{{#include docs/examples/python/tmq_native.py:consume}} -``` - -#### 关闭订阅 - -消费结束后,应当取消订阅,并关闭 Consumer。 - -```python -{{#include docs/examples/python/tmq_native.py:unsubscribe}} -``` - -#### 完整示例 - -```python -{{#include docs/examples/python/tmq_native.py}} -``` - -### 更多示例程序 - -| 示例程序链接 | 示例程序内容 | +| 示例程序链接 | 示例程序内容 | | ------------------------------------------------------------------------------------------------------------- | ----------------------- | | [bind_multi.py](https://github.com/taosdata/taos-connector-python/blob/main/examples/bind-multi.py) | 参数绑定, 一次绑定多行 | | [bind_row.py](https://github.com/taosdata/taos-connector-python/blob/main/examples/bind-row.py) | 参数绑定,一次绑定一行 | @@ -607,19 +109,13 @@ Consumer API 的 `seek` 方法用于重置 Consumer 的消费进度到指定位 | [json_tag.py](https://github.com/taosdata/taos-connector-python/blob/main/examples/json-tag.py) | 使用 JSON 类型的标签 | | [tmq_consumer.py](https://github.com/taosdata/taos-connector-python/blob/main/examples/tmq_consumer.py) | tmq 订阅 | -## 其它说明 - -### 关于纳秒 (nanosecond) +## 关于纳秒 (nanosecond) 由于目前 Python 对 nanosecond 支持的不完善(见下面的链接),目前的实现方式是在 nanosecond 精度时返回整数,而不是 ms 和 us 返回的 datetime 类型,应用开发者需要自行处理,建议使用 pandas 的 to_datetime()。未来如果 Python 正式完整支持了纳秒,Python 连接器可能会修改相关接口。 1. https://stackoverflow.com/questions/10611328/parsing-datetime-strings-containing-nanoseconds 2. https://www.python.org/dev/peps/pep-0564/ -## 重要更新 - -[**Release Notes**](https://github.com/taosdata/taos-connector-python/releases) - ## API 参考 - [taos](https://docs.taosdata.com/api/taospy/taos/) @@ -629,3 +125,442 @@ Consumer API 的 `seek` 方法用于重置 Consumer 的消费进度到指定位 欢迎[提问或报告问题](https://github.com/taosdata/taos-connector-python/issues)。 +## API 参考 + + + + +### URL 规范 + +```text +[+]://[[:@]:][/][?=[&=]] +|------------|---|-----------|-----------|------|------|------------|-----------------------| +| protocol | | username | password | host | port | database | params | +``` + +- **protocol**: 使用 websocket 协议建立连接。例如`ws://localhost:6041` +- **username/password**: 数据库的用户名和密码。 +- **host/port**: 主机地址和端口号。例如`localhost:6041` +- **database**: 数据库名称。 +- **params**: 其他参数。 例如token。 + +### 建立连接 + +- `fn connect(dsn: Option<&str>, args: Option<&PyDict>) -> PyResult` + - **接口说明**:建立 taosAdapter 连接。 + - **参数说明**: + - `dsn`: 类型 `Option<&str>` 可选,数据源名称(DSN),用于指定要连接的数据库的位置和认证信息。 + - `args`: 类型 `Option<&PyDict>` 可选,以 Python 字典的形式提供, 可用于设置 + - `user`: 数据库的用户名 + - `password`: 数据库的密码。 + - `host`: 主机地址 + - `port`: 端口号 + - `database`: 数据库名称 + - **返回值**:连接对象。 + - **异常**:操作失败抛出 `ConnectionError` 异常。 +- `fn cursor(&self) -> PyResult` + - **接口说明**:创建一个新的数据库游标对象,用于执行SQL命令和查询。 + - **返回值**:数据库游标对象。 + - **异常**:操作失败抛出 `ConnectionError` 异常。 + +### 执行SQL + +- `fn execute(&self, sql: &str) -> PyResult` + - **接口说明**:执行 sql 语句。 + - **参数说明**: + - `sql`:待执行的 sql 语句。 + - **返回值**:影响的条数。 + - **异常**:操作失败抛出 `QueryError` 异常。 +- `fn execute_with_req_id(&self, sql: &str, req_id: u64) -> PyResult` + - **接口说明**:执行带有 req_id 的 sql 语句。 + - **参数说明**: + - `sql`:待执行的 sql 语句。 + - `reqId`: 用于问题追踪。 + - **返回值**:影响的条数。 + - **异常**:操作失败抛出 `QueryError` 异常。 +- `fn query(&self, sql: &str) -> PyResult` + - **接口说明**:查询数据。 + - **参数说明**: + - `sql`:待执行的 sql 语句。 + - **返回值**:`TaosResult` 数据集对象。 + - **异常**:操作失败抛出 `QueryError` 异常。 +- `fn query_with_req_id(&self, sql: &str, req_id: u64) -> PyResult` + - **接口说明**:查询带有 req_id 的 sql 语句。 + - **参数说明**: + - `sql`:待执行的 sql 语句。 + - `reqId`: 用于问题追踪。 + - **返回值**:`TaosResult` 数据集对象。 + - **异常**:操作失败抛出 `QueryError` 异常。 + +### 数据集 + +TaosResult 对象可以通过循环遍历获取查询到的数据。 + +- `fn fields(&self) -> Vec` + - **接口说明**:获取查询数据的字段信息, 包括:名称,类型及字段长度。 + - **返回值**:`Vec` 字段信息数组。 +- `fn field_count(&self) -> i32` + - **接口说明**:获取查询到的记录条数。 + - **返回值**:`i32` 查询到的记录条数。 + +### 无模式写入 +- `fn schemaless_insert(&self, lines: Vec, protocol: PySchemalessProtocol, precision: PySchemalessPrecision, ttl: i32, req_id: u64) -> PyResult<()>` + - **接口说明**:无模式写入。 + - **参数说明**: + - `lines`:待写入的数据数组,无模式具体的数据格式可参考 `Schemaless 写入`。 + - `protocol`: 协议类型 + - `PySchemalessProtocol::Line`: InfluxDB 行协议(Line Protocol)。 + - `PySchemalessProtocol::Telnet`:OpenTSDB 文本行协议。 + - `PySchemalessProtocol::Json`: JSON 协议格式 + - `precision`: 时间精度 + - `PySchemalessPrecision::Hour`: 小时 + - `PySchemalessPrecision::Minute`:分钟 + - `PySchemalessPrecision::Second` 秒 + - `PySchemalessPrecision::Millisecond`:毫秒 + - `PySchemalessPrecision::Microsecond`:微秒 + - `PySchemalessPrecision::Nanosecond`: 纳秒 + - `ttl`:表过期时间,单位天。 + - `reqId`: 用于问题追踪。 + - **异常**:操作失败抛出 `DataError` 或 `OperationalError` 异常。 + +### 参数绑定 +- `fn statement(&self) -> PyResult` + - **接口说明**:使用 连接 对象创建 stmt 对象。 + - **返回值**:stmt 对象。 + - **异常**:操作失败抛出 `ConnectionError` 异常。 +- `fn prepare(&mut self, sql: &str) -> PyResult<()>` + - **接口说明**:绑定预编译 sql 语句。 + - **参数说明**: + - `sql`: 预编译的 SQL 语句。 + - **异常**:操作失败抛出 `ProgrammingError` 异常。 +- `fn set_tbname(&mut self, table_name: &str) -> PyResult<()>` + - **接口说明**:设置将要写入数据的表名。 + - **参数说明**: + - `tableName`: 表名,如果需要指定数据库, 例如: `db_name.table_name` 即可。 + - **异常**:操作失败抛出 `ProgrammingError` 异常。 +- `fn set_tags(&mut self, tags: Vec) -> PyResult<()>` + - **接口说明**:设置表 Tags 数据, 用于自动建表。 + - **参数说明**: + - `paramsArray`: Tags 数据。 + - **异常**:操作失败抛出 `ProgrammingError` 异常。 +- `fn bind_param(&mut self, params: Vec) -> PyResult<()>` + - **接口说明**:绑定数据。 + - **参数说明**: + - `paramsArray`: 绑定数据。 + - **异常**:操作失败抛出 `ProgrammingError` 异常。 +- `fn add_batch(&mut self) -> PyResult<()>` + - **接口说明**:提交绑定数据。 + - **异常**:操作失败抛出 `ProgrammingError` 异常。 +- `fn execute(&mut self) -> PyResult` + - **接口说明**:执行将绑定的数据全部写入。 + - **返回值**:写入条数。 + - **异常**:操作失败抛出 `QueryError` 异常。 +- `fn affect_rows(&mut self) -> PyResult` + - **接口说明**: 获取写入条数。 + - **返回值**:写入条数。 +- `fn close(&self) -> PyResult<()>` + - **接口说明**: 关闭 stmt 对象。 + +### 数据订阅 +- **创建消费者支持属性列表**: + - host:主机地址。 + - port:端口号。 + - group.id:所在的 group。 + - client.id:客户端id。 + - td.connect.user: 数据库用户名。 + - td.connect.pass: 数据库密码。 + - td.connect.token:数据库的连接token。 + - auto.offset.reset:来确定消费位置为最新数据(latest)还是包含旧数据(earliest)。 + - enable.auto.commit:是否允许自动提交。 + - auto.commit.interval.ms:自动提交间隔 + +- `fn Consumer(conf: Option<&PyDict>, dsn: Option<&str>) -> PyResult` + - **接口说明** 消费者构造函数。 + - `conf`: 类型 `Option<&PyDict>` 可选,以 Python 字典的形式提供, 具体配置参见属性列表。 + - `dsn`: 类型 `Option<&str>` 可选,数据源名称(DSN),用于指定要连接的数据库的位置和认证信息。 + - **返回值**:Consumer 消费者对象。 + - **异常**:操作失败抛出 `ConsumerException` 异常。 +- `fn subscribe(&mut self, topics: &PyList) -> PyResult<()>` + - **接口说明** 订阅一组主题。 + - **参数说明**: + - `topics`: 订阅的主题列表。 + - **异常**:操作失败抛出 `ConsumerException` 异常。 +- `fn unsubscribe(&mut self)` + - **接口说明** 取消订阅。 + - **异常**:操作失败抛出 `ConsumerException` 异常。 +- `fn poll(&mut self, timeout: Option) -> PyResult>` + - **接口说明** 轮询消息。 + - **参数说明**: + - `timeoutMs`: 表示轮询的超时时间,单位毫秒。 + - **返回值**:`Message` 每个主题对应的数据。 + - **异常**:操作失败抛出 `ConsumerException` 异常。 +- `fn commit(&mut self, message: &mut Message) -> PyResult<()>` + - **接口说明** 提交当前处理的消息的偏移量。 + - **参数说明**: + - `message`: 类型 `Message`, 当前处理的消息的偏移量。 + - **异常**:操作失败抛出 `ConsumerException` 异常。 +- `fn assignment(&mut self) -> PyResult>>` + - **接口说明**:获取消费者当前分配的指定的分区或所有分区。 + - **返回值**:返回值类型为 `Vec`,即消费者当前分配的所有分区。 + - **异常**:操作失败抛出 ConsumerException 异常。 +- `fn seek(&mut self, topic: &str, vg_id: i32, offset: i64) -> PyResult<()>` + - **接口说明**:将给定分区的偏移量设置到指定的位置。 + - **参数说明**: + - `topic`: 订阅的主题。 + - `vg_id`: vgroupid。 + - `offset`:需要设置的的偏移量。 + - **异常**:操作失败抛出 ConsumerException 异常。 +- `fn committed(&mut self, topic: &str, vg_id: i32) -> PyResult` + - **接口说明**:获取订阅主题的vgroupid分区最后提交的偏移量。 + - **参数说明**: + - `topic`: 订阅的主题。 + - `vg_id`: vgroupid。 + - **返回值**:`i64`,分区最后提交的偏移量。 + - **异常**:操作失败抛出 ConsumerException 异常。 +- `fn position(&mut self, topic: &str, vg_id: i32) -> PyResult` + - **接口说明**:获取给定分区当前的偏移量。 + - **参数说明**: + - `topic`: 订阅的主题。 + - `vg_id`: vgroupid。 + - **返回值**:`i64`,分区最后提交的偏移量。 + - **异常**:操作失败抛出 ConsumerException 异常。 +- `fn close(&mut self)` + - **接口说明**:关闭 tmq 连接。 + - **异常**:操作失败抛出 ConsumerException 异常。 + + + +### 建立连接 + +- `def connect(*args, **kwargs):` + - **接口说明**:建立 taosAdapter 连接。 + - **参数说明**: + - `kwargs`: 以 Python 字典的形式提供, 可用于设置 + - `user`: 数据库的用户名 + - `password`: 数据库的密码。 + - `host`: 主机地址 + - `port`: 端口号 + - `database`: 数据库名称 + - `timezone`: 时区 + - **返回值**:`TaosConnection` 连接对象。 + - **异常**:操作失败抛出 `AttributeError` 或 `ConnectionError` 异常。 +- `def cursor(self)` + - **接口说明**:创建一个新的数据库游标对象,用于执行SQL命令和查询。 + - **返回值**:数据库游标对象。 + + +### 执行SQL + +- `def execute(self, operation, req_id: Optional[int] = None)` + - **接口说明**:执行 sql 语句。 + - **参数说明**: + - `operation`:待执行的 sql 语句。 + - `reqId`: 用于问题追踪。 + - **返回值**:影响的条数。 + - **异常**:操作失败抛出 `ProgrammingError` 异常。 +- `def query(self, sql: str, req_id: Optional[int] = None) -> TaosResult` + - **接口说明**:查询数据。 + - **参数说明**: + - `sql`:待执行的 sql 语句。 + - `reqId`: 用于问题追踪。 + - **返回值**:`TaosResult` 数据集对象。 + - **异常**:操作失败抛出 `ProgrammingError` 异常。 + +### 数据集 + +TaosResult 对象可以通过循环遍历获取查询到的数据。 + +- `def fields(&self)` + - **接口说明**:获取查询数据的字段信息, 包括:名称,类型及字段长度。 + - **返回值**:`TaosFields` 字段信息 list。 +- `def field_count(&self)` + - **接口说明**:获取查询到的记录条数。 + - **返回值**:查询到的记录条数。 +- `def fetch_all_into_dict(self)` + - **接口说明**:将所有的记录转换为字典。 + - **返回值**:返回字典列表。 + +### 无模式写入 +- `def schemaless_insert(&self, lines: List[str], protocol: SmlProtocol, precision: SmlPrecision, req_id: Optional[int] = None, ttl: Optional[int] = None) -> int:` + - **接口说明**:无模式写入。 + - **参数说明**: + - `lines`:待写入的数据数组,无模式具体的数据格式可参考 `Schemaless 写入`。 + - `protocol`: 协议类型 + - `SmlProtocol.LINE_PROTOCOL`: InfluxDB 行协议(Line Protocol)。 + - `SmlProtocol.TELNET_PROTOCOL`:OpenTSDB 文本行协议。 + - `SmlProtocol.JSON_PROTOCOL`: JSON 协议格式 + - `precision`: 时间精度 + - `SmlPrecision.Hour`: 小时 + - `SmlPrecision.Minute`:分钟 + - `SmlPrecision.Second` 秒 + - `SmlPrecision.Millisecond`:毫秒 + - `SmlPrecision.Microsecond`:微秒 + - `SmlPrecision.Nanosecond`: 纳秒 + - `ttl`:表过期时间,单位天。 + - `reqId`: 用于问题追踪。 + - **返回值**:影响的条数。 + - **异常**:操作失败抛出 `SchemalessError` 异常。 + +### 参数绑定 +- `def statement(self, sql=None)` + - **接口说明**:使用连接对象创建 stmt 对象, 如果 sql 不空会进行调用 prepare。 + - `sql`: 预编译的 SQL 语句。 + - **返回值**:stmt 对象。 + - **异常**:操作失败抛出 `StatementError` 异常。 +- `def prepare(self, sql)` + - **接口说明**:绑定预编译 sql 语句。 + - **参数说明**: + - `sql`: 预编译的 SQL 语句。 + - **异常**:操作失败抛出 `StatementError` 异常。 +- `def set_tbname(self, name)` + - **接口说明**:设置将要写入数据的表名。 + - **参数说明**: + - `name`: 表名,如果需要指定数据库, 例如: `db_name.table_name` 即可。 + - **异常**:操作失败抛出 `StatementError` 异常。 +- `def set_tbname_tags(self, name, tags):` + - **接口说明**:设置表和 Tags 数据, 用于自动建表。 + - **参数说明**: + - `name`: 表名,如果需要指定数据库, 例如: `db_name.table_name` 即可。 + - `tags`: Tags 数据。 + - **异常**:操作失败抛出 `StatementError` 异常。 +- `def bind_param(self, params, add_batch=True)` + - **接口说明**:绑定一组数据并提交。 + - **参数说明**: + - `params`: 绑定数据。 + - `add_batch`: 是否提交绑定数据。 + - **异常**:操作失败抛出 `StatementError` 异常。 +- `def bind_param_batch(self, binds, add_batch=True)` + - **接口说明**:绑定多组数据并提交。 + - **参数说明**: + - `binds`: 绑定数据。 + - `add_batch`: 是否提交绑定数据。 + - **异常**:操作失败抛出 `StatementError` 异常。 +- `def add_batch(self)` + - **接口说明**:提交绑定数据。 + - **异常**:操作失败抛出 `StatementError` 异常。 +- `def execute(self)` + - **接口说明**:执行将绑定的数据全部写入。 + - **异常**:操作失败抛出 `StatementError` 异常。 +- `def affected_rows(self)` + - **接口说明**: 获取写入条数。 + - **返回值**:写入条数。 +- `def close(&self)` + - **接口说明**: 关闭 stmt 对象。 + +### 数据订阅 +- **创建消费者支持属性列表**: + - td.connect.ip:主机地址。 + - td.connect.port:端口号。 + - group.id:所在的 group。 + - client.id:客户端id。 + - td.connect.user: 数据库用户名。 + - td.connect.pass: 数据库密码。 + - td.connect.token:数据库的连接token。 + - auto.offset.reset:来确定消费位置为最新数据(latest)还是包含旧数据(earliest)。 + - enable.auto.commit:是否允许自动提交。 + - auto.commit.interval.ms:自动提交间隔 +- `def Consumer(configs)` + - **接口说明** 消费者构造函数。 + - `configs`: Python 字典的形式提供, 具体配置参见属性列表。 + - **返回值**:Consumer 消费者对象。 + - **异常**:操作失败抛出 `TmqError` 异常。 +- `def subscribe(self, topics)` + - **接口说明** 订阅一组主题。 + - **参数说明**: + - `topics`: 订阅的主题列表。 + - **异常**:操作失败抛出 `TmqError` 异常。 +- `def unsubscribe(self)` + - **接口说明** 取消订阅。 + - **异常**:操作失败抛出 `TmqError` 异常。 +- `def poll(self, timeout: float = 1.0)` + - **接口说明** 轮询消息。 + - **参数说明**: + - `timeout`: 表示轮询的超时时间,单位毫秒。 + - **返回值**:`Message` 每个主题对应的数据。 + - **异常**:操作失败抛出 `TmqError` 异常。 +- `def commit(self, message: Message = None, offsets: [TopicPartition] = None)` + - **接口说明** 提交当前处理的消息的偏移量。 + - **参数说明**: + - `message`: 类型 `Message`, 当前处理的消息的偏移量。 + - `offsets`: 类型 `[TopicPartition]`, 提交一批消息的偏移量。 + - **异常**:操作失败抛出 `TmqError` 异常。 +- `def assignment(self)` + - **接口说明**:获取消费者当前分配的指定的分区或所有分区。 + - **返回值**:返回值类型为 `[TopicPartition]`,即消费者当前分配的所有分区。 + - **异常**:操作失败抛出 TmqError 异常。 +- `def seek(self, partition)` + - **接口说明**:将给定分区的偏移量设置到指定的位置。 + - **参数说明**: + - `partition`: 需要设置的的偏移量。 + - `topic`: 订阅的主题 + - `partition`: 分区 + - `offset`: 偏移量 + - **异常**:操作失败抛出 `TmqError` 异常。 +- `def committed(self, partitions)` + - **接口说明**:获取订阅主题的分区最后提交的偏移量。 + - **参数说明**: + - `partition`: 需要设置的的偏移量。 + - `topic`: 订阅的主题 + - `partition`: 分区 + - **返回值**:`partition`,分区最后提交的偏移量。 + - **异常**:操作失败抛出 `TmqError` 异常。 +- `def position(self, partitions)` + - **接口说明**:获取给定分区当前的偏移量。 + - **参数说明**: + - `partition`: 需要设置的的偏移量。 + - `topic`: 订阅的主题 + - `partition`: 分区 + - **返回值**:`partition`,分区最后提交的偏移量。 + - **异常**:操作失败抛出 TmqError 异常。 +- `def close(self)` + - **接口说明**:关闭 tmq 连接。 + - **异常**:操作失败抛出 TmqError 异常。 + + +- `def connect(**kwargs) -> TaosRestConnection` + - **接口说明**:建立 taosAdapter 连接。 + - **参数说明**: + - `kwargs`: 以 Python 字典的形式提供, 可用于设置 + - `user`: 数据库的用户名 + - `password`: 数据库的密码。 + - `host`: 主机地址 + - `port`: 端口号 + - `database`: 数据库名称 + - **返回值**:连接对象。 + - **异常**:操作失败抛出 `ConnectError` 异常。 +- `def execute(self, sql: str, req_id: Optional[int] = None) -> Optional[int]` + - **接口说明**:执行 sql 语句。 + - **参数说明**: + - `sql`:待执行的 sql 语句。 + - `reqId`: 用于问题追踪。 + - **返回值**:影响的条数。 + - **异常**:操作失败抛出 `ConnectError` 或 `HTTPError` 异常。 +- `def query(self, sql: str, req_id: Optional[int] = None) -> Result` + - **接口说明**:查询数据。 + - **参数说明**: + - `sql`:待执行的 sql 语句。 + - `reqId`: 用于问题追踪。 + - **返回值**:`Result` 数据集对象。 + - **异常**:操作失败抛出 `ConnectError` 或 `HTTPError` 异常。 +- `RestClient(self, url: str, token: str = None, database: str = None, user: str = "root", password: str = "taosdata", timeout: int = None, convert_timestamp: bool = True, timezone: Union[str, datetime.tzinfo] = None)` + - **接口说明**:建立 taosAdapter 连接 client。 + - **参数说明**: + - `url`: taosAdapter REST 服务的 URL。默认是 \。 + - `user`: 数据库的用户名。 + - `password`: 数据库的密码。 + - `database`: 数据库名称。 + - `timezone`: 时区。 + - `timeout`: HTTP 请求超时时间。单位为秒。 + - `convert_timestamp`: 是否将时间戳从STR类型转换为datetime类型。 + - `timezone`: 时区. + - **返回值**:连接对象。 + - **异常**:操作失败抛出 `ConnectError` 异常。 +- `def sql(self, q: str, req_id: Optional[int] = None) -> dict` + - **接口说明**:执行 sql 语句。 + - **参数说明**: + - `sql`:待执行的 sql 语句。 + - `reqId`: 用于问题追踪。 + - **返回值**:返回字典列表。 + - **异常**:操作失败抛出 `ConnectError` 或 `HTTPError` 异常。 + + diff --git a/docs/zh/14-reference/05-connector/35-node.mdx b/docs/zh/14-reference/05-connector/35-node.mdx index 88a27ad05a..c963b0c7f7 100644 --- a/docs/zh/14-reference/05-connector/35-node.mdx +++ b/docs/zh/14-reference/05-connector/35-node.mdx @@ -28,15 +28,6 @@ Node.js 连接器目前仅支持 Websocket 连接器, 其通过 taosAdapter | :------------------: | :----------------------: | :----------------: | | 3.1.0 | 新版本发布,支持 WebSocket 连接 | 3.2.0.0 及更高版本 | -## 支持的功能特性 - -- 连接管理 -- SQL写入 -- SQL查询 -- 参数绑定 -- 数据订阅 -- 无模式写入 - ## 处理异常 在调用连接器 api 报错后,通过 try catch 可以获取到错误的信息和错误码。 @@ -85,227 +76,6 @@ Node.js 连接器目前仅支持 Websocket 连接器, 其通过 taosAdapter **注意**:JSON 类型仅在 tag 中支持。 -## 安装步骤 - -### 安装前准备 - -- 安装 Node.js 开发环境, 使用14以上版本。下载链接: https://nodejs.org/en/download/ - -### 使用 npm 安装 Node.js 连接器 - -```bash -npm install @tdengine/websocket -``` - -### 安装验证 - -验证方法: - -- 新建安装验证目录,例如:`~/tdengine-test`,下载 GitHub 上 [nodejsChecker.js 源代码](https://github.com/taosdata/TDengine/tree/main/docs/examples/node/websocketexample/nodejsChecker.js)到本地。 - -- 在命令行中执行以下命令。 - -```bash - npm init -y - npm install @tdengine/websocket - node nodejsChecker.js -``` - -- 执行以上步骤后,在命令行会输出 nodeChecker.js 连接 TDengine 实例,并执行简单插入和查询的结果。 - -## 建立连接 - -安装并引用 `@tdengine/websocket` 包。 - -**注意**: -- 链接器使用结束后,需要调用 taos.destroy() 释放连接器资源 -```javascript -const taos = require("@tdengine/websocket"); - -//数据库操作...... - -taos.destroy(); -``` - -```javascript -WSConfig配置Websocket参数如下: - getToken(): string | undefined | null; - setToken(token: string): void; - getUser(): string | undefined | null; - setUser(user: string): void; - getPwd(): string | undefined | null; - setPwd(pws: string): void; - getDb(): string | undefined | null; - setDb(db: string): void; - getUrl(): string; - setUrl(url: string): void; - setTimeOut(ms: number): void; - getTimeOut(): number | undefined | null; -``` - -```javascript -{{#include docs/examples/node/websocketexample/sql_example.js:createConnect}} -``` - -## 使用示例 - -### 创建数据库和表 - -```javascript -{{#include docs/examples/node/websocketexample/sql_example.js:create_db_and_table}} -``` -> **注意**:如果不使用 `USE power` 指定数据库,则后续对表的操作都需要增加数据库名称作为前缀,如 power.meters。 - -### 插入数据 - -```javascript -{{#include docs/examples/node/websocketexample/sql_example.js:insertData}} -``` - -> NOW 为系统内部函数,默认为客户端所在计算机当前时间。 -> `NOW + 1s` 代表客户端当前时间往后加 1 秒,数字后面代表时间单位:a(毫秒),s(秒),m(分),h(小时),d(天),w(周),n(月),y(年)。 - -### 查询数据 - -```javascript -{{#include docs/examples/node/websocketexample/sql_example.js:queryData}} -``` - -> 查询到的数据 - -```javascript -wsRow:meta:=> [ - { name: 'ts', type: 'TIMESTAMP', length: 8 }, - { name: 'current', type: 'FLOAT', length: 4 }, - { name: 'voltage', type: 'INT', length: 4 }, - { name: 'phase', type: 'FLOAT', length: 4 }, - { name: 'location', type: 'VARCHAR', length: 64}, - { name: 'groupid', type: 'INT', length: 4 } -] -wsRow:data:=> [ - [ 1714013737536n, 12.3, 221, 0.31, 'California.SanFrancisco', 3 ] -] -``` - -### 执行带有 reqId 的 SQL - - - -```javascript -{{#include docs/examples/node/websocketexample/sql_example.js:sqlWithReqid}} -``` - -### 通过参数绑定写入数据 - -TDengine 的 NodeJs 连接器支持参数绑定风格的 Prepare API 方式写入数据,和大多数数据库类似,目前仅支持用 ? 来代表待绑定的参数。采用这种方式写入数据时,能避免 SQL 语法解析的资源消耗,从而在很多情况下显著提升写入性能。 - -**注意**: -- 预处理语句中指定数据库与子表名称不要使用 `db.?`,应直接使用 `?`,然后在 setTableName 中指定数据库,如:`stmt.setTableName("db.t1")`。 - -示例代码: -```javascript -{{#include docs/examples/node/websocketexample/stmt_example.js}} -``` - -用于设定 TAG/VALUES 数据列的取值的方法总共有: - -```javascript -setBoolean(params: any[]): void; -setTinyInt(params: any[]): void; -setUTinyInt(params: any[]): void; -setSmallInt(params: any[]): void; -setUSmallInt(params: any[]): void; -setInt(params: any[]): void; -setUInt(params: any[]): void; -setBigint(params: any[]): void; -setUBigint(params: any[]): void; -setFloat(params: any[]): void; -setDouble(params: any[]): void; -setVarchar(params: any[]): void; -setBinary(params: any[]): void; -setNchar(params: any[]): void; -setJson(params: any[]): void; -setVarBinary(params: any[]): void; -setGeometry(params: any[]): void; -setTimestamp(params: any[]): void; -``` - -**注意**:JSON 类型仅在 tag 中支持。 - -### 无模式写入 - -TDengine 支持无模式写入功能。无模式写入兼容 InfluxDB 的 行协议(Line Protocol)、OpenTSDB 的 telnet 行协议和 OpenTSDB 的 JSON 格式协议。详情请参见[无模式写入](../../reference/schemaless/)。 - -```javascript -{{#include docs/examples/node/websocketexample/line_example.js}} -``` - -### 执行带有 reqId 的无模式写入 - -此 reqId 可用于请求链路追踪。 - -```javascript -await wsSchemaless.schemalessInsert([influxdbData], SchemalessProto.InfluxDBLineProtocol, Precision.NANO_SECONDS, ttl, reqId); -await wsSchemaless.schemalessInsert([telnetData], SchemalessProto.OpenTSDBTelnetLineProtocol, Precision.NANO_SECONDS, ttl, reqId); -await wsSchemaless.schemalessInsert([jsonData], SchemalessProto.OpenTSDBJsonFormatProtocol, Precision.NANO_SECONDS, ttl, reqId); -``` - -### 数据订阅 - -TDengine NodeJs 连接器支持订阅功能,应用 API 如下: - -#### 创建 Topic -```javascript -{{#include docs/examples/node/websocketexample/tmq_example.js:create_topic}} -``` - -#### 创建 Consumer - -```javascript -{{#include docs/examples/node/websocketexample/tmq_example.js:create_consumer}} -``` -> 参数说明 -- taos.TMQConstants.CONNECT_USER: 用户名。 -- taos.TMQConstants.CONNECT_PASS: 密码。 -- taos.TMQConstants.GROUP_ID: 所在的 group。 -- taos.TMQConstants.CLIENT_ID: client id。 -- taos.TMQConstants.WS_URL: taosAdapter 的url地址。 -- taos.TMQConstants.AUTO_OFFSET_RESET: 来确定消费位置为最新数据(latest)还是包含旧数据(earliest)。 -- taos.TMQConstants.ENABLE_AUTO_COMMIT: 是否允许自动提交。 -- taos.TMQConstants.AUTO_COMMIT_INTERVAL_MS: 自动提交间隔。 -- taos.TMQConstants.CONNECT_MESSAGE_TIMEOUT: 数据传输超时参数,单位 ms,默认为 10000 ms。 - -其他参数请参考:[Consumer 参数列表](../../develop/tmq/#数据订阅相关参数), 注意 TDengine 服务端自3.2.0.0版本开始消息订阅中的 auto.offset.reset 默认值发生变化。 - -#### 订阅消费数据 -```javascript -{{#include docs/examples/node/websocketexample/tmq_example.js:subscribe}} -``` - -#### 指定订阅 Offset - -```javascript -{{#include docs/examples/node/websocketexample/tmq_example.js:assignment}} -``` - -#### 关闭订阅 -```javascript -// 取消订阅 -consumer.unsubscribe(); -// 关闭消费 -consumer.close() -// 释放连接器资源 -taos.destroy(); -``` - -详情请参考:[数据订阅](../../develop/tmq) - -#### 完整示例 - -```javascript -{{#include docs/examples/node/websocketexample/tmq_example.js}} -``` - ## 更多示例程序 | 示例程序 | 示例程序描述 | @@ -447,17 +217,24 @@ WSConfig 中的配置如下: - **接口说明**:无模式写入。 - **参数说明**: - `lines`:待写入的数据数组,无模式具体的数据格式可参考 `Schemaless 写入`。 - - `protocol`: - ```js - InfluxDBLineProtocol //InfluxDB 行协议(Line Protocol) - OpenTSDBTelnetLineProtocol //OpenTSDB 文本行协议 - OpenTSDBJsonFormatProtocol //JSON 协议格式 - ``` + - `protocol`: 协议类型 + - `SchemalessProto.InfluxDBLineProtocol`:InfluxDB 行协议(Line Protocol)。 + - `SchemalessProto.OpenTSDBTelnetLineProtocol`:OpenTSDB 文本行协议。 + - `SchemalessProto.OpenTSDBJsonFormatProtocol`:JSON 协议格式。 + - `precision`: 时间精度 + - `Precision.HOURS`: 小时 + - `Precision.MINUTES`:分钟 + - `Precision.SECONDS`:秒 + - `Precision.MILLI_SECONDS`:毫秒 + - `Precision.MICRO_SECONDS`:微秒 + - `Precision.NANO_SECONDS`: 纳秒 + - `ttl`:表过期时间,单位天。 + - `reqId`: 用于问题追踪,可选。 - **异常**:连接失败抛出 `TaosResultError` 异常。 ### 参数绑定 - `async stmtInit(reqId?:number): Promise` - - **接口说明** 使用 WsSql 对象创建 stmt 对象创建。 + - **接口说明** 使用 WsSql 对象创建 stmt 对象。 - **参数说明**: - `reqId`: 请求 id 非必填,用于问题追踪。 - **返回值**:stmt 对象。 @@ -466,7 +243,6 @@ WSConfig 中的配置如下: - **接口说明** 绑定预编译 sql 语句。 - **参数说明**: - `sql`: 预编译的 SQL 语句。 - - **返回值**:stmt 对象。 - **异常**:连接失败抛出 `TDWebSocketClientError` 异常。 - `async setTableName(tableName: string): Promise` - **接口说明** 设置将要写入数据的表名。 @@ -497,6 +273,11 @@ WSConfig 中的配置如下: - `setVarBinary(params :any[])` - `setGeometry(params :any[])` - `setTimestamp(params :any[])` +- `async setTags(paramsArray:StmtBindParams): Promise` + - **接口说明** 设置表 Tags 数据,用于自动建表。 + - **参数说明**: + - `paramsArray`: Tags 数据。 + - **异常**:连接失败抛出 `TDWebSocketClientError` 异常。 - `async bind(paramsArray:StmtBindParams): Promise` - **接口说明** 绑定数据。 - **参数说明**: @@ -508,6 +289,9 @@ WSConfig 中的配置如下: - `async exec(): Promise` - **接口说明** 执行将绑定的数据全部写入。 - **异常**:连接失败抛出 `TDWebSocketClientError` 异常。 +- `getLastAffected()` + - **接口说明** 获取写入条数。 + - **返回值**:写入条数。 - `async close(): Promise` - **接口说明** 关闭 stmt 对象。 - **异常**:连接失败抛出 `TDWebSocketClientError` 异常。 @@ -518,7 +302,7 @@ WSConfig 中的配置如下: - taos.TMQConstants.CONNECT_USER: 用户名。 - taos.TMQConstants.CONNECT_PASS: 密码。 - taos.TMQConstants.GROUP_ID: 所在的 group。 - - taos.TMQConstants.CLIENT_ID: client id。 + - taos.TMQConstants.CLIENT_ID: 客户端id。 - taos.TMQConstants.WS_URL: taosAdapter 的url地址。 - taos.TMQConstants.AUTO_OFFSET_RESET: 来确定消费位置为最新数据(latest)还是包含旧数据(earliest)。 - taos.TMQConstants.ENABLE_AUTO_COMMIT: 是否允许自动提交。 @@ -529,37 +313,37 @@ WSConfig 中的配置如下: - **参数说明**: - `wsConfig`: 创建消费者属性配置。 - **返回值**:WsConsumer 消费者对象。 - - **异常**:连接失败抛出 `TDWebSocketClientError` 异常。 + - **异常**:如果在执行过程中出现异常,抛出 `TDWebSocketClientError` 错误。 - `async subscribe(topics: Array, reqId?:number): Promise` - **接口说明** 订阅一组主题。 - **参数说明**: - `topics`: 订阅的主题列表。 - `reqId`: 请求 id 非必填,用于问题追踪。 - - **异常**:连接失败抛出 `TDWebSocketClientError` 异常。 + - **异常**:失败抛出 `TDWebSocketClientError` 异常。 - `async unsubscribe(reqId?:number): Promise` - **接口说明** 取消订阅。 - **参数说明**: - `reqId`: 请求 id 非必填,用于问题追踪。 - - **异常**:连接失败抛出 `TDWebSocketClientError` 异常。 + - **异常**:失败抛出 `TDWebSocketClientError` 异常。 - `async poll(timeoutMs: number, reqId?:number):Promise>` - **接口说明** 轮询消息。 - **参数说明**: - `timeoutMs`: 表示轮询的超时时间,单位毫秒。 - `reqId`: 请求 id 非必填,用于问题追踪。 - **返回值**:`Map` 每个主题对应的数据。 - - **异常**:连接失败抛出 `TDWebSocketClientError` 异常。 + - **异常**:失败抛出 `TDWebSocketClientError` 异常。 - `async subscription(reqId?:number):Promise>` - **接口说明** 获取当前订阅的所有主题。 - **参数说明**: - `reqId`: 请求 id 非必填,用于问题追踪。 - **返回值**:`Array` 主题列表。 - - **异常**:连接失败抛出 `TDWebSocketClientError` 异常。 + - **异常**:失败抛出 `TDWebSocketClientError` 异常。 - `async commit(reqId?:number):Promise>` - **接口说明** 提交当前处理的消息的偏移量。 - **参数说明**: - `reqId`: 请求 id 非必填,用于问题追踪。 - **返回值**:`Array` 每个主题的消费进度。 - - **异常**:连接失败抛出 `TDWebSocketClientError` 异常。 + - **异常**:失败抛出 `TDWebSocketClientError` 异常。 - `async committed(partitions:Array, reqId?:number):Promise>` - **接口说明**:获取一组分区最后提交的偏移量。 - **参数说明**: @@ -597,5 +381,5 @@ WSConfig 中的配置如下: - **返回值**:返回值类型为 `Array`,即消费者当前分配的所有分区。 - **异常**:如果在获取分配的分区过程中发生错误,将抛出 TDWebSocketClientError 异常。 - `async close():Promise` - - **接口说明**:关闭数据库连接。 + - **接口说明**:关闭 tmq 连接。 - **异常**:操作失败抛出 `TDWebSocketClientError` 异常。 From 971a80d6f032379e7663d881d1ebb3c438217112 Mon Sep 17 00:00:00 2001 From: menshibin Date: Thu, 1 Aug 2024 18:17:52 +0800 Subject: [PATCH 10/14] modify python nodejs install --- docs/zh/08-develop/01-connect/index.md | 96 +++++++++++++++++++------- 1 file changed, 72 insertions(+), 24 deletions(-) diff --git a/docs/zh/08-develop/01-connect/index.md b/docs/zh/08-develop/01-connect/index.md index fcb70f2293..5f566267f4 100644 --- a/docs/zh/08-develop/01-connect/index.md +++ b/docs/zh/08-develop/01-connect/index.md @@ -97,18 +97,63 @@ TDengine 提供了丰富的应用程序开发接口,为了便于用户快速 -使用 `pip` 从 PyPI 安装: +- **安装前准备** + - 安装 Python。新近版本 taospy 包要求 Python 3.6.2+。早期版本 taospy 包要求 Python 3.7+。taos-ws-py 包要求 Python 3.7+。如果系统上还没有 Python 可参考 [Python BeginnersGuide](https://wiki.python.org/moin/BeginnersGuide/Download) 安装。 + - 安装 [pip](https://pypi.org/project/pip/)。大部分情况下 Python 的安装包都自带了 pip 工具, 如果没有请参考 [pip documentation](https://pip.pypa.io/en/stable/installation/) 安装。 + - 如果使用原生连接,还需[安装客户端驱动](../#安装客户端驱动)。客户端软件包含了 TDengine 客户端动态链接库(libtaos.so 或 taos.dll) 和 TDengine CLI。 -``` -pip install taospy -``` - -从 Git URL 安装: - -``` -pip install git+https://github.com/taosdata/taos-connector-python.git -``` +- **使用 pip 安装** + - 卸载旧版本 + 如果以前安装过旧版本的 Python 连接器, 请提前卸载。 + ``` + pip3 uninstall taos taospy + pip3 uninstall taos taos-ws-py + ``` + - 安装 `taospy` + - 最新版本 + ``` + pip3 install taospy + ``` + - 指定某个特定版本安装 + ``` + pip3 install taospy==2.3.0 + ``` + - 从 GitHub 安装 + ``` + pip3 install git+https://github.com/taosdata/taos-connector-python.git + ``` + :::note 此安装包为原生连接器 + - 安装 `taos-ws-py` + ```bash + pip3 install taos-ws-py + ``` + :::note 此安装包为 Websocket 连接器 + - 同时安装 `taospy` 和 `taos-ws-py` + ```bash + pip3 install taospy[ws] + ``` + - **安装验证** + + + 对于原生连接,需要验证客户端驱动和 Python 连接器本身是否都正确安装。如果能成功导入 `taos` 模块,则说明已经正确安装了客户端驱动和 Python 连接器。可在 Python 交互式 Shell 中输入: + ```python + import taos + ``` + + + 对于 REST 连接,只需验证是否能成功导入 `taosrest` 模块。可在 Python 交互式 Shell 中输入: + ```python + import taosrest + ``` + + + 对于 WebSocket 连接,只需验证是否能成功导入 `taosws` 模块。可在 Python 交互式 Shell 中输入: + ```python + import taosws + ``` + + @@ -149,23 +194,26 @@ taos = { version = "*", default-features = false, features = ["ws"] } -Node.js 连接器通过不同的包提供不同的连接方式。 +- **安装前准备** + - 安装 Node.js 开发环境, 使用14以上版本。下载链接: https://nodejs.org/en/download/ -1. 安装 Node.js 原生连接器 +- **安装** + - 使用 npm 安装 Node.js 连接器 + ``` + npm install @tdengine/websocket + ``` + :::note Node.js 目前只支持 Websocket 连接 +- **安装验证** + - 新建安装验证目录,例如:`~/tdengine-test`,下载 GitHub 上 [nodejsChecker.js 源代码](https://github.com/taosdata/TDengine/tree/main/docs/examples/node/websocketexample/nodejsChecker.js)到本地。 + - 在命令行中执行以下命令。 + ```bash + npm init -y + npm install @tdengine/websocket + node nodejsChecker.js + ``` + - 执行以上步骤后,在命令行会输出 nodeChecker.js 连接 TDengine 实例,并执行简单插入和查询的结果。 -``` -npm install @tdengine/client -``` -:::note -推荐 Node 版本大于等于 `node-v12.8.0` 小于 `node-v13.0.0` -::: - -2. 安装 Node.js REST 连接器 - -``` -npm install @tdengine/rest -``` From 3c285d48cd74fc862fa345c87def2b838907c654 Mon Sep 17 00:00:00 2001 From: menshibin Date: Thu, 1 Aug 2024 20:13:35 +0800 Subject: [PATCH 11/14] modify python api --- .../node/websocketexample/sql_example.js | 2 +- docs/examples/python/connect_example.py | 7 +-- .../08-develop/01-connect/_connect_python.mdx | 13 +----- docs/zh/08-develop/01-connect/index.md | 17 +++---- .../14-reference/05-connector/30-python.mdx | 46 ++++++++----------- 5 files changed, 31 insertions(+), 54 deletions(-) diff --git a/docs/examples/node/websocketexample/sql_example.js b/docs/examples/node/websocketexample/sql_example.js index 484559e2b3..836fb68829 100644 --- a/docs/examples/node/websocketexample/sql_example.js +++ b/docs/examples/node/websocketexample/sql_example.js @@ -1,6 +1,6 @@ +// ANCHOR: createConnect const taos = require("@tdengine/websocket"); -// ANCHOR: createConnect async function createConnect() { let dsn = 'ws://localhost:6041'; let conf = new taos.WSConfig(dsn); diff --git a/docs/examples/python/connect_example.py b/docs/examples/python/connect_example.py index 719af79fd1..c31e1cac51 100644 --- a/docs/examples/python/connect_example.py +++ b/docs/examples/python/connect_example.py @@ -1,19 +1,14 @@ import taos - def test_connection(): # all parameters are optional. - # if database is specified, - # then it must exist. conn = taos.connect(host="localhost", port=6030, user="root", - password="taosdata", - database="log") + password="taosdata") print('client info:', conn.client_info) print('server info:', conn.server_info) conn.close() - if __name__ == "__main__": test_connection() diff --git a/docs/zh/08-develop/01-connect/_connect_python.mdx b/docs/zh/08-develop/01-connect/_connect_python.mdx index 222c92fc0d..8b04088ac3 100644 --- a/docs/zh/08-develop/01-connect/_connect_python.mdx +++ b/docs/zh/08-develop/01-connect/_connect_python.mdx @@ -1,14 +1,3 @@ -```text -[+]://[[:@]:][/][?=[&=]] -|------------|---|-----------|-----------|------|------|------------|-----------------------| -| protocol | | username | password | host | port | database | params | -- **protocol**: Display using websocket protocol to establish connection. -- **username/password**: Database's username and password. -- **host/port**: Declare host and port. eg. `localhost:6041` -- **database**: Optional, use to specify database name. -- **params**: Other parameters. Like cloud Token. -``` - ```python -{{#include docs/examples/python/connect_websocket_examples.py:connect}} +{{#include docs/examples/python/connect_example.py}} ``` diff --git a/docs/zh/08-develop/01-connect/index.md b/docs/zh/08-develop/01-connect/index.md index e8eb2891a4..ac2787a4cc 100644 --- a/docs/zh/08-develop/01-connect/index.md +++ b/docs/zh/08-develop/01-connect/index.md @@ -351,10 +351,9 @@ URL 和 Properties 的详细参数说明和如何使用详见 [API 说明](../.. ``` - - ```python - {{#include docs/examples/python/connect_websocket_examples.py:connect}} - ``` +```python +{{#include docs/examples/python/connect_websocket_examples.py:connect}} +``` @@ -363,9 +362,9 @@ URL 和 Properties 的详细参数说明和如何使用详见 [API 说明](../.. - ```js - {{#include docs/examples/node/websocketexample/sql_example.js:createConnect}} - ``` +```js +{{#include docs/examples/node/websocketexample/sql_example.js:createConnect}} +``` @@ -424,7 +423,9 @@ URL 和 Properties 的详细参数说明和如何使用详见 [API 说明](../.. ``` - +```python +{{#include docs/examples/python/connect_rest_examples.py:connect}} +``` diff --git a/docs/zh/14-reference/05-connector/30-python.mdx b/docs/zh/14-reference/05-connector/30-python.mdx index 7f5897c021..cbc0436010 100644 --- a/docs/zh/14-reference/05-connector/30-python.mdx +++ b/docs/zh/14-reference/05-connector/30-python.mdx @@ -115,11 +115,6 @@ TDengine 目前支持时间戳、数字、字符、布尔类型,与 Python 对 1. https://stackoverflow.com/questions/10611328/parsing-datetime-strings-containing-nanoseconds 2. https://www.python.org/dev/peps/pep-0564/ - -## API 参考 - -- [taos](https://docs.taosdata.com/api/taospy/taos/) -- [taosrest](https://docs.taosdata.com/api/taospy/taosrest) ## 常见问题 @@ -127,10 +122,9 @@ TDengine 目前支持时间戳、数字、字符、布尔类型,与 Python 对 ## API 参考 - - +### WebSocket 连接 -### URL 规范 +#### URL 规范 ```text [+]://[[:@]:][/][?=[&=]] @@ -144,7 +138,7 @@ TDengine 目前支持时间戳、数字、字符、布尔类型,与 Python 对 - **database**: 数据库名称。 - **params**: 其他参数。 例如token。 -### 建立连接 +#### 建立连接 - `fn connect(dsn: Option<&str>, args: Option<&PyDict>) -> PyResult` - **接口说明**:建立 taosAdapter 连接。 @@ -163,7 +157,7 @@ TDengine 目前支持时间戳、数字、字符、布尔类型,与 Python 对 - **返回值**:数据库游标对象。 - **异常**:操作失败抛出 `ConnectionError` 异常。 -### 执行SQL +#### 执行SQL - `fn execute(&self, sql: &str) -> PyResult` - **接口说明**:执行 sql 语句。 @@ -192,7 +186,7 @@ TDengine 目前支持时间戳、数字、字符、布尔类型,与 Python 对 - **返回值**:`TaosResult` 数据集对象。 - **异常**:操作失败抛出 `QueryError` 异常。 -### 数据集 +#### 数据集 TaosResult 对象可以通过循环遍历获取查询到的数据。 @@ -203,7 +197,7 @@ TaosResult 对象可以通过循环遍历获取查询到的数据。 - **接口说明**:获取查询到的记录条数。 - **返回值**:`i32` 查询到的记录条数。 -### 无模式写入 +#### 无模式写入 - `fn schemaless_insert(&self, lines: Vec, protocol: PySchemalessProtocol, precision: PySchemalessPrecision, ttl: i32, req_id: u64) -> PyResult<()>` - **接口说明**:无模式写入。 - **参数说明**: @@ -223,7 +217,7 @@ TaosResult 对象可以通过循环遍历获取查询到的数据。 - `reqId`: 用于问题追踪。 - **异常**:操作失败抛出 `DataError` 或 `OperationalError` 异常。 -### 参数绑定 +#### 参数绑定 - `fn statement(&self) -> PyResult` - **接口说明**:使用 连接 对象创建 stmt 对象。 - **返回值**:stmt 对象。 @@ -261,7 +255,7 @@ TaosResult 对象可以通过循环遍历获取查询到的数据。 - `fn close(&self) -> PyResult<()>` - **接口说明**: 关闭 stmt 对象。 -### 数据订阅 +#### 数据订阅 - **创建消费者支持属性列表**: - host:主机地址。 - port:端口号。 @@ -327,10 +321,10 @@ TaosResult 对象可以通过循环遍历获取查询到的数据。 - `fn close(&mut self)` - **接口说明**:关闭 tmq 连接。 - **异常**:操作失败抛出 ConsumerException 异常。 - - -### 建立连接 +### Native 连接 + +#### 建立连接 - `def connect(*args, **kwargs):` - **接口说明**:建立 taosAdapter 连接。 @@ -348,8 +342,7 @@ TaosResult 对象可以通过循环遍历获取查询到的数据。 - **接口说明**:创建一个新的数据库游标对象,用于执行SQL命令和查询。 - **返回值**:数据库游标对象。 - -### 执行SQL +#### 执行SQL - `def execute(self, operation, req_id: Optional[int] = None)` - **接口说明**:执行 sql 语句。 @@ -366,7 +359,7 @@ TaosResult 对象可以通过循环遍历获取查询到的数据。 - **返回值**:`TaosResult` 数据集对象。 - **异常**:操作失败抛出 `ProgrammingError` 异常。 -### 数据集 +#### 数据集 TaosResult 对象可以通过循环遍历获取查询到的数据。 @@ -380,7 +373,7 @@ TaosResult 对象可以通过循环遍历获取查询到的数据。 - **接口说明**:将所有的记录转换为字典。 - **返回值**:返回字典列表。 -### 无模式写入 +#### 无模式写入 - `def schemaless_insert(&self, lines: List[str], protocol: SmlProtocol, precision: SmlPrecision, req_id: Optional[int] = None, ttl: Optional[int] = None) -> int:` - **接口说明**:无模式写入。 - **参数说明**: @@ -401,7 +394,7 @@ TaosResult 对象可以通过循环遍历获取查询到的数据。 - **返回值**:影响的条数。 - **异常**:操作失败抛出 `SchemalessError` 异常。 -### 参数绑定 +#### 参数绑定 - `def statement(self, sql=None)` - **接口说明**:使用连接对象创建 stmt 对象, 如果 sql 不空会进行调用 prepare。 - `sql`: 预编译的 SQL 语句。 @@ -447,7 +440,7 @@ TaosResult 对象可以通过循环遍历获取查询到的数据。 - `def close(&self)` - **接口说明**: 关闭 stmt 对象。 -### 数据订阅 +#### 数据订阅 - **创建消费者支持属性列表**: - td.connect.ip:主机地址。 - td.connect.port:端口号。 @@ -515,8 +508,9 @@ TaosResult 对象可以通过循环遍历获取查询到的数据。 - `def close(self)` - **接口说明**:关闭 tmq 连接。 - **异常**:操作失败抛出 TmqError 异常。 - - + +### REST 连接 + - `def connect(**kwargs) -> TaosRestConnection` - **接口说明**:建立 taosAdapter 连接。 - **参数说明**: @@ -562,5 +556,3 @@ TaosResult 对象可以通过循环遍历获取查询到的数据。 - `reqId`: 用于问题追踪。 - **返回值**:返回字典列表。 - **异常**:操作失败抛出 `ConnectError` 或 `HTTPError` 异常。 - - From 709c31dbc414d0d4dbd4506e818a14eb128ecac0 Mon Sep 17 00:00:00 2001 From: menshibin Date: Thu, 1 Aug 2024 21:07:55 +0800 Subject: [PATCH 12/14] modify python api --- docs/examples/python/connect_example.py | 25 +++++--- .../python/connect_websocket_examples.py | 61 +++++++++++++------ docs/zh/08-develop/02-sql.md | 2 + 3 files changed, 62 insertions(+), 26 deletions(-) diff --git a/docs/examples/python/connect_example.py b/docs/examples/python/connect_example.py index c31e1cac51..493cd512ee 100644 --- a/docs/examples/python/connect_example.py +++ b/docs/examples/python/connect_example.py @@ -1,14 +1,21 @@ import taos -def test_connection(): +def create_connection(): # all parameters are optional. - conn = taos.connect(host="localhost", - port=6030, - user="root", - password="taosdata") - print('client info:', conn.client_info) - print('server info:', conn.server_info) - conn.close() + conn = None + try: + conn = taosws.connect( + user="root", + password="taosdata", + host="192.168.1.98", + port=6041, + ) + except Exception as err: + print(f'Exception {err}') + finally: + if conn: + conn.close() + if __name__ == "__main__": - test_connection() + create_connection() diff --git a/docs/examples/python/connect_websocket_examples.py b/docs/examples/python/connect_websocket_examples.py index 75e7422a90..1446bdf120 100644 --- a/docs/examples/python/connect_websocket_examples.py +++ b/docs/examples/python/connect_websocket_examples.py @@ -1,26 +1,53 @@ -# ANCHOR: connect import taosws -conn = taosws.connect("taosws://root:taosdata@localhost:6041") +def create_connection(): + conn = None +# ANCHOR: connect + try: + conn = taosws.connect( + user="root", + password="taosdata", + host="localhost", + port=6041, + ) + except Exception as err: + print(f'Exception {err}') # ANCHOR_END: connect + return conn -# ANCHOR: basic -conn.execute("drop database if exists connwspy") -conn.execute("create database if not exists connwspy wal_retention_period 3600 keep 36500 ") -conn.execute("use connwspy") -conn.execute("create table if not exists stb (ts timestamp, c1 int) tags (t1 int)") -conn.execute("create table if not exists tb1 using stb tags (1)") -conn.execute("insert into tb1 values (now, 1)") -conn.execute("insert into tb1 values (now+1s, 2)") -conn.execute("insert into tb1 values (now+2s, 3)") +def create_db_table(conn): +# ANCHOR: create_db + try: + conn.execute("CREATE DATABASE IF NOT EXISTS power") + conn.execute("USE power") + conn.execute("CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))") + conn.execute("CREATE TABLE `d0` USING `meters` TAGS(0, 'Los Angles')") + except Exception as err: + print(f'Exception {err}') +# ANCHOR_END: create_db -r = conn.execute("select * from stb") -result = conn.query("select * from stb") -num_of_fields = result.field_count -print(num_of_fields) +def insert(conn): + sql = """ + INSERT INTO + power.d1001 USING power.meters TAGS('California.SanFrancisco', 2) + VALUES (NOW + 1a, 10.30000, 219, 0.31000) + (NOW + 2a, 12.60000, 218, 0.33000) (NOW + 3a, 12.30000, 221, 0.31000) + power.d1002 USING power.meters TAGS('California.SanFrancisco', 3) + VALUES (NOW + 1a, 10.30000, 218, 0.25000) + """ + try: + inserted = conn.execute(sql) + assert inserted == 8 + except Exception as err: + print(f'Exception {err}') -for row in result: - print(row) +def query(conn): + result = conn.query("select * from stb") + num_of_fields = result.field_count + print(num_of_fields) + + for row in result: + print(row) # output: # 3 diff --git a/docs/zh/08-develop/02-sql.md b/docs/zh/08-develop/02-sql.md index 105b42d120..7b4c6e5d98 100644 --- a/docs/zh/08-develop/02-sql.md +++ b/docs/zh/08-develop/02-sql.md @@ -25,6 +25,8 @@ TDengine 对 SQL 语言提供了全面的支持,允许用户以熟悉的 SQL +- Websocket 连接 + From cbf666b529fd80ea72a91ee3fd17ff2c454f45ba Mon Sep 17 00:00:00 2001 From: sheyanjie-qq <249478495@qq.com> Date: Thu, 1 Aug 2024 21:15:53 +0800 Subject: [PATCH 13/14] mod tmq example --- docs/zh/08-develop/07-tmq.md | 66 +--- .../com/taosdata/example/AbsConsumerLoop.java | 2 +- .../taosdata/example/AbsConsumerLoopFull.java | 142 ------- .../taosdata/example/AbsWsConsumerLoop.java | 144 ------- .../taosdata/example/ConsumerLoopFull.java | 357 +++++++++++++++++ .../example/ParameterBindingBasicDemo.java | 44 ++- .../example/ParameterBindingBatchDemo.java | 83 ---- .../taosdata/example/WsConsumerLoopFull.java | 358 ++++++++++++++++++ 8 files changed, 764 insertions(+), 432 deletions(-) delete mode 100644 examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoopFull.java delete mode 100644 examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsWsConsumerLoop.java create mode 100644 examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ConsumerLoopFull.java delete mode 100644 examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ParameterBindingBatchDemo.java create mode 100644 examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WsConsumerLoopFull.java diff --git a/docs/zh/08-develop/07-tmq.md b/docs/zh/08-develop/07-tmq.md index 16a538757f..1d5b59307e 100644 --- a/docs/zh/08-develop/07-tmq.md +++ b/docs/zh/08-develop/07-tmq.md @@ -85,7 +85,7 @@ Java 连接器创建消费者的参数为 Properties, 可以设置的参数列 ```java -{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsWsConsumerLoop.java:create_consumer}} +{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WsConsumerLoopFull.java:create_consumer}} ``` @@ -135,7 +135,7 @@ Java 连接器创建消费者的参数为 Properties, 可以设置的参数列 ```java -{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoop.java:create_consumer}} +{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ConsumerLoopFull.java:create_consumer}} ``` @@ -180,7 +180,7 @@ Java 连接器创建消费者的参数为 Properties, 可以设置的参数列 ```java -{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoop.java:poll_data_code_piece}} +{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WsConsumerLoopFull.java:poll_data_code_piece}} ``` - `subscribe` 方法的参数含义为:订阅的主题列表(即名称),支持同时订阅多个主题。 @@ -273,33 +273,7 @@ Java 连接器创建消费者的参数为 Properties, 可以设置的参数列 ```java - -// 获取当前消费者分配的 TopicPartition 集合 -Set assignment() throws SQLException; - -// 获取指定分区的当前偏移量 -long position(TopicPartition partition) throws SQLException; -// 获取指定主题的所有分区的当前偏移量 -Map position(String topic) throws SQLException; -// 获取指定主题的所有分区的起始偏移量 -Map beginningOffsets(String topic) throws SQLException; -// 获取指定主题的所有分区的最新偏移量 -Map endOffsets(String topic) throws SQLException; -// 获取指定分区集合中的已提交偏移量 -Map committed(Set partitions) throws SQLException; - -// 设置指定分区的偏移量 -void seek(TopicPartition partition, long offset) throws SQLException; -// 将指定分区集合的偏移量设置为最开始 -void seekToBeginning(Collection partitions) throws SQLException; -// 将指定分区集合的偏移量设置为最新 -void seekToEnd(Collection partitions) throws SQLException; -``` - -示例代码: - -```java -{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ConsumerOffsetSeek.java:consumer_seek}} +{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WsConsumerLoopFull.java:consumer_seek}} ``` @@ -344,7 +318,6 @@ void seekToEnd(Collection partitions) throws SQLException; - 同 Websocket 代码样例。 @@ -389,22 +362,9 @@ void seekToEnd(Collection partitions) throws SQLException; -```java -// 同步提交当前消费者的偏移量 -void commitSync() throws SQLException; -// 同步提交指定的偏移量 -void commitSync(Map offsets) throws SQLException; - -// 异步提交仅在 native 连接下有效 -// 异步提交当前消费者的偏移量,需要提供回调以处理可能的提交结果 -void commitAsync(OffsetCommitCallback callback) throws SQLException; -// 异步提交指定的偏移量,需要提供回调以处理可能的提交结果 -void commitAsync(Map offsets, OffsetCommitCallback callback) throws SQLException; -``` - ```java -{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoop.java:commit_code_piece}} +{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WsConsumerLoopFull.java:commit_code_piece}} ``` @@ -501,7 +461,7 @@ void commitAsync(Map offsets, OffsetCommitCal ```java -{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoop.java:unsubscribe_data_code_piece}} +{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WsConsumerLoopFull.java:unsubscribe_data_code_piece}} ``` @@ -593,12 +553,14 @@ void commitAsync(Map offsets, OffsetCommitCal ### Websocket 连接 +
+完整 Websocket 连接代码示例 ```java -{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsWsConsumerLoop.java:consumer_demo}} +{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WsConsumerLoopFull.java:consumer_demo}} ``` **注意**:这里的 value.deserializer 配置参数值应该根据测试环境的包路径做相应的调整。 -其余代码请参考: [JDBC example](https://github.com/taosdata/TDengine/tree/3.0/examples/JDBC/JDBCDemo) +
@@ -641,12 +603,16 @@ void commitAsync(Map offsets, OffsetCommitCal ### 原生连接 +
+完整原生连接代码示例 ```java -{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoopFull.java:consumer_demo}} +{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ConsumerLoopFull.java:consumer_demo}} ``` **注意**:这里的 value.deserializer 配置参数值应该根据测试环境的包路径做相应的调整。 -其余代码请参考: [JDBC example](https://github.com/taosdata/TDengine/tree/3.0/examples/JDBC/JDBCDemo) +
+ +
diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoop.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoop.java index 90e6a950cd..f7570c742a 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoop.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoop.java @@ -32,7 +32,7 @@ config.setProperty("msg.with.table.name", "true"); config.setProperty("enable.auto.commit", "true"); config.setProperty("auto.commit.interval.ms", "1000"); config.setProperty("group.id", "group1"); -config.setProperty("client.id", "1"); +config.setProperty("client.id", "client1"); config.setProperty("value.deserializer", "com.taosdata.example.AbsConsumerLoop$ResultDeserializer"); config.setProperty("value.deserializer.encoding", "UTF-8"); try { diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoopFull.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoopFull.java deleted file mode 100644 index bd8f1799f6..0000000000 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoopFull.java +++ /dev/null @@ -1,142 +0,0 @@ -package com.taosdata.example; - -import com.taosdata.jdbc.tmq.ConsumerRecord; -import com.taosdata.jdbc.tmq.ConsumerRecords; -import com.taosdata.jdbc.tmq.ReferenceDeserializer; -import com.taosdata.jdbc.tmq.TaosConsumer; - -import java.sql.SQLException; -import java.sql.Timestamp; -import java.time.Duration; -import java.util.Collections; -import java.util.List; -import java.util.Properties; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.atomic.AtomicBoolean; - -// ANCHOR: consumer_demo -public abstract class AbsConsumerLoopFull { - private final TaosConsumer consumer; - private final List topics; - private final AtomicBoolean shutdown; - private final CountDownLatch shutdownLatch; - - public AbsConsumerLoopFull() throws SQLException { - - Properties config = new Properties(); - config.setProperty("td.connect.type", "jni"); - config.setProperty("bootstrap.servers", "localhost:6030"); - config.setProperty("auto.offset.reset", "latest"); - config.setProperty("msg.with.table.name", "true"); - config.setProperty("enable.auto.commit", "true"); - config.setProperty("auto.commit.interval.ms", "1000"); - config.setProperty("group.id", "group1"); - config.setProperty("client.id", "1"); - config.setProperty("value.deserializer", "com.taosdata.example.AbsConsumerLoop$ResultDeserializer"); - config.setProperty("value.deserializer.encoding", "UTF-8"); - - try { - this.consumer = new TaosConsumer<>(config); - } catch (SQLException ex) { - // handle any errors, please refer to the JDBC specifications for detailed exceptions info - System.out.println("Failed to create jni consumer, host : " + config.getProperty("bootstrap.servers") + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); - throw new SQLException("Failed to create consumer", ex); - } - - this.topics = Collections.singletonList("topic_meters"); - this.shutdown = new AtomicBoolean(false); - this.shutdownLatch = new CountDownLatch(1); - } - - public abstract void process(ResultBean result); - - public void pollData() throws SQLException { - try { - // subscribe to the topics - consumer.subscribe(topics); - while (!shutdown.get()) { - // poll data - ConsumerRecords records = consumer.poll(Duration.ofMillis(100)); - for (ConsumerRecord record : records) { - ResultBean bean = record.value(); - // process the data here - process(bean); - } - } - // unsubscribe the topics - consumer.unsubscribe(); - } finally { - // close the consumer - consumer.close(); - shutdownLatch.countDown(); - } - } - - public void shutdown() throws InterruptedException { - shutdown.set(true); - shutdownLatch.await(); - } - - public static class ResultDeserializer extends ReferenceDeserializer { - - } - - // use this class to define the data structure of the result record - public static class ResultBean { - private Timestamp ts; - private double current; - private int voltage; - private double phase; - private int groupid; - private String location; - - public Timestamp getTs() { - return ts; - } - - public void setTs(Timestamp ts) { - this.ts = ts; - } - - public double getCurrent() { - return current; - } - - public void setCurrent(double current) { - this.current = current; - } - - public int getVoltage() { - return voltage; - } - - public void setVoltage(int voltage) { - this.voltage = voltage; - } - - public double getPhase() { - return phase; - } - - public void setPhase(double phase) { - this.phase = phase; - } - - public int getGroupid() { - return groupid; - } - - public void setGroupid(int groupid) { - this.groupid = groupid; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - } -} -// ANCHOR_END: consumer_demo diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsWsConsumerLoop.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsWsConsumerLoop.java deleted file mode 100644 index 60466629f6..0000000000 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsWsConsumerLoop.java +++ /dev/null @@ -1,144 +0,0 @@ -package com.taosdata.example; - -import com.taosdata.jdbc.tmq.ConsumerRecord; -import com.taosdata.jdbc.tmq.ConsumerRecords; -import com.taosdata.jdbc.tmq.ReferenceDeserializer; -import com.taosdata.jdbc.tmq.TaosConsumer; - -import java.sql.SQLException; -import java.sql.Timestamp; -import java.time.Duration; -import java.util.Collections; -import java.util.List; -import java.util.Properties; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.atomic.AtomicBoolean; - -// ANCHOR: consumer_demo -public abstract class AbsWsConsumerLoop { - private final TaosConsumer consumer; - private final List topics; - private final AtomicBoolean shutdown; - private final CountDownLatch shutdownLatch; - - public AbsWsConsumerLoop() throws SQLException { -// ANCHOR: create_consumer -Properties config = new Properties(); -config.setProperty("td.connect.type", "ws"); -config.setProperty("bootstrap.servers", "localhost:6041"); -config.setProperty("auto.offset.reset", "latest"); -config.setProperty("msg.with.table.name", "true"); -config.setProperty("enable.auto.commit", "true"); -config.setProperty("auto.commit.interval.ms", "1000"); -config.setProperty("group.id", "group1"); -config.setProperty("client.id", "client1"); -config.setProperty("value.deserializer", "com.taosdata.example.AbsConsumerLoopWs$ResultDeserializer"); -config.setProperty("value.deserializer.encoding", "UTF-8"); - -try { - this.consumer = new TaosConsumer<>(config); -} catch (SQLException ex) { - // handle any errors, please refer to the JDBC specifications for detailed exceptions info - System.out.println("Failed to create ws consumer with " + config.getProperty("bootstrap.servers") + " ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); - throw new SQLException("Failed to create consumer", ex); -} -// ANCHOR_END: create_consumer - - this.topics = Collections.singletonList("topic_meters"); - this.shutdown = new AtomicBoolean(false); - this.shutdownLatch = new CountDownLatch(1); - } - - public abstract void process(ResultBean result); - - public void pollData() throws SQLException { - try { - // Subscribe to the topic - consumer.subscribe(topics); - - while (!shutdown.get()) { - // poll data - ConsumerRecords records = consumer.poll(Duration.ofMillis(100)); - for (ConsumerRecord record : records) { - ResultBean bean = record.value(); - // process data here - process(bean); - } - } - // unsubscribe the topics - consumer.unsubscribe(); - } finally { - // close the consumer - consumer.close(); - shutdownLatch.countDown(); - } - } - - public void shutdown() throws InterruptedException { - shutdown.set(true); - shutdownLatch.await(); - } - - public static class ResultDeserializer extends ReferenceDeserializer { - - } - - // use this class to define the data structure of the result record - public static class ResultBean { - private Timestamp ts; - private double current; - private int voltage; - private double phase; - private int groupid; - private String location; - - public Timestamp getTs() { - return ts; - } - - public void setTs(Timestamp ts) { - this.ts = ts; - } - - public double getCurrent() { - return current; - } - - public void setCurrent(double current) { - this.current = current; - } - - public int getVoltage() { - return voltage; - } - - public void setVoltage(int voltage) { - this.voltage = voltage; - } - - public double getPhase() { - return phase; - } - - public void setPhase(double phase) { - this.phase = phase; - } - - public int getGroupid() { - return groupid; - } - - public void setGroupid(int groupid) { - this.groupid = groupid; - } - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - } -} -// ANCHOR_END: consumer_demo diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ConsumerLoopFull.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ConsumerLoopFull.java new file mode 100644 index 0000000000..4012f2e679 --- /dev/null +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ConsumerLoopFull.java @@ -0,0 +1,357 @@ +package com.taosdata.example; + +import com.alibaba.fastjson.JSON; +import com.taosdata.jdbc.TSDBDriver; +import com.taosdata.jdbc.tmq.*; + +import java.sql.*; +import java.time.Duration; +import java.util.*; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +// ANCHOR: consumer_demo +public class ConsumerLoopFull { + static private Connection connection; + static private Statement statement; + public static TaosConsumer getConsumer() throws SQLException{ +// ANCHOR: create_consumer +Properties config = new Properties(); +config.setProperty("td.connect.type", "jni"); +config.setProperty("bootstrap.servers", "localhost:6030"); +config.setProperty("auto.offset.reset", "latest"); +config.setProperty("msg.with.table.name", "true"); +config.setProperty("enable.auto.commit", "true"); +config.setProperty("auto.commit.interval.ms", "1000"); +config.setProperty("group.id", "group1"); +config.setProperty("client.id", "1"); +config.setProperty("td.connect.user", "root"); +config.setProperty("td.connect.pass", "taosdata"); +config.setProperty("value.deserializer", "com.taosdata.example.ConsumerLoopFull$ResultDeserializer"); +config.setProperty("value.deserializer.encoding", "UTF-8"); + +try { + return new TaosConsumer<>(config); +} catch (SQLException ex) { + // handle any errors, please refer to the JDBC specifications for detailed exceptions info + System.out.println("Failed to create jni consumer, host : " + config.getProperty("bootstrap.servers") + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + throw new SQLException("Failed to create consumer", ex); +} catch (Exception e) { + e.printStackTrace(); + throw new SQLException("Failed to create consumer", e); +} +// ANCHOR_END: create_consumer + } + + public static void pollDataExample() throws SQLException { + try (TaosConsumer consumer = getConsumer()){ + // subscribe to the topics + List topics = Collections.singletonList("topic_meters"); + + consumer.subscribe(topics); + System.out.println("subscribe topics successfully"); + for (int i = 0; i < 50; i++) { + // poll data + ConsumerRecords records = consumer.poll(Duration.ofMillis(100)); + for (ConsumerRecord record : records) { + ResultBean bean = record.value(); + // process the data here + System.out.println("data: " + JSON.toJSONString(bean)); + } + } + // unsubscribe the topics + consumer.unsubscribe(); + System.out.println("unsubscribed topics successfully"); + } catch (SQLException ex) { + // handle any errors, please refer to the JDBC specifications for detailed exceptions info + System.out.println("Failed to poll data from topic_meters, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + throw new SQLException("Failed to poll data from topic_meters", ex); + } + } + + public static void pollExample() throws SQLException { +// ANCHOR: poll_data_code_piece +try (TaosConsumer consumer = getConsumer()){ + List topics = Collections.singletonList("topic_meters"); + + // subscribe to the topics + consumer.subscribe(topics); + System.out.println("subscribe topics successfully"); + for (int i = 0; i < 50; i++) { + // poll data + ConsumerRecords records = consumer.poll(Duration.ofMillis(100)); + for (ConsumerRecord record : records) { + ResultBean bean = record.value(); + // process the data here + System.out.println("data: " + JSON.toJSONString(bean)); + } + } + +} catch (SQLException ex) { + // handle any errors, please refer to the JDBC specifications for detailed exceptions info + System.out.println("Failed to poll data; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + throw new SQLException("Failed to poll data", ex); +} +// ANCHOR_END: poll_data_code_piece +} + + public static void seekExample() throws SQLException { +// ANCHOR: consumer_seek +try (TaosConsumer consumer = getConsumer()){ + List topics = Collections.singletonList("topic_meters"); + + // subscribe to the topics + consumer.subscribe(topics); + System.out.println("subscribe topics successfully"); + ConsumerRecords records = ConsumerRecords.emptyRecord(); + // make sure we have got some data + while (records.isEmpty()){ + records = consumer.poll(Duration.ofMillis(100)); + } + + for (ConsumerRecord record : records) { + System.out.println("first data polled: " + JSON.toJSONString(record.value())); + Set assignment = consumer.assignment(); + // seek to the beginning of the all partitions + consumer.seekToBeginning(assignment); + System.out.println("assignment seek to beginning successfully"); + break; + } + + // poll data agagin + records = consumer.poll(Duration.ofMillis(100)); + for (ConsumerRecord record : records) { + // process the data here + System.out.println("second data polled: " + JSON.toJSONString(record.value())); + break; + } + + +} catch (SQLException ex) { + // handle any errors, please refer to the JDBC specifications for detailed exceptions info + System.out.println("seek example failed; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + throw new SQLException("seek example failed", ex); +} +// ANCHOR_END: consumer_seek + } + + + public static void commitExample() throws SQLException { +// ANCHOR: commit_code_piece +try (TaosConsumer consumer = getConsumer()){ + List topics = Collections.singletonList("topic_meters"); + + consumer.subscribe(topics); + for (int i = 0; i < 50; i++) { + ConsumerRecords records = consumer.poll(Duration.ofMillis(100)); + for (ConsumerRecord record : records) { + ResultBean bean = record.value(); + // process your data here + System.out.println("data: " + JSON.toJSONString(bean)); + } + if (!records.isEmpty()) { + // after processing the data, commit the offset manually + consumer.commitSync(); + } + } +} catch (SQLException ex){ + // handle any errors, please refer to the JDBC specifications for detailed exceptions info + System.out.println("Failed to execute consumer functions. ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + throw new SQLException("Failed to execute consumer functions", ex); +} +// ANCHOR_END: commit_code_piece + } + public static void unsubscribeExample() throws SQLException { + TaosConsumer consumer = getConsumer(); + List topics = Collections.singletonList("topic_meters"); + consumer.subscribe(topics); +// ANCHOR: unsubscribe_data_code_piece + try { + consumer.unsubscribe(); + } catch (SQLException ex){ + // handle any errors, please refer to the JDBC specifications for detailed exceptions info + System.out.println("Failed to unsubscribe consumer. ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + throw new SQLException("Failed to unsubscribe consumer", ex); + } finally { + consumer.close(); + } +// ANCHOR_END: unsubscribe_data_code_piece + } + + public static class ResultDeserializer extends ReferenceDeserializer { + + } + // use this class to define the data structure of the result record + public static class ResultBean { + private Timestamp ts; + private double current; + private int voltage; + private double phase; + private int groupid; + private String location; + + public Timestamp getTs() { + return ts; + } + + public void setTs(Timestamp ts) { + this.ts = ts; + } + + public double getCurrent() { + return current; + } + + public void setCurrent(double current) { + this.current = current; + } + + public int getVoltage() { + return voltage; + } + + public void setVoltage(int voltage) { + this.voltage = voltage; + } + + public double getPhase() { + return phase; + } + + public void setPhase(double phase) { + this.phase = phase; + } + + public int getGroupid() { + return groupid; + } + + public void setGroupid(int groupid) { + this.groupid = groupid; + } + + public String getLocation() { + return location; + } + + public void setLocation(String location) { + this.location = location; + } + } + + public static void prepareData() throws SQLException{ + StringBuilder insertQuery = new StringBuilder(); + insertQuery.append("INSERT INTO " + + "power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " + + "VALUES "); + for (int i = 0; i < 10000; i++){ + insertQuery.append("(NOW + ").append(i).append("a, 10.30000, 219, 0.31000) "); + } + try { + int affectedRows = statement.executeUpdate(insertQuery.toString()); + assert affectedRows == 10000; + } catch (SQLException ex) { + System.out.println("Failed to insert data to power.meters, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + throw new SQLException("Failed to insert data to power.meters", ex); + } + } + public static void prepareMeta() throws SQLException{ + try { + statement.executeUpdate("CREATE DATABASE IF NOT EXISTS power"); + statement.executeUpdate("USE power"); + statement.executeUpdate("CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); + statement.executeUpdate("CREATE TOPIC IF NOT EXISTS topic_meters AS SELECT ts, current, voltage, phase, groupid, location FROM meters"); + } catch (SQLException ex) { + System.out.println("Failed to create db and table, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + throw new SQLException("Failed to create db and table", ex); + } + } + + public static void initConnection() throws SQLException { + String url = "jdbc:TAOS://localhost:6030?user=root&password=taosdata"; + Properties properties = new Properties(); + properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "C"); + properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); + + try { + connection = DriverManager.getConnection(url, properties); + } catch (SQLException ex) { + System.out.println("Failed to create connection, url:" + url + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + throw new SQLException("Failed to create connection", ex); + } + try { + statement = connection.createStatement(); + } catch (SQLException ex) { + System.out.println("Failed to create statement, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + throw new SQLException("Failed to create statement", ex); + } + System.out.println("Connection created successfully."); + } + public static void closeConnection() throws SQLException { + try { + if (statement != null) { + statement.close(); + } + } catch (SQLException ex) { + System.out.println("Failed to close statement, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + throw new SQLException("Failed to close statement", ex); + } + + try { + if (connection != null) { + connection.close(); + } + } catch (SQLException ex) { + System.out.println("Failed to close connection, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + throw new SQLException("Failed to close connection", ex); + } + System.out.println("Connection closed Successfully."); + } + + + public static void main(String[] args) throws SQLException { + initConnection(); + prepareMeta(); + + // create a single thread executor + ExecutorService executor = Executors.newSingleThreadExecutor(); + + // submit a task + executor.submit(() -> { + try { + // please use one example at a time + pollDataExample(); +// seekExample(); +// pollExample(); +// commitExample(); + unsubscribeExample(); + } catch (SQLException ex) { + System.out.println("Failed to poll data from topic_meters, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + } + System.out.println("pollDataExample executed successfully"); + }); + + prepareData(); + closeConnection(); + + System.out.println("Data prepared successfully"); + + // 关闭线程池,不再接收新任务 + executor.shutdown(); + + try { + // 等待直到所有任务完成 + boolean result = executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); + assert result; + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } catch (Exception e){ + e.printStackTrace(); + System.out.println("Wait executor termination failed."); + } + + System.out.println("program end."); + } +} +// ANCHOR_END: consumer_demo diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ParameterBindingBasicDemo.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ParameterBindingBasicDemo.java index 469316efc7..fa2efab2ee 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ParameterBindingBasicDemo.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ParameterBindingBasicDemo.java @@ -2,7 +2,10 @@ package com.taosdata.example; import com.taosdata.jdbc.TSDBPreparedStatement; -import java.sql.*; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.sql.Statement; import java.util.ArrayList; import java.util.Random; @@ -24,6 +27,7 @@ public class ParameterBindingBasicDemo { String sql = "INSERT INTO ? USING meters TAGS(?,?) VALUES (?,?,?,?)"; try (TSDBPreparedStatement pstmt = conn.prepareStatement(sql).unwrap(TSDBPreparedStatement.class)) { + for (int i = 1; i <= numOfSubTable; i++) { // set table name pstmt.setTableName("d_bind_" + i); @@ -32,19 +36,35 @@ public class ParameterBindingBasicDemo { pstmt.setTagInt(0, i); pstmt.setTagString(1, "location_" + i); - // set columns + // set column ts + ArrayList tsList = new ArrayList<>(); long current = System.currentTimeMillis(); - for (int j = 0; j < numOfRow; j++) { - pstmt.setTimestamp(1, new Timestamp(current + j)); - pstmt.setFloat(2, random.nextFloat() * 30); - pstmt.setInt(3, random.nextInt(300)); - pstmt.setFloat(4, random.nextFloat()); - pstmt.addBatch(); - } - int [] exeResult = pstmt.executeBatch(); - // you can check exeResult here - System.out.println("insert " + exeResult.length + " rows."); + for (int j = 0; j < numOfRow; j++) + tsList.add(current + j); + pstmt.setTimestamp(0, tsList); + + // set column current + ArrayList currentList = new ArrayList<>(); + for (int j = 0; j < numOfRow; j++) + currentList.add(random.nextFloat() * 30); + pstmt.setFloat(1, currentList); + + // set column voltage + ArrayList voltageList = new ArrayList<>(); + for (int j = 0; j < numOfRow; j++) + voltageList.add(random.nextInt(300)); + pstmt.setInt(2, voltageList); + + // set column phase + ArrayList phaseList = new ArrayList<>(); + for (int j = 0; j < numOfRow; j++) + phaseList.add(random.nextFloat()); + pstmt.setFloat(3, phaseList); + // add column + pstmt.columnDataAddBatch(); } + // execute column + pstmt.columnDataExecuteBatch(); } } catch (SQLException ex) { // handle any errors, please refer to the JDBC specifications for detailed exceptions info diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ParameterBindingBatchDemo.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ParameterBindingBatchDemo.java deleted file mode 100644 index 60d76eee4f..0000000000 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ParameterBindingBatchDemo.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.taosdata.example; - -import com.taosdata.jdbc.TSDBPreparedStatement; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.Random; - -// ANCHOR: para_bind -public class ParameterBindingBatchDemo { - - // modify host to your own - private static final String host = "127.0.0.1"; - private static final Random random = new Random(System.currentTimeMillis()); - private static final int numOfSubTable = 10, numOfRow = 10; - - public static void main(String[] args) throws SQLException { - - String jdbcUrl = "jdbc:TAOS://" + host + ":6030/"; - try (Connection conn = DriverManager.getConnection(jdbcUrl, "root", "taosdata")) { - - init(conn); - - String sql = "INSERT INTO ? USING meters TAGS(?,?) VALUES (?,?,?,?)"; - - try (TSDBPreparedStatement pstmt = conn.prepareStatement(sql).unwrap(TSDBPreparedStatement.class)) { - - for (int i = 1; i <= numOfSubTable; i++) { - // set table name - pstmt.setTableName("d_bind_" + i); - - // set tags - pstmt.setTagInt(0, i); - pstmt.setTagString(1, "location_" + i); - - // set column ts - ArrayList tsList = new ArrayList<>(); - long current = System.currentTimeMillis(); - for (int j = 0; j < numOfRow; j++) - tsList.add(current + j); - pstmt.setTimestamp(0, tsList); - - // set column current - ArrayList f1List = new ArrayList<>(); - for (int j = 0; j < numOfRow; j++) - f1List.add(random.nextFloat() * 30); - pstmt.setFloat(1, f1List); - - // set column voltage - ArrayList f2List = new ArrayList<>(); - for (int j = 0; j < numOfRow; j++) - f2List.add(random.nextInt(300)); - pstmt.setInt(2, f2List); - - // set column phase - ArrayList f3List = new ArrayList<>(); - for (int j = 0; j < numOfRow; j++) - f3List.add(random.nextFloat()); - pstmt.setFloat(3, f3List); - // add column - pstmt.columnDataAddBatch(); - } - // execute column - pstmt.columnDataExecuteBatch(); - } - } catch (SQLException ex) { - // handle any errors, please refer to the JDBC specifications for detailed exceptions info - System.out.println("Failed to insert to table meters using stmt, url: " + jdbcUrl + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); - } - } - - private static void init(Connection conn) throws SQLException { - try (Statement stmt = conn.createStatement()) { - stmt.execute("CREATE DATABASE IF NOT EXISTS power"); - stmt.execute("USE power"); - stmt.execute("CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); - } - } -} -// ANCHOR_END: para_bind diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WsConsumerLoopFull.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WsConsumerLoopFull.java new file mode 100644 index 0000000000..d8084eb9f6 --- /dev/null +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WsConsumerLoopFull.java @@ -0,0 +1,358 @@ +package com.taosdata.example; + +import com.alibaba.fastjson.JSON; +import com.taosdata.jdbc.TSDBDriver; +import com.taosdata.jdbc.tmq.*; + +import java.sql.*; +import java.time.Duration; +import java.util.Collections; +import java.util.List; +import java.util.Properties; +import java.util.Set; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +// ANCHOR: consumer_demo +public class WsConsumerLoopFull { + static private Connection connection; + static private Statement statement; + public static TaosConsumer getConsumer() throws SQLException{ +// ANCHOR: create_consumer +Properties config = new Properties(); +config.setProperty("td.connect.type", "ws"); +config.setProperty("bootstrap.servers", "localhost:6041"); +config.setProperty("auto.offset.reset", "latest"); +config.setProperty("msg.with.table.name", "true"); +config.setProperty("enable.auto.commit", "true"); +config.setProperty("auto.commit.interval.ms", "1000"); +config.setProperty("group.id", "group1"); +config.setProperty("client.id", "client1"); +config.setProperty("td.connect.user", "root"); +config.setProperty("td.connect.pass", "taosdata"); +config.setProperty("value.deserializer", "com.taosdata.example.WsConsumerLoopFull$ResultDeserializer"); +config.setProperty("value.deserializer.encoding", "UTF-8"); + +try { + return new TaosConsumer<>(config); + } catch (SQLException ex) { + // handle any errors, please refer to the JDBC specifications for detailed exceptions info + System.out.println("Failed to create websocket consumer, host : " + config.getProperty("bootstrap.servers") + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + throw new SQLException("Failed to create consumer", ex); + } catch (Exception e) { + e.printStackTrace(); + throw new SQLException("Failed to create consumer", e); + } +// ANCHOR_END: create_consumer +} + + public static void pollDataExample() throws SQLException { + try (TaosConsumer consumer = getConsumer()){ + // subscribe to the topics + List topics = Collections.singletonList("topic_meters"); + + consumer.subscribe(topics); + System.out.println("subscribe topics successfully"); + for (int i = 0; i < 50; i++) { + // poll data + ConsumerRecords records = consumer.poll(Duration.ofMillis(100)); + for (ConsumerRecord record : records) { + ResultBean bean = record.value(); + // process the data here + System.out.println("data: " + JSON.toJSONString(bean)); + } + } + // unsubscribe the topics + consumer.unsubscribe(); + System.out.println("unsubscribed topics successfully"); + } catch (SQLException ex) { + // handle any errors, please refer to the JDBC specifications for detailed exceptions info + System.out.println("Failed to poll data from topic_meters, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + throw new SQLException("Failed to poll data from topic_meters", ex); + } + } + + public static void pollExample() throws SQLException { +// ANCHOR: poll_data_code_piece +try (TaosConsumer consumer = getConsumer()){ + List topics = Collections.singletonList("topic_meters"); + + // subscribe to the topics + consumer.subscribe(topics); + System.out.println("subscribe topics successfully"); + for (int i = 0; i < 50; i++) { + // poll data + ConsumerRecords records = consumer.poll(Duration.ofMillis(100)); + for (ConsumerRecord record : records) { + ResultBean bean = record.value(); + // process the data here + System.out.println("data: " + JSON.toJSONString(bean)); + } + } + +} catch (SQLException ex) { + // handle any errors, please refer to the JDBC specifications for detailed exceptions info + System.out.println("Failed to poll data; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + throw new SQLException("Failed to poll data", ex); +} +// ANCHOR_END: poll_data_code_piece + } + + public static void seekExample() throws SQLException { +// ANCHOR: consumer_seek +try (TaosConsumer consumer = getConsumer()){ + List topics = Collections.singletonList("topic_meters"); + + // subscribe to the topics + consumer.subscribe(topics); + System.out.println("subscribe topics successfully"); + ConsumerRecords records = ConsumerRecords.emptyRecord(); + // make sure we have got some data + while (records.isEmpty()){ + records = consumer.poll(Duration.ofMillis(100)); + } + + for (ConsumerRecord record : records) { + System.out.println("first data polled: " + JSON.toJSONString(record.value())); + Set assignment = consumer.assignment(); + // seek to the beginning of the all partitions + consumer.seekToBeginning(assignment); + System.out.println("assignment seek to beginning successfully"); + break; + } + + // poll data agagin + records = consumer.poll(Duration.ofMillis(100)); + for (ConsumerRecord record : records) { + // process the data here + System.out.println("second data polled: " + JSON.toJSONString(record.value())); + break; + } +} catch (SQLException ex) { + // handle any errors, please refer to the JDBC specifications for detailed exceptions info + System.out.println("seek example failed; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + throw new SQLException("seek example failed", ex); +} +// ANCHOR_END: consumer_seek + } + + + public static void commitExample() throws SQLException { +// ANCHOR: commit_code_piece +try (TaosConsumer consumer = getConsumer()){ + List topics = Collections.singletonList("topic_meters"); + + consumer.subscribe(topics); + for (int i = 0; i < 50; i++) { + ConsumerRecords records = consumer.poll(Duration.ofMillis(100)); + for (ConsumerRecord record : records) { + ResultBean bean = record.value(); + // process your data here + System.out.println("data: " + JSON.toJSONString(bean)); + } + if (!records.isEmpty()) { + // after processing the data, commit the offset manually + consumer.commitSync(); + } + } +} catch (SQLException ex){ + // handle any errors, please refer to the JDBC specifications for detailed exceptions info + System.out.println("Failed to execute consumer functions. ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + throw new SQLException("Failed to execute consumer functions", ex); +} +// ANCHOR_END: commit_code_piece + } + public static void unsubscribeExample() throws SQLException { + TaosConsumer consumer = getConsumer(); + List topics = Collections.singletonList("topic_meters"); + consumer.subscribe(topics); +// ANCHOR: unsubscribe_data_code_piece +try { + consumer.unsubscribe(); +} catch (SQLException ex){ + // handle any errors, please refer to the JDBC specifications for detailed exceptions info + System.out.println("Failed to unsubscribe consumer. ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + throw new SQLException("Failed to unsubscribe consumer", ex); +} finally { + consumer.close(); +} +// ANCHOR_END: unsubscribe_data_code_piece + } + +public static class ResultDeserializer extends ReferenceDeserializer { + +} +// use this class to define the data structure of the result record +public static class ResultBean { + private Timestamp ts; + private double current; + private int voltage; + private double phase; + private int groupid; + private String location; + + public Timestamp getTs() { + return ts; + } + + public void setTs(Timestamp ts) { + this.ts = ts; + } + + public double getCurrent() { + return current; + } + + public void setCurrent(double current) { + this.current = current; + } + + public int getVoltage() { + return voltage; + } + + public void setVoltage(int voltage) { + this.voltage = voltage; + } + + public double getPhase() { + return phase; + } + + public void setPhase(double phase) { + this.phase = phase; + } + + public int getGroupid() { + return groupid; + } + + public void setGroupid(int groupid) { + this.groupid = groupid; + } + + public String getLocation() { + return location; + } + + public void setLocation(String location) { + this.location = location; + } +} + + public static void prepareData() throws SQLException{ + StringBuilder insertQuery = new StringBuilder(); + insertQuery.append("INSERT INTO " + + "power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " + + "VALUES "); + for (int i = 0; i < 10000; i++){ + insertQuery.append("(NOW + ").append(i).append("a, 10.30000, 219, 0.31000) "); + } + try { + int affectedRows = statement.executeUpdate(insertQuery.toString()); + assert affectedRows == 10000; + } catch (SQLException ex) { + System.out.println("Failed to insert data to power.meters, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + throw new SQLException("Failed to insert data to power.meters", ex); + } + } + public static void prepareMeta() throws SQLException{ + try { + statement.executeUpdate("CREATE DATABASE IF NOT EXISTS power"); + statement.executeUpdate("USE power"); + statement.executeUpdate("CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); + statement.executeUpdate("CREATE TOPIC IF NOT EXISTS topic_meters AS SELECT ts, current, voltage, phase, groupid, location FROM meters"); + } catch (SQLException ex) { + System.out.println("Failed to create db and table, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + throw new SQLException("Failed to create db and table", ex); + } + } + + public static void initConnection() throws SQLException { + String url = "jdbc:TAOS://localhost:6030?user=root&password=taosdata"; + Properties properties = new Properties(); + properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "C"); + properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); + + try { + connection = DriverManager.getConnection(url, properties); + } catch (SQLException ex) { + System.out.println("Failed to create connection, url:" + url + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + throw new SQLException("Failed to create connection", ex); + } + try { + statement = connection.createStatement(); + } catch (SQLException ex) { + System.out.println("Failed to create statement, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + throw new SQLException("Failed to create statement", ex); + } + System.out.println("Connection created successfully."); + } + public static void closeConnection() throws SQLException { + try { + if (statement != null) { + statement.close(); + } + } catch (SQLException ex) { + System.out.println("Failed to close statement, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + throw new SQLException("Failed to close statement", ex); + } + + try { + if (connection != null) { + connection.close(); + } + } catch (SQLException ex) { + System.out.println("Failed to close connection, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + throw new SQLException("Failed to close connection", ex); + } + System.out.println("Connection closed Successfully."); + } + + + public static void main(String[] args) throws SQLException { + initConnection(); + prepareMeta(); + + // create a single thread executor + ExecutorService executor = Executors.newSingleThreadExecutor(); + + // submit a task + executor.submit(() -> { + try { + // please use one example at a time + pollDataExample(); +// seekExample(); +// pollExample(); +// commitExample(); + unsubscribeExample(); + } catch (SQLException ex) { + System.out.println("Failed to poll data from topic_meters, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + } + System.out.println("pollDataExample executed successfully"); + }); + + prepareData(); + closeConnection(); + + System.out.println("Data prepared successfully"); + + // 关闭线程池,不再接收新任务 + executor.shutdown(); + + try { + // 等待直到所有任务完成 + boolean result = executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); + assert result; + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } catch (Exception e){ + e.printStackTrace(); + System.out.println("Wait executor termination failed."); + } + + System.out.println("program end."); + } +} +// ANCHOR_END: consumer_demo From ef1884d675a2a227a9080380ebad3e7f0ab04cbf Mon Sep 17 00:00:00 2001 From: sheyanjie-qq <249478495@qq.com> Date: Fri, 2 Aug 2024 08:49:41 +0800 Subject: [PATCH 14/14] add rust api --- docs/zh/14-reference/05-connector/26-rust.mdx | 397 +++++++++++++++++- 1 file changed, 396 insertions(+), 1 deletion(-) diff --git a/docs/zh/14-reference/05-connector/26-rust.mdx b/docs/zh/14-reference/05-connector/26-rust.mdx index 2cdfdc9e41..f6c9e5d688 100644 --- a/docs/zh/14-reference/05-connector/26-rust.mdx +++ b/docs/zh/14-reference/05-connector/26-rust.mdx @@ -607,7 +607,402 @@ stmt.execute()?; 一个可运行的示例请见 [GitHub 上的示例](https://github.com/taosdata/taos-connector-rust/blob/main/examples/bind.rs)。 -其他相关结构体 API 使用说明请移步 Rust 文档托管网页:\。 +## API 参考 + +Rust 连接器的接口分为同步接口和异步接口,一般同步接口是由异步接口实现,方法签名除 async 关键字外基本相同。对于同步接口和异步接口功能一样的接口,本文档只提供同步接口的说明。 +对于 WebSocket 连接和原生连接两种方式,除了建立连接的 DSN 不同,其余接口调用没有区别。 + +### 连接功能 +#### DSN + +TaosBuilder 通过 DSN 连接描述字符串创建一个连接构造器。 +DSN 描述字符串基本结构如下: + +```text +[+]://[[:@]:][/][?=[&=]] +|------|------------|---|-----------|-----------|------|------|------------|-----------------------| +|driver| protocol | | username | password | host | port | database | params | +``` + +各部分意义见下表: + +- **driver**: 必须指定驱动名以便连接器选择何种方式创建连接,支持如下驱动名: + - **taos**: 表名使用 TDengine 连接器驱动。 + - **tmq**: 使用 TMQ 订阅数据。 + - **http/ws**: 使用 Websocket 创建连接。 + - **https/wss**: 在 Websocket 连接方式下显示启用 SSL/TLS 连接。 +- **protocol**: 显示指定以何种方式建立连接,例如:`taos+ws://localhost:6041` 指定以 Websocket 方式建立连接。 +- **username/password**: 用于创建连接的用户名及密码。 +- **host/port**: 指定创建连接的服务器及端口,当不指定服务器地址及端口时(`taos://`),原生连接默认为 `localhost:6030`,Websocket 连接默认为 `localhost:6041` 。 +- **database**: 指定默认连接的数据库名,可选参数。 +- **params**:其他可选参数。 + +一个完整的 DSN 描述字符串示例如下:`taos+ws://localhost:6041/test`, 表示使用 Websocket(`ws`)方式通过 `6041` 端口连接服务器 `localhost`,并指定默认数据库为 `test`。 + +#### TaosBuilder +TaosBuilder 结构体提供了建立连接,检查连接,以及获取服务端版本号等功能。 + +- `fn available_params() -> &'static [&'static str]` + - **接口说明**:获取DSN中可用的参数列表。 + - **返回值**:返回静态字符串切片的引用,包含可用的参数名称。 + +- `fn from_dsn(dsn: D) -> RawResult` + - **接口说明**:使用DSN字符串创建连接,不检查连接。 + - **参数说明**: + - `dsn`:DSN字符串或可转换为DSN的类型。 + - **返回值**:成功时返回自身类型的 `RawResult`,失败时返回错误。 + +- `fn client_version() -> &'static str` + - **接口说明**:获取客户端版本。 + - **返回值**:返回客户端版本的静态字符串。 + +- `fn ping(&self, _: &mut Self::Target) -> RawResult<()>` + - **接口说明**:检查连接是否仍然存活。 + - **参数说明**: + - `_`:目标连接的可变引用。 + - **返回值**:成功时返回空的 `RawResult`,失败时返回错误。 + +- `fn ready(&self) -> bool` + - **接口说明**:检查是否准备好连接。 + - **返回值**:大多数情况下返回true,表示地址准备好连接。 + +- `fn build(&self) -> RawResult` + - **接口说明**:从此结构创建新的连接。 + - **返回值**:成功时返回目标连接类型的 `RawResult`,失败时返回错误。 + +### 执行 SQL +执行 SQL 主要涉及到 Taos 结构体,以及结果集 ResultSet 结构体,还有列信息 Field。 +#### Taos +Taos 结构体提供了多个数据库操作的 API,包括:执行 SQL,无模式写入,以及一些常用数据库查询的封装(如创建数据库,获取) + +- `pub fn is_native(&self) -> bool` + - **接口说明**:判断连接是否使用本地协议。 + - **返回值**:如果使用本地协议,则返回 `true`,否则返回 `false`。 + +- `pub fn is_ws(&self) -> bool` + - **接口说明**:判断连接是否使用websocket协议。 + - **返回值**:如果使用websocket协议,则返回 `true`,否则返回 `false`。 + +- `fn query>(&self, sql: T) -> RawResult` + - **接口说明**:执行SQL查询。 + - **参数说明**: + - `sql`:要执行的SQL语句。 + - **返回值**:成功时返回结果集 `ResultSet` 的 `RawResult`,失败时返回错误。 + +- `fn query_with_req_id>(&self, sql: T, req_id: u64) -> RawResult` + - **接口说明**:带请求ID执行SQL查询。 + - **参数说明**: + - `sql`:要执行的SQL语句。 + - `req_id`:请求ID。 + - **返回值**:成功时返回结果集 `ResultSet` 的 `RawResult`,失败时返回错误。 + +- `fn exec>(&self, sql: T) -> RawResult` + - **接口说明**:执行SQL语句。 + - **参数说明**: + - `sql`:要执行的SQL语句。 + - **返回值**:成功时返回受影响的行数,失败时返回错误。 + +- `fn exec_many, I: IntoIterator>(&self, input: I) -> RawResult` + - **接口说明**:批量执行SQL语句。 + - **参数说明**: + - `input`:要执行的SQL语句集合。 + - **返回值**:成功时返回总共受影响的行数,失败时返回错误。 + +- `fn query_one, O: DeserializeOwned>(&self, sql: T) -> RawResult>` + - **接口说明**:执行SQL查询并返回单个结果。 + - **参数说明**: + - `sql`:要执行的SQL语句。 + - **返回值**:成功时返回可选的结果对象,失败时返回错误。 + +- `fn server_version(&self) -> RawResult>` + - **接口说明**:获取服务器版本。 + - **返回值**:成功时返回服务器版本字符串的 `RawResult`,失败时返回错误。 + +- `fn create_topic(&self, name: impl AsRef, sql: impl AsRef) -> RawResult<()>` + - **接口说明**:创建主题。 + - **参数说明**: + - `name`:主题名称。 + - `sql`:关联的SQL语句。 + - **返回值**:成功时返回空的 `RawResult`,失败时返回错误。 + +- `fn databases(&self) -> RawResult>` + - **接口说明**:获取数据库列表。 + - **返回值**:成功时返回数据库列表的 `RawResult`,失败时返回错误。 + +- `fn topics(&self) -> RawResult>` + - **接口说明**:获取主题信息。 + - **返回值**:成功时返回主题列表的 `RawResult`,失败时返回错误。 + +- `fn describe(&self, table: &str) -> RawResult` + - **接口说明**:描述表结构。 + - **参数说明**: + - `table`:表名称。 + - **返回值**:成功时返回表描述的 `RawResult`,失败时返回错误。 + +- `fn database_exists(&self, name: &str) -> RawResult` + - **接口说明**:检查数据库是否存在。 + - **参数说明**: + - `name`:数据库名称。 + - **返回值**:成功时返回布尔值的 `RawResult`,指示数据库是否存在,失败时返回错误。 + +- `fn put(&self, data: &SmlData) -> RawResult<()>` + - **接口说明**:写入无模式数据。 + - **参数说明**: + - `data`:无模式数据。 + - **返回值**:成功时返回空的 `RawResult`,失败时返回错误。 + + +#### ResultSet +ResultSet 结构体提供了结果集的一些方法,可以用来获取结果集的数据和元数据。 + +- `fn affected_rows(&self) -> i32` + - **接口说明**:获取受影响的行数。 + - **返回值**:受影响的行数,类型为 `i32`。 + +- `fn precision(&self) -> Precision` + - **接口说明**:获取精度信息。 + - **返回值**:精度信息,类型为 `Precision`。 + +- `fn fields(&self) -> &[Field]` + - **接口说明**:获取字段信息。见下文 Feild 结构体描述。 + - **返回值**:字段信息数组的引用。 + +- `fn summary(&self) -> (usize, usize)` + - **接口说明**:获取摘要信息。 + - **返回值**:包含两个 `usize` 类型的元组,分别表示某些统计信息。 + +- `fn num_of_fields(&self) -> usize` + - **接口说明**:获取字段数量。 + - **返回值**:字段数量,类型为 `usize`。 + +- `fn blocks(&mut self) -> IBlockIter<'_, Self>` + - **接口说明**:获取原始数据块的迭代器。 + - **返回值**:原始数据块的迭代器,类型为 `IBlockIter<'_, Self>`。 + +- `fn rows(&mut self) -> IRowsIter<'_, Self>` + - **接口说明**:获取按行查询的迭代器。 + - **返回值**:按行查询的迭代器,类型为 `IRowsIter<'_, Self>`。 + +- `fn deserialize(&mut self) -> Map, fn(_: Result, Error>) -> Result>` + - **接口说明**:反序列化行数据。 + - **泛型参数**: + - `T`:目标类型,需实现 `DeserializeOwned`。 + - **返回值**:反序列化结果的映射,类型为 `Map, fn(_: Result, Error>) -> Result>`。 + +- `fn to_rows_vec(&mut self) -> Result>, Error>` + - **接口说明**:将结果集转换为值的二维向量。 + - **返回值**:成功时返回值的二维向量,失败时返回错误,类型为 `Result>, Error>`。 + +#### Feild +Feild 结构体提供了字段信息的一些方法。 + +- `pub const fn empty() -> Field` + - **接口说明**:创建一个空的 `Field` 实例。 + - **返回值**:返回一个空的 `Field` 实例。 + +- `pub fn new(name: impl Into, ty: Ty, bytes: u32) -> Field` + - **接口说明**:创建一个新的 `Field` 实例。 + - **参数说明**: + - `name`:字段名称。 + - `ty`:字段类型。 + - `bytes`:字段数据长度。 + - **返回值**:返回一个新的 `Field` 实例。 + +- `pub fn name(&self) -> &str` + - **接口说明**:获取字段名称。 + - **返回值**:返回字段的名称。 + +- `pub fn escaped_name(&self) -> String` + - **接口说明**:获取转义后的字段名称。 + - **返回值**:返回转义后的字段名称。 + +- `pub const fn ty(&self) -> Ty` + - **接口说明**:获取字段类型。 + - **返回值**:返回字段的类型。 + +- `pub const fn bytes(&self) -> u32` + - **接口说明**:获取字段的预设长度。 + - **返回值**:对于变长数据类型,返回其预设长度;对于其他类型,返回其字节宽度。 + +- `pub fn to_c_field(&self) -> c_field_t` + - **接口说明**:将 `Field` 实例转换为 C 语言结构体。 + - **返回值**:返回 C 语言结构体表示的字段。 + +- `pub fn sql_repr(&self) -> String` + - **接口说明**:表示字段在 SQL 中的数据类型。 + - **返回值**:例如:"INT", "VARCHAR(100)" 等 SQL 数据类型表示。 + +### 参数绑定 +参数绑定功能主要由 Stmt 结构体支持。 +#### Stmt +Stmt 结构体提供了参数绑定相关功能,用于实现高效写入。 + +- `fn init(taos: &Q) -> RawResult` + - **接口说明**:初始化参数绑定实例。 + - **参数说明**: + - `taos`:数据库连接实例。 + - **返回值**:成功时返回初始化的实例,失败时返回错误。 + +- `fn init_with_req_id(taos: &Q, req_id: u64) -> RawResult` + - **接口说明**:使用请求ID初始化参数绑定实例。 + - **参数说明**: + - `taos`:数据库连接实例。 + - `req_id`:请求ID。 + - **返回值**:成功时返回初始化的实例,失败时返回错误。 + +- `fn prepare>(&mut self, sql: S) -> RawResult<&mut Self>` + - **接口说明**:准备要绑定的 SQL 语句。 + - **参数说明**: + - `sql`:要准备的SQL语句。 + - **返回值**:成功时返回自身的可变引用,失败时返回错误。 + +- `fn set_tbname>(&mut self, name: S) -> RawResult<&mut Self>` + - **接口说明**:设置表名称。 + - **参数说明**: + - `name`:表名称。 + - **返回值**:成功时返回自身的可变引用,失败时返回错误。 + +- `fn set_tags(&mut self, tags: &[Value]) -> RawResult<&mut Self>` + - **接口说明**:设置标签。 + - **参数说明**: + - `tags`:标签数组。 + - **返回值**:成功时返回自身的可变引用,失败时返回错误。 + +- `fn set_tbname_tags>(&mut self, name: S, tags: &[Value]) -> RawResult<&mut Self>` + - **接口说明**:设置表名称和标签。 + - **参数说明**: + - `name`:表名称。 + - `tags`:标签数组。 + - **返回值**:成功时返回自身的可变引用,失败时返回错误。 + +- `fn bind(&mut self, params: &[ColumnView]) -> RawResult<&mut Self>` + - **接口说明**:绑定参数。 + - **参数说明**: + - `params`:参数数组。 + - **返回值**:成功时返回自身的可变引用,失败时返回错误。 + +- `fn add_batch(&mut self) -> RawResult<&mut Self>` + - **接口说明**:添加批处理。 + - **返回值**:成功时返回自身的可变引用,失败时返回错误。 + +- `fn execute(&mut self) -> RawResult` + - **接口说明**:执行语句。 + - **返回值**:成功时返回受影响的行数,失败时返回错误。 + +- `fn affected_rows(&self) -> usize` + - **接口说明**:获取受影响的行数。 + - **返回值**:受影响的行数。 + +### 数据订阅 +数据订阅主要涉及三个结构体,提供连接建立的 TmqBuilder, 消费数据和提交偏移量的 Consumer,以及偏移量 Offset。 + +#### TmqBuilder +同 TaosBuilder 类似,TmqBuilder 提供了创建消费者对象的功能。 + +- `fn available_params() -> &'static [&'static str]` + - **接口说明**:获取 DSN 中可用的参数列表。 + - **返回值**:返回静态字符串切片的引用,包含可用的参数名称。 + +- `fn from_dsn(dsn: D) -> RawResult` + - **接口说明**:使用 DSN 字符串创建连接,不检查连接。 + - **参数说明**: + - `dsn`:DSN 字符串或可转换为DSN的类型。 + - **返回值**:成功时返回自身类型的 `RawResult`,失败时返回错误。 + +- `fn client_version() -> &'static str` + - **接口说明**:获取客户端版本。 + - **返回值**:返回客户端版本的静态字符串。 + +- `fn ping(&self, conn: &mut Self::Target) -> RawResult<()>` + - **接口说明**:检查连接是否仍然存活。 + - **参数说明**: + - `conn`:目标连接的可变引用。 + - **返回值**:成功时返回空的 `RawResult`,失败时返回错误。 + +- `fn ready(&self) -> bool` + - **接口说明**:检查是否准备好连接。 + - **返回值**:大多数情况下返回true,表示地址准备好连接。 + +- `fn build(&self) -> RawResult` + - **接口说明**:从此结构创建新的连接。 + - **返回值**:成功时返回目标连接类型的 `RawResult`,失败时返回错误。 + +#### Consumer +Consumer 结构体提供了订阅相关的功能,包括订阅,获取消息,提交偏移量,设置偏移量等。 + +- `fn subscribe, I: IntoIterator + Send>(&mut self, topics: I) -> RawResult<()>` + - **接口说明**:订阅一系列主题。 + - **参数说明**: + - `topics`:要订阅的主题列表。 + - **返回值**:成功时返回空的 `RawResult`,失败时返回错误。 + +- `fn recv_timeout(&self, timeout: Timeout) -> RawResult)>>` + - **接口说明**:在指定超时时间内接收消息。 + - **参数说明**: + - `timeout`:超时时间。 + - **返回值**:成功时返回消息,失败时返回错误。 + +- `fn commit(&self, offset: Self::Offset) -> RawResult<()>` + - **接口说明**:提交给定的偏移量。 + - **参数说明**: + - `offset`:要提交的偏移量,见下文 Offset 结构体。 + - **返回值**:成功时返回空的 `RawResult`,失败时返回错误。 + +- `fn commit_offset(&self, topic_name: &str, vgroup_id: VGroupId, offset: i64) -> RawResult<()>` + - **接口说明**:为特定主题和分区提交偏移量。 + - **参数说明**: + - `topic_name`:主题名称。 + - `vgroup_id`:分区 ID。 + - `offset`:要提交的偏移量。 + - **返回值**:成功时返回空的 `RawResult`,失败时返回错误。 + +- `fn list_topics(&self) -> RawResult>` + - **接口说明**:列出所有可用主题。 + - **返回值**:成功时返回主题列表,失败时返回错误。 + +- `fn assignments(&self) -> Option)>>` + - **接口说明**:获取当前分配的主题和分区。 + - **返回值**:成功时返回分配信息,失败时返回 `None`。 + +- `fn offset_seek(&mut self, topic: &str, vg_id: VGroupId, offset: i64) -> RawResult<()>` + - **接口说明**:为特定主题和分区设置偏移量。 + - **参数说明**: + - `topic`:主题名称。 + - `vg_id`:分区 ID。 + - `offset`:要设置的偏移量。 + - **返回值**:成功时返回空的 `RawResult`,失败时返回错误。 + +- `fn committed(&self, topic: &str, vgroup_id: VGroupId) -> RawResult` + - **接口说明**:获取特定主题和分区的已提交偏移量。 + - **参数说明**: + - `topic`:主题名称。 + - `vgroup_id`:分区 ID。 + - **返回值**:成功时返回偏移量,失败时返回错误。 + +- `fn position(&self, topic: &str, vgroup_id: VGroupId) -> RawResult` + - **接口说明**:获取特定主题和分区的当前位置。 + - **参数说明**: + - `topic`:主题名称。 + - `vgroup_id`:分区 ID。 + - **返回值**:成功时返回当前位置,失败时返回错误。 + +#### Offset + +Offset 结构体提供了获取当前消息所属的数据库,主题和分区信息。 + +- `fn database(&self) -> &str` + - **接口说明**:获取当前消息的数据库名称。 + - **返回值**:数据库名称的引用。 + +- `fn topic(&self) -> &str` + - **接口说明**:获取当前消息的主题名称。 + - **返回值**:主题名称的引用。 + +- `fn vgroup_id(&self) -> VGroupId` + - **接口说明**:获取当前消息的分区 ID。 + - **返回值**:分区 ID。 + +其他相关结构体 API 使用说明请移步 Rust 文档托管网页:https://docs.rs/taos。 [taos]: https://github.com/taosdata/rust-connector-taos [deadpool]: https://crates.io/crates/deadpool