From 5fc0f32257e08d41e058832d95604df2895ea693 Mon Sep 17 00:00:00 2001 From: menshibin Date: Thu, 1 Aug 2024 21:30:34 +0800 Subject: [PATCH 01/15] modify python api --- .../python/connect_websocket_examples.py | 37 ++++++++++++------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/docs/examples/python/connect_websocket_examples.py b/docs/examples/python/connect_websocket_examples.py index 1446bdf120..69c3900187 100644 --- a/docs/examples/python/connect_websocket_examples.py +++ b/docs/examples/python/connect_websocket_examples.py @@ -7,7 +7,7 @@ def create_connection(): conn = taosws.connect( user="root", password="taosdata", - host="localhost", + host="192.168.1.98", port=6041, ) except Exception as err: @@ -21,12 +21,13 @@ def create_db_table(conn): 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')") + conn.execute("CREATE TABLE IF NOT EXISTS `d0` USING `meters` (groupId, location) TAGS(0, 'Los Angles')") except Exception as err: print(f'Exception {err}') # ANCHOR_END: create_db -def insert(conn): +def insert(conn): +# ANCHOR: insert sql = """ INSERT INTO power.d1001 USING power.meters TAGS('California.SanFrancisco', 2) @@ -39,18 +40,26 @@ def insert(conn): inserted = conn.execute(sql) assert inserted == 8 except Exception as err: - print(f'Exception {err}') + print(f'Exception111 {err}') +# ANCHOR_END: insert def query(conn): - result = conn.query("select * from stb") - num_of_fields = result.field_count - print(num_of_fields) +# ANCHOR: query + try: + result = conn.query("select * from meters") + num_of_fields = result.field_count + print(num_of_fields) - for row in result: - print(row) + for row in result: + print(row) + except Exception as err: + print(f'Exception {err}') +# ANCHOR_END: query -# output: -# 3 -# ('2023-02-28 15:56:13.329 +08:00', 1, 1) -# ('2023-02-28 15:56:13.333 +08:00', 2, 1) -# ('2023-02-28 15:56:13.337 +08:00', 3, 1) +if __name__ == "__main__": + conn = create_connection() + create_db_table(conn) + insert(conn) + query(conn) + if conn: + conn.close() From 43a9872c4ca1f307c828930506a4f91b0974b829 Mon Sep 17 00:00:00 2001 From: sheyanjie-qq <249478495@qq.com> Date: Fri, 2 Aug 2024 14:02:22 +0800 Subject: [PATCH 02/15] mod rust dev guide --- .../rust/nativeexample/examples/connect.rs | 4 +- .../rust/nativeexample/examples/query.rs | 100 +++++++++--------- .../rust/nativeexample/examples/schemaless.rs | 8 +- .../rust/nativeexample/examples/stmt.rs | 5 + .../rust/restexample/examples/connect.rs | 4 +- docs/zh/08-develop/01-connect/index.md | 51 ++++++++- docs/zh/08-develop/02-sql.md | 22 +++- docs/zh/08-develop/04-schemaless.md | 7 ++ docs/zh/08-develop/05-stmt.md | 6 +- docs/zh/08-develop/07-tmq.md | 9 +- docs/zh/14-reference/05-connector/26-rust.mdx | 98 +++++++++++------ 11 files changed, 212 insertions(+), 102 deletions(-) diff --git a/docs/examples/rust/nativeexample/examples/connect.rs b/docs/examples/rust/nativeexample/examples/connect.rs index fb226d8710..dee6db2a41 100644 --- a/docs/examples/rust/nativeexample/examples/connect.rs +++ b/docs/examples/rust/nativeexample/examples/connect.rs @@ -3,7 +3,7 @@ use taos::*; #[tokio::main] async fn main() -> Result<(), Error> { #[allow(unused_variables)] - let taos = TaosBuilder::from_dsn("taos://")?.build()?; - println!("Connected"); + let taos = TaosBuilder::from_dsn("taos://localhost:6030")?.build()?; + println!("Connected to localhost with native connection successfully."); Ok(()) } diff --git a/docs/examples/rust/nativeexample/examples/query.rs b/docs/examples/rust/nativeexample/examples/query.rs index dfe55e8749..a493e7c729 100644 --- a/docs/examples/rust/nativeexample/examples/query.rs +++ b/docs/examples/rust/nativeexample/examples/query.rs @@ -7,60 +7,62 @@ async fn main() -> anyhow::Result<()> { let taos = builder.build()?; - // ANCHOR: create_db_and_table - let db = "power"; - // create database - taos.exec_many([ - format!("DROP DATABASE IF EXISTS `{db}`"), - format!("CREATE DATABASE `{db}`"), - format!("USE `{db}`"), - ]) - .await?; +// ANCHOR: create_db_and_table +let db = "power"; +// create database +taos.exec_many([ + format!("CREATE DATABASE IF NOT EXISTS `{db}`"), + format!("USE `{db}`"), +]) +.await?; +println!("Create database power successfully."); - // create table - taos.exec_many([ - // create super table - "CREATE TABLE `meters` (`ts` TIMESTAMP, `current` FLOAT, `voltage` INT, `phase` FLOAT) \ - TAGS (`groupid` INT, `location` BINARY(24))", - ]).await?; - // ANCHOR_END: create_db_and_table - - // ANCHOR: insert_data - let inserted = taos.exec("INSERT INTO " + - "power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " + - "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(3, 'California.SanFrancisco') " + - "VALUES " + - "(NOW + 1a, 10.30000, 218, 0.25000) ").await?; +// create super table +taos.exec_many([ + "CREATE TABLE `meters` (`ts` TIMESTAMP, `current` FLOAT, `voltage` INT, `phase` FLOAT) \ + TAGS (`groupid` INT, `location` BINARY(24))", +]).await?; +println!("Create stable meters successfully."); - println!("inserted: {} rows", inserted); - // ANCHOR_END: insert_data +// ANCHOR_END: create_db_and_table - // ANCHOR: query_data - let mut result = taos.query("SELECT * FROM power.meters").await?; +// ANCHOR: insert_data +let inserted = taos.exec("INSERT INTO " + +"power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " + +"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(3, 'California.SanFrancisco') " + +"VALUES " + +"(NOW + 1a, 10.30000, 218, 0.25000) ").await?; - for field in result.fields() { - println!("got field: {}", field.name()); +println!("inserted: {} rows to power.meters successfully.", inserted); +// ANCHOR_END: insert_data + +// ANCHOR: query_data +// query data, make sure the database and table are created before +let mut result = taos.query("SELECT ts, current, location FROM power.meters limit 100").await?; + +for field in result.fields() { + println!("got field: {}", field.name()); +} + +let mut rows = result.rows(); +let mut nrows = 0; +while let Some(row) = rows.try_next().await? { + for (col, (name, value)) in row.enumerate() { + println!( + "[{}] got value in col {} (named `{:>8}`): {}", + nrows, col, name, value + ); } + nrows += 1; +} +// ANCHOR_END: query_data - let mut rows = result.rows(); - let mut nrows = 0; - while let Some(row) = rows.try_next().await? { - for (col, (name, value)) in row.enumerate() { - println!( - "[{}] got value in col {} (named `{:>8}`): {}", - nrows, col, name, value - ); - } - nrows += 1; - } - // ANCHOR_END: query_data - - // ANCHOR: query_with_req_id - let result = taos.query_with_req_id("SELECT * FROM power.meters", 0).await?; - // ANCHOR_END: query_with_req_id +// ANCHOR: query_with_req_id +let result = taos.query_with_req_id("SELECT ts, current, location FROM power.meters limit 1", 1).await?; +// ANCHOR_END: query_with_req_id } diff --git a/docs/examples/rust/nativeexample/examples/schemaless.rs b/docs/examples/rust/nativeexample/examples/schemaless.rs index 44ce0fe694..2da99400d3 100644 --- a/docs/examples/rust/nativeexample/examples/schemaless.rs +++ b/docs/examples/rust/nativeexample/examples/schemaless.rs @@ -17,8 +17,6 @@ async fn put() -> anyhow::Result<()> { let db = "power"; - client.exec(format!("drop database if exists {db}")).await?; - client .exec(format!("create database if not exists {db}")) .await?; @@ -44,7 +42,7 @@ async fn put() -> anyhow::Result<()> { // SchemalessProtocol::Telnet let data = [ - "meters.current 1648432611249 10.3 location=California.SanFrancisco group=2", + "metric_telnet 1648432611249 10.3 location=California.SanFrancisco group=2", ] .map(String::from) .to_vec(); @@ -60,7 +58,7 @@ async fn put() -> anyhow::Result<()> { // SchemalessProtocol::Json let data = [ - r#"[{"metric": "meters.current", "timestamp": 1681345954000, "value": 10.3, "tags": {"location": "California.SanFrancisco", "groupid": 2}}, {"metric": "meters.voltage", "timestamp": 1648432611249, "value": 219, "tags": {"location": "California.LosAngeles", "groupid": 1}}, {"metric": "meters.current", "timestamp": 1648432611250, "value": 12.6, "tags": {"location": "California.SanFrancisco", "groupid": 2}}, {"metric": "meters.voltage", "timestamp": 1648432611250, "value": 221, "tags": {"location": "California.LosAngeles", "groupid": 1}}]"# + r#"[{"metric": "metric_json", "timestamp": 1681345954000, "value": 10.3, "tags": {"location": "California.SanFrancisco", "groupid": 2}}, {"metric": "meters.voltage", "timestamp": 1648432611249, "value": 219, "tags": {"location": "California.LosAngeles", "groupid": 1}}, {"metric": "meters.current", "timestamp": 1648432611250, "value": 12.6, "tags": {"location": "California.SanFrancisco", "groupid": 2}}, {"metric": "meters.voltage", "timestamp": 1648432611250, "value": 221, "tags": {"location": "California.LosAngeles", "groupid": 1}}]"# ] .map(String::from) .to_vec(); @@ -74,7 +72,5 @@ async fn put() -> anyhow::Result<()> { .build()?; assert_eq!(client.put(&sml_data).await?, ()); - client.exec(format!("drop database if exists {db}")).await?; - Ok(()) } diff --git a/docs/examples/rust/nativeexample/examples/stmt.rs b/docs/examples/rust/nativeexample/examples/stmt.rs index 0194eccdf1..d784607e03 100644 --- a/docs/examples/rust/nativeexample/examples/stmt.rs +++ b/docs/examples/rust/nativeexample/examples/stmt.rs @@ -17,6 +17,8 @@ async fn main() -> anyhow::Result<()> { for i in 0..NUM_TABLES { let table_name = format!("d{}", i); let tags = vec![Value::VarChar("California.SanFransico".into()), Value::Int(2)]; + + // set table name and tags for the prepared statement. stmt.set_tbname_tags(&table_name, &tags).await?; for j in 0..NUM_ROWS { let values = vec![ @@ -25,13 +27,16 @@ async fn main() -> anyhow::Result<()> { ColumnView::from_ints(vec![219 + j as i32]), ColumnView::from_floats(vec![0.31 + j as f32]), ]; + // bind values to the prepared statement. stmt.bind(&values).await?; } + stmt.add_batch().await?; } // execute. let rows = stmt.execute().await?; assert_eq!(rows, NUM_TABLES * NUM_ROWS); + Ok(()) } diff --git a/docs/examples/rust/restexample/examples/connect.rs b/docs/examples/rust/restexample/examples/connect.rs index fb226d8710..0c89517f22 100644 --- a/docs/examples/rust/restexample/examples/connect.rs +++ b/docs/examples/rust/restexample/examples/connect.rs @@ -3,7 +3,7 @@ use taos::*; #[tokio::main] async fn main() -> Result<(), Error> { #[allow(unused_variables)] - let taos = TaosBuilder::from_dsn("taos://")?.build()?; - println!("Connected"); + let taos = TaosBuilder::from_dsn("taos+ws://localhost:6041")?.build()?; + println!("Connected to localhost with websocket connection successfully."); Ok(()) } diff --git a/docs/zh/08-develop/01-connect/index.md b/docs/zh/08-develop/01-connect/index.md index ac2787a4cc..bd738209f9 100644 --- a/docs/zh/08-develop/01-connect/index.md +++ b/docs/zh/08-develop/01-connect/index.md @@ -321,7 +321,7 @@ 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}]` -URL 和 Properties 的详细参数说明和如何使用详见 [API 说明](../../reference/connector/java/#url-规范) +URL 和 Properties 的详细参数说明和如何使用详见 [url 规范](../../reference/connector/java/#url-规范) @@ -329,6 +329,16 @@ URL 和 Properties 的详细参数说明和如何使用详见 [API 说明](../.. +Rust 连接器使用 DSN 来创建连接, DSN 描述字符串基本结构如下: + +```text +[+]://[[:@]:][/][?=[&=]] +|------|------------|---|-----------|-----------|------|------|------------|-----------------------| +|driver| protocol | | username | password | host | port | database | params | +``` + +DSN 的详细说明和如何使用详见 [连接功能](../../reference/connector/rust/#连接功能) + @@ -359,7 +369,9 @@ URL 和 Properties 的详细参数说明和如何使用详见 [API 说明](../.. - +```rust +{{#include docs/examples/rust/restexample/examples/connect.rs}} +``` ```js @@ -396,7 +408,10 @@ URL 和 Properties 的详细参数说明和如何使用详见 [API 说明](../.. - +```rust +{{#include docs/examples/rust/nativeexample/examples/connect.rs}} +``` + @@ -431,7 +446,7 @@ URL 和 Properties 的详细参数说明和如何使用详见 [API 说明](../.. - +不支持 @@ -491,7 +506,33 @@ URL 和 Properties 的详细参数说明和如何使用详见 [API 说明](../.. - + +在复杂应用中,建议启用连接池。[taos] 的连接池默认(异步模式)使用 [deadpool] 实现。 + +如下,可以生成一个默认参数的连接池。 + +```rust +let pool: Pool = TaosBuilder::from_dsn("taos:///") + .unwrap() + .pool() + .unwrap(); +``` + +同样可以使用连接池的构造器,对连接池参数进行设置: + +```rust +let pool: Pool = Pool::builder(Manager::from_dsn(self.dsn.clone()).unwrap().0) + .max_size(88) // 最大连接数 + .build() + .unwrap(); +``` + +在应用代码中,使用 `pool.get()?` 来获取一个连接对象 [Taos]。 + +```rust +let taos = pool.get()?; +``` + diff --git a/docs/zh/08-develop/02-sql.md b/docs/zh/08-develop/02-sql.md index 7b4c6e5d98..d4ee344c11 100644 --- a/docs/zh/08-develop/02-sql.md +++ b/docs/zh/08-develop/02-sql.md @@ -21,7 +21,6 @@ TDengine 对 SQL 语言提供了全面的支持,允许用户以熟悉的 SQL ```java {{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcCreatDBDemo.java:create_db_and_table}} ``` -> **注意**:如果不使用 `USE power` 指定数据库,则后续对表的操作都需要增加数据库名称作为前缀,如 power.meters。 @@ -31,6 +30,11 @@ TDengine 对 SQL 语言提供了全面的支持,允许用户以熟悉的 SQL + +```rust +{{#include docs/examples/rust/nativeexample/examples/query.rs:create_db_and_table}} +``` + @@ -41,6 +45,7 @@ TDengine 对 SQL 语言提供了全面的支持,允许用户以熟悉的 SQL +> **注意**:如果不使用 `USE power` 指定数据库,则后续对表的操作都需要增加数据库名称作为前缀,如 `power.meters`。 ## 插入数据 下面以智能电表为例,展示如何使用连接器执行 SQL 来插入数据到 `power` 数据库的 `meters` 超级表。样例使用 TDengine 自动建表 SQL 语法,写入 d1001 子表中 3 条数据,写入 d1002 子表中 1 条数据,然后打印出实际插入数据条数。 @@ -61,6 +66,11 @@ NOW 为系统内部函数,默认为客户端所在计算机当前时间。 NOW + +```rust +{{#include docs/examples/rust/nativeexample/examples/query.rs:insert_data}} +``` + @@ -90,6 +100,11 @@ NOW 为系统内部函数,默认为客户端所在计算机当前时间。 NOW + +```rust +{{#include docs/examples/rust/nativeexample/examples/query.rs:query_data}} +``` + @@ -127,6 +142,11 @@ reqId 可用于请求链路追踪,reqId 就像分布式系统中的 traceId + +```rust +{{#include docs/examples/rust/nativeexample/examples/query.rs:query_with_req_id}} +``` + diff --git a/docs/zh/08-develop/04-schemaless.md b/docs/zh/08-develop/04-schemaless.md index 734e9558a2..7a5730df46 100644 --- a/docs/zh/08-develop/04-schemaless.md +++ b/docs/zh/08-develop/04-schemaless.md @@ -181,6 +181,11 @@ writer.write(lineDemo, SchemalessProtocolType.LINE, SchemalessTimestampType.NANO + +```rust +{{#include docs/examples/rust/restexample/examples/schemaless.rs}} +``` + @@ -211,6 +216,7 @@ writer.write(lineDemo, SchemalessProtocolType.LINE, SchemalessTimestampType.NANO +除 DSN 不同,其余同 Websocket 代码示例。 @@ -234,6 +240,7 @@ writer.write(lineDemo, SchemalessProtocolType.LINE, SchemalessTimestampType.NANO + 不支持 diff --git a/docs/zh/08-develop/05-stmt.md b/docs/zh/08-develop/05-stmt.md index 132a1b8850..5dd9daaed5 100644 --- a/docs/zh/08-develop/05-stmt.md +++ b/docs/zh/08-develop/05-stmt.md @@ -43,6 +43,10 @@ import TabItem from "@theme/TabItem"; +```rust +{{#include docs/examples/rust/restexample/examples/stmt.rs}} +``` + @@ -82,7 +86,7 @@ import TabItem from "@theme/TabItem"; - +除 DSN 不同,其余同 Websocket 代码示例。 diff --git a/docs/zh/08-develop/07-tmq.md b/docs/zh/08-develop/07-tmq.md index 1d5b59307e..405d227e8e 100644 --- a/docs/zh/08-develop/07-tmq.md +++ b/docs/zh/08-develop/07-tmq.md @@ -46,7 +46,7 @@ TDengine 消费者的概念跟 Kafka 类似,消费者通过订阅主题来接 下面是各语言连接器创建参数: -Java 连接器创建消费者的参数为 Properties, 可以设置的参数列表请参考 [API 说明](../../reference/connector/java/#消费者) +Java 连接器创建消费者的参数为 Properties, 可以设置的参数列表请参考 [消费者参数](../../reference/connector/java/#消费者) 其他参数请参考上文通用基础配置项。 @@ -58,6 +58,8 @@ Java 连接器创建消费者的参数为 Properties, 可以设置的参数列 +Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请参考 [DSN](../../reference/connector/rust/#dsn) +其他参数请参考上文通用基础配置项。 @@ -102,6 +104,11 @@ Java 连接器创建消费者的参数为 Properties, 可以设置的参数列 + +```rust +{{#include docs/examples/rust/nativeexample/examples/tmq.rs:create_consumer}} +``` + diff --git a/docs/zh/14-reference/05-connector/26-rust.mdx b/docs/zh/14-reference/05-connector/26-rust.mdx index f6c9e5d688..e33d3f0a0f 100644 --- a/docs/zh/14-reference/05-connector/26-rust.mdx +++ b/docs/zh/14-reference/05-connector/26-rust.mdx @@ -168,7 +168,7 @@ DSN 描述字符串基本结构如下: 各部分意义见下表: - **driver**: 必须指定驱动名以便连接器选择何种方式创建连接,支持如下驱动名: - - **taos**: 表名使用 TDengine 连接器驱动。 + - **taos**: 表明使用 TDengine 连接器驱动。 - **tmq**: 使用 TMQ 订阅数据。 - **http/ws**: 使用 Websocket 创建连接。 - **https/wss**: 在 Websocket 连接方式下显示启用 SSL/TLS 连接。 @@ -640,16 +640,16 @@ DSN 描述字符串基本结构如下: 一个完整的 DSN 描述字符串示例如下:`taos+ws://localhost:6041/test`, 表示使用 Websocket(`ws`)方式通过 `6041` 端口连接服务器 `localhost`,并指定默认数据库为 `test`。 #### TaosBuilder -TaosBuilder 结构体提供了建立连接,检查连接,以及获取服务端版本号等功能。 +TaosBuilder 结构体主要提供了根据 DSN 构建 Taos 对象的方法,还提供了检查连接,以及获取客户端版本号等功能。 - `fn available_params() -> &'static [&'static str]` - - **接口说明**:获取DSN中可用的参数列表。 + - **接口说明**:获取 DSN 中可用的参数列表。 - **返回值**:返回静态字符串切片的引用,包含可用的参数名称。 - `fn from_dsn(dsn: D) -> RawResult` - - **接口说明**:使用DSN字符串创建连接,不检查连接。 + - **接口说明**:使用 DSN 字符串创建连接,不检查连接。 - **参数说明**: - - `dsn`:DSN字符串或可转换为DSN的类型。 + - `dsn`:DSN 字符串或可转换为 DSN 的类型。 - **返回值**:成功时返回自身类型的 `RawResult`,失败时返回错误。 - `fn client_version() -> &'static str` @@ -664,14 +664,15 @@ TaosBuilder 结构体提供了建立连接,检查连接,以及获取服务 - `fn ready(&self) -> bool` - **接口说明**:检查是否准备好连接。 - - **返回值**:大多数情况下返回true,表示地址准备好连接。 + - **返回值**:大多数情况下返回 `true`,表示地址准备好连接。 - `fn build(&self) -> RawResult` - - **接口说明**:从此结构创建新的连接。 + - **接口说明**:从此结构创建新的 Taos 对象。 - **返回值**:成功时返回目标连接类型的 `RawResult`,失败时返回错误。 ### 执行 SQL -执行 SQL 主要涉及到 Taos 结构体,以及结果集 ResultSet 结构体,还有列信息 Field。 +执行 SQL 主要使用 Taos 结构体,获取结果集以及元数据需要使用下节介绍的 ResultSet 结构体 和列信息 Field 结构体。 + #### Taos Taos 结构体提供了多个数据库操作的 API,包括:执行 SQL,无模式写入,以及一些常用数据库查询的封装(如创建数据库,获取) @@ -684,34 +685,34 @@ Taos 结构体提供了多个数据库操作的 API,包括:执行 SQL,无 - **返回值**:如果使用websocket协议,则返回 `true`,否则返回 `false`。 - `fn query>(&self, sql: T) -> RawResult` - - **接口说明**:执行SQL查询。 + - **接口说明**:执行 SQL 查询。 - **参数说明**: - - `sql`:要执行的SQL语句。 + - `sql`:要执行的 SQL 语句。 - **返回值**:成功时返回结果集 `ResultSet` 的 `RawResult`,失败时返回错误。 - `fn query_with_req_id>(&self, sql: T, req_id: u64) -> RawResult` - - **接口说明**:带请求ID执行SQL查询。 + - **接口说明**:带请求 ID 执行 SQL 查询。 - **参数说明**: - - `sql`:要执行的SQL语句。 - - `req_id`:请求ID。 + - `sql`:要执行的 SQL 语句。 + - `req_id`:请求 ID。 - **返回值**:成功时返回结果集 `ResultSet` 的 `RawResult`,失败时返回错误。 - `fn exec>(&self, sql: T) -> RawResult` - - **接口说明**:执行SQL语句。 + - **接口说明**:执行 SQL 语句。 - **参数说明**: - - `sql`:要执行的SQL语句。 + - `sql`:要执行的 SQL 语句。 - **返回值**:成功时返回受影响的行数,失败时返回错误。 - `fn exec_many, I: IntoIterator>(&self, input: I) -> RawResult` - - **接口说明**:批量执行SQL语句。 + - **接口说明**:批量执行 SQL 语句。 - **参数说明**: - - `input`:要执行的SQL语句集合。 + - `input`:要执行的 SQL 语句集合。 - **返回值**:成功时返回总共受影响的行数,失败时返回错误。 - `fn query_one, O: DeserializeOwned>(&self, sql: T) -> RawResult>` - - **接口说明**:执行SQL查询并返回单个结果。 + - **接口说明**:执行 SQL 查询并返回单个结果。 - **参数说明**: - - `sql`:要执行的SQL语句。 + - `sql`:要执行的 SQL 语句。 - **返回值**:成功时返回可选的结果对象,失败时返回错误。 - `fn server_version(&self) -> RawResult>` @@ -722,7 +723,7 @@ Taos 结构体提供了多个数据库操作的 API,包括:执行 SQL,无 - **接口说明**:创建主题。 - **参数说明**: - `name`:主题名称。 - - `sql`:关联的SQL语句。 + - `sql`:关联的 SQ L语句。 - **返回值**:成功时返回空的 `RawResult`,失败时返回错误。 - `fn databases(&self) -> RawResult>` @@ -737,7 +738,7 @@ Taos 结构体提供了多个数据库操作的 API,包括:执行 SQL,无 - **接口说明**:描述表结构。 - **参数说明**: - `table`:表名称。 - - **返回值**:成功时返回表描述的 `RawResult`,失败时返回错误。 + - **返回值**:成功时返回表结构描述的 `RawResult`,失败时返回错误。 - `fn database_exists(&self, name: &str) -> RawResult` - **接口说明**:检查数据库是否存在。 @@ -746,12 +747,43 @@ Taos 结构体提供了多个数据库操作的 API,包括:执行 SQL,无 - **返回值**:成功时返回布尔值的 `RawResult`,指示数据库是否存在,失败时返回错误。 - `fn put(&self, data: &SmlData) -> RawResult<()>` - - **接口说明**:写入无模式数据。 + - **接口说明**:写入无模式数据,SmlData 结构介绍见下文。 - **参数说明**: - `data`:无模式数据。 - **返回值**:成功时返回空的 `RawResult`,失败时返回错误。 +### SmlData +SmlData 结构体提供了无模式写入的数据结构,以及获取属性的方法。 +- `pub struct SmlData` + - **结构体说明**:`SmlData` 结构体用于存储无模式数据及其相关信息。 + - **字段说明**: + - `protocol`:无模式协议,支持 `Line`, `Telnet`, `Json`, 三种。 + - `precision`:时间戳精度,支持 `Hours`, `Minutes`, `Seconds`, `Millisecond`(默认), `Microsecond`, `Nanosecond`。 + - `data`:数据列表。 + - `ttl`:数据存活时间,单位为秒。 + - `req_id`:请求 ID。 +- `pub fn protocol(&self) -> SchemalessProtocol` + - **接口说明**:获取无模式协议。 + - **返回值**:无模式协议类型,支持 `Line`, `Telnet`, `Json`, 三种。 + +- `pub fn precision(&self) -> SchemalessPrecision` + - **接口说明**:获取时间戳精度。 + - **返回值**:时间戳精度类型,支持 `Hours`, `Minutes`, `Seconds`, `Millisecond`(默认), `Microsecond`, `Nanosecond`。 + +- `pub fn data(&self) -> &Vec` + - **接口说明**:获取数据列表。 + - **返回值**:数据列表的引用。 + +- `pub fn ttl(&self) -> Option` + - **接口说明**:获取数据存活时间。 + - **返回值**:数据存活时间(可选),单位为秒。 + +- `pub fn req_id(&self) -> Option` + - **接口说明**:获取请求 ID。 + - **返回值**:请求 ID(可选)。 + +### 结果获取 #### ResultSet ResultSet 结构体提供了结果集的一些方法,可以用来获取结果集的数据和元数据。 @@ -844,16 +876,16 @@ Stmt 结构体提供了参数绑定相关功能,用于实现高效写入。 - **返回值**:成功时返回初始化的实例,失败时返回错误。 - `fn init_with_req_id(taos: &Q, req_id: u64) -> RawResult` - - **接口说明**:使用请求ID初始化参数绑定实例。 + - **接口说明**:使用请求 ID 初始化参数绑定实例。 - **参数说明**: - `taos`:数据库连接实例。 - - `req_id`:请求ID。 + - `req_id`:请求 ID。 - **返回值**:成功时返回初始化的实例,失败时返回错误。 - `fn prepare>(&mut self, sql: S) -> RawResult<&mut Self>` - **接口说明**:准备要绑定的 SQL 语句。 - **参数说明**: - - `sql`:要准备的SQL语句。 + - `sql`:要准备的 SQL 语句。 - **返回值**:成功时返回自身的可变引用,失败时返回错误。 - `fn set_tbname>(&mut self, name: S) -> RawResult<&mut Self>` @@ -921,7 +953,7 @@ Stmt 结构体提供了参数绑定相关功能,用于实现高效写入。 - `fn ready(&self) -> bool` - **接口说明**:检查是否准备好连接。 - - **返回值**:大多数情况下返回true,表示地址准备好连接。 + - **返回值**:大多数情况下返回 `true`,表示地址准备好连接。 - `fn build(&self) -> RawResult` - **接口说明**:从此结构创建新的连接。 @@ -1002,12 +1034,8 @@ Offset 结构体提供了获取当前消息所属的数据库,主题和分区 - **接口说明**:获取当前消息的分区 ID。 - **返回值**:分区 ID。 -其他相关结构体 API 使用说明请移步 Rust 文档托管网页:https://docs.rs/taos。 - -[taos]: https://github.com/taosdata/rust-connector-taos -[deadpool]: https://crates.io/crates/deadpool -[r2d2]: https://crates.io/crates/r2d2 -[TaosBuilder]: https://docs.rs/taos/latest/taos/struct.TaosBuilder.html -[TaosCfg]: https://docs.rs/taos/latest/taos/struct.TaosCfg.html -[struct.Taos]: https://docs.rs/taos/latest/taos/struct.Taos.html -[Stmt]: https://docs.rs/taos/latest/taos/struct.Stmt.html +## 附录 +- Rust 连接器文档:https://docs.rs/taos +- Rust 连接器项目地址: https://github.com/taosdata/rust-connector-taos +- deadpool 连接池: https://crates.io/crates/deadpool +- r2d2 连接池: https://crates.io/crates/r2d2 From 1bb29caf50c1388726d11cf40cd13112678900c4 Mon Sep 17 00:00:00 2001 From: sheyanjie-qq <249478495@qq.com> Date: Fri, 2 Aug 2024 14:05:14 +0800 Subject: [PATCH 03/15] mod schemaless --- .../rust/restexample/examples/schemaless.rs | 76 ++++++++ .../rust/restexample/examples/stmt.rs | 42 +++++ .../examples/rust/restexample/examples/tmq.rs | 163 ++++++++++++++++++ docs/zh/08-develop/04-schemaless.md | 2 +- 4 files changed, 282 insertions(+), 1 deletion(-) create mode 100644 docs/examples/rust/restexample/examples/schemaless.rs create mode 100644 docs/examples/rust/restexample/examples/stmt.rs create mode 100644 docs/examples/rust/restexample/examples/tmq.rs diff --git a/docs/examples/rust/restexample/examples/schemaless.rs b/docs/examples/rust/restexample/examples/schemaless.rs new file mode 100644 index 0000000000..eefcd63dae --- /dev/null +++ b/docs/examples/rust/restexample/examples/schemaless.rs @@ -0,0 +1,76 @@ +use taos_query::common::SchemalessPrecision; +use taos_query::common::SchemalessProtocol; +use taos_query::common::SmlDataBuilder; + +use crate::AsyncQueryable; +use crate::AsyncTBuilder; +use crate::TaosBuilder; + +async fn put() -> anyhow::Result<()> { + std::env::set_var("RUST_LOG", "taos=debug"); + pretty_env_logger::init(); + let dsn = + std::env::var("TDENGINE_ClOUD_DSN").unwrap_or("https://localhost:6041".to_string()); + log::debug!("dsn: {:?}", &dsn); + + let client = TaosBuilder::from_dsn(dsn)?.build().await?; + + let db = "power"; + + client + .exec(format!("create database if not exists {db}")) + .await?; + + // should specify database before insert + client.exec(format!("use {db}")).await?; + + // SchemalessProtocol::Line + let data = [ + "meters,groupid=2,location=California.SanFrancisco current=10.3000002f64,voltage=219i32,phase=0.31f64 1626006833639000000", + ] + .map(String::from) + .to_vec(); + + let sml_data = SmlDataBuilder::default() + .protocol(SchemalessProtocol::Line) + .precision(SchemalessPrecision::Millisecond) + .data(data.clone()) + .ttl(1000) + .req_id(100u64) + .build()?; + assert_eq!(client.put(&sml_data).await?, ()); + + // SchemalessProtocol::Telnet + let data = [ + "metric_telnet 1648432611249 10.3 location=California.SanFrancisco group=2", + ] + .map(String::from) + .to_vec(); + + let sml_data = SmlDataBuilder::default() + .protocol(SchemalessProtocol::Telnet) + .precision(SchemalessPrecision::Millisecond) + .data(data.clone()) + .ttl(1000) + .req_id(200u64) + .build()?; + assert_eq!(client.put(&sml_data).await?, ()); + + // SchemalessProtocol::Json + let data = [ + r#"[{"metric": "metric_json", "timestamp": 1681345954000, "value": 10.3, "tags": {"location": "California.SanFrancisco", "groupid": 2}}, {"metric": "meters.voltage", "timestamp": 1648432611249, "value": 219, "tags": {"location": "California.LosAngeles", "groupid": 1}}, {"metric": "meters.current", "timestamp": 1648432611250, "value": 12.6, "tags": {"location": "California.SanFrancisco", "groupid": 2}}, {"metric": "meters.voltage", "timestamp": 1648432611250, "value": 221, "tags": {"location": "California.LosAngeles", "groupid": 1}}]"# + ] + .map(String::from) + .to_vec(); + + let sml_data = SmlDataBuilder::default() + .protocol(SchemalessProtocol::Json) + .precision(SchemalessPrecision::Millisecond) + .data(data.clone()) + .ttl(1000) + .req_id(300u64) + .build()?; + assert_eq!(client.put(&sml_data).await?, ()); + + Ok(()) +} diff --git a/docs/examples/rust/restexample/examples/stmt.rs b/docs/examples/rust/restexample/examples/stmt.rs new file mode 100644 index 0000000000..524b37b919 --- /dev/null +++ b/docs/examples/rust/restexample/examples/stmt.rs @@ -0,0 +1,42 @@ +use taos::*; + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + let taos = TaosBuilder::from_dsn("ws://")?.build().await?; + + taos.exec("DROP DATABASE IF EXISTS power").await?; + taos.create_database("power").await?; + taos.use_database("power").await?; + taos.exec("CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)").await?; + + let mut stmt = Stmt::init(&taos).await?; + stmt.prepare("INSERT INTO ? USING meters TAGS(?, ?) VALUES(?, ?, ?, ?)").await?; + + const NUM_TABLES: usize = 10; + const NUM_ROWS: usize = 10; + for i in 0..NUM_TABLES { + let table_name = format!("d{}", i); + let tags = vec![Value::VarChar("California.SanFransico".into()), Value::Int(2)]; + + // set table name and tags for the prepared statement. + stmt.set_tbname_tags(&table_name, &tags).await?; + for j in 0..NUM_ROWS { + let values = vec![ + ColumnView::from_millis_timestamp(vec![1648432611249 + j as i64]), + ColumnView::from_floats(vec![10.3 + j as f32]), + ColumnView::from_ints(vec![219 + j as i32]), + ColumnView::from_floats(vec![0.31 + j as f32]), + ]; + // bind values to the prepared statement. + stmt.bind(&values).await?; + } + + stmt.add_batch().await?; + } + + // execute. + let rows = stmt.execute().await?; + assert_eq!(rows, NUM_TABLES * NUM_ROWS); + + Ok(()) +} diff --git a/docs/examples/rust/restexample/examples/tmq.rs b/docs/examples/rust/restexample/examples/tmq.rs new file mode 100644 index 0000000000..8f195e1629 --- /dev/null +++ b/docs/examples/rust/restexample/examples/tmq.rs @@ -0,0 +1,163 @@ +use std::time::Duration; +use std::str::FromStr; + +use taos::*; + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + pretty_env_logger::formatted_timed_builder() + .filter_level(log::LevelFilter::Info) + .init(); + use taos_query::prelude::*; + let dsn = "ws://localhost:6041".to_string(); + log::info!("dsn: {}", dsn); + let mut dsn = Dsn::from_str(&dsn)?; + + let taos = TaosBuilder::from_dsn(&dsn)?.build().await?; + + // prepare database and table + taos.exec_many([ + "drop topic if exists topic_meters", + "drop database if exists power", + "create database if not exists power WAL_RETENTION_PERIOD 86400", + "use power", + "CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))", + "create table if not exists power.d001 using power.meters tags(1,'location')", + ]) + .await?; + + taos.exec_many([ + "drop database if exists db2", + "create database if not exists db2 wal_retention_period 3600", + "use db2", + ]) + .await?; + + // ANCHOR: create_topic + taos.exec_many([ + "CREATE TOPIC IF NOT EXISTS topic_meters AS SELECT ts, current, voltage, phase, groupid, location FROM power.meters", + ]) + .await?; + // ANCHOR_END: create_topic + + // ANCHOR: create_consumer + dsn.params.insert("group.id".to_string(), "abc".to_string()); + dsn.params.insert("auto.offset.reset".to_string(), "earliest".to_string()); + + let builder = TmqBuilder::from_dsn(&dsn)?; + let mut consumer = builder.build().await?; + // ANCHOR_END: create_consumer + + // ANCHOR: subscribe + consumer.subscribe(["topic_meters"]).await?; + // ANCHOR_END: subscribe + + // ANCHOR: consume + { + let mut stream = consumer.stream_with_timeout(Timeout::from_secs(1)); + + while let Some((offset, message)) = stream.try_next().await? { + + let topic: &str = offset.topic(); + let database = offset.database(); + let vgroup_id = offset.vgroup_id(); + log::debug!( + "topic: {}, database: {}, vgroup_id: {}", + topic, + database, + vgroup_id + ); + + match message { + MessageSet::Meta(meta) => { + log::info!("Meta"); + let raw = meta.as_raw_meta().await?; + taos.write_raw_meta(&raw).await?; + + let json = meta.as_json_meta().await?; + let sql = json.to_string(); + if let Err(err) = taos.exec(sql).await { + println!("maybe error: {}", err); + } + } + MessageSet::Data(data) => { + log::info!("Data"); + while let Some(data) = data.fetch_raw_block().await? { + log::debug!("data: {:?}", data); + } + } + MessageSet::MetaData(meta, data) => { + log::info!("MetaData"); + let raw = meta.as_raw_meta().await?; + taos.write_raw_meta(&raw).await?; + + let json = meta.as_json_meta().await?; + let sql = json.to_string(); + if let Err(err) = taos.exec(sql).await { + println!("maybe error: {}", err); + } + + while let Some(data) = data.fetch_raw_block().await? { + log::debug!("data: {:?}", data); + } + } + } + consumer.commit(offset).await?; + } + } + // ANCHOR_END: consume + + // ANCHOR: assignments + let assignments = consumer.assignments().await.unwrap(); + log::info!("assignments: {:?}", assignments); + // ANCHOR_END: assignments + + // seek offset + for topic_vec_assignment in assignments { + let topic = &topic_vec_assignment.0; + let vec_assignment = topic_vec_assignment.1; + for assignment in vec_assignment { + let vgroup_id = assignment.vgroup_id(); + let current = assignment.current_offset(); + let begin = assignment.begin(); + let end = assignment.end(); + log::debug!( + "topic: {}, vgroup_id: {}, current offset: {} begin {}, end: {}", + topic, + vgroup_id, + current, + begin, + end + ); + // ANCHOR: seek_offset + let res = consumer.offset_seek(topic, vgroup_id, end).await; + if res.is_err() { + log::error!("seek offset error: {:?}", res); + let a = consumer.assignments().await.unwrap(); + log::error!("assignments: {:?}", a); + } + // ANCHOR_END: seek_offset + } + + let topic_assignment = consumer.topic_assignment(topic).await; + log::debug!("topic assignment: {:?}", topic_assignment); + } + + // after seek offset + let assignments = consumer.assignments().await.unwrap(); + log::info!("after seek offset assignments: {:?}", assignments); + + // ANCHOR: unsubscribe + consumer.unsubscribe().await; + // ANCHOR_END: unsubscribe + + tokio::time::sleep(Duration::from_secs(1)).await; + + taos.exec_many([ + "drop database db2", + "drop topic topic_meters", + "drop database power", + ]) + .await?; + Ok(()) +} diff --git a/docs/zh/08-develop/04-schemaless.md b/docs/zh/08-develop/04-schemaless.md index 7a5730df46..9c136cb109 100644 --- a/docs/zh/08-develop/04-schemaless.md +++ b/docs/zh/08-develop/04-schemaless.md @@ -161,7 +161,7 @@ st,t1=3,t2=4,t3=t3 c1=3i64,c6="passit" 1626006833640000000 ### Websocket 连接 - + ```java From 251d9ecab1bcbfb1ca5da0c520ea7e793b96a925 Mon Sep 17 00:00:00 2001 From: t_max <1172915550@qq.com> Date: Fri, 2 Aug 2024 14:28:24 +0800 Subject: [PATCH 04/15] docs: add go and csharp example --- docs/en/07-develop/01-connect/index.md | 2 +- docs/examples/csharp/connect/Program.cs | 28 +- docs/examples/csharp/csharp.sln | 18 + docs/examples/csharp/nativesml/Program.cs | 57 + .../csharp/nativesml/nativesml.csproj | 13 + .../obj/nativesml.csproj.nuget.dgspec.json | 67 + .../obj/nativesml.csproj.nuget.g.props | 15 + .../obj/nativesml.csproj.nuget.g.targets | 2 + .../csharp/nativesml/obj/project.assets.json | 149 +++ .../csharp/nativesml/obj/project.nuget.cache | 11 + .../nativesml/obj/project.packagespec.json | 1 + .../obj/rider.project.model.nuget.info | 1 + .../nativesml/obj/rider.project.restore.info | 1 + docs/examples/csharp/optsJSON/Program.cs | 55 +- docs/examples/csharp/query/Program.cs | 3 +- docs/examples/csharp/sqlInsert/Program.cs | 145 ++- docs/examples/csharp/stmtInsert/Program.cs | 74 +- docs/examples/csharp/subscribe/Program.cs | 243 +++- docs/examples/csharp/wsConnect/Program.cs | 28 +- docs/examples/csharp/wsInsert/Program.cs | 181 ++- docs/examples/csharp/wsQuery/Program.cs | 3 +- docs/examples/csharp/wsStmt/Program.cs | 76 +- docs/examples/csharp/wssml/Program.cs | 57 + .../csharp/wssml/obj/project.assets.json | 149 +++ .../csharp/wssml/obj/project.nuget.cache | 11 + .../csharp/wssml/obj/project.packagespec.json | 1 + .../wssml/obj/rider.project.model.nuget.info | 1 + .../wssml/obj/rider.project.restore.info | 1 + .../wssml/obj/wssml.csproj.nuget.dgspec.json | 67 + .../wssml/obj/wssml.csproj.nuget.g.props | 15 + .../wssml/obj/wssml.csproj.nuget.g.targets | 2 + docs/examples/csharp/wssml/wssml.csproj | 12 + docs/examples/csharp/wssubscribe/Program.cs | 229 ++++ .../wssubscribe/obj/project.assets.json | 150 +++ .../wssubscribe/obj/project.nuget.cache | 11 + .../wssubscribe/obj/project.packagespec.json | 1 + .../obj/rider.project.model.nuget.info | 1 + .../obj/rider.project.restore.info | 1 + .../obj/wssubscribe.csproj.nuget.dgspec.json | 68 + .../obj/wssubscribe.csproj.nuget.g.props | 18 + .../obj/wssubscribe.csproj.nuget.g.targets | 2 + .../csharp/wssubscribe/wssubscribe.csproj | 12 + docs/examples/go/connect/afconn/main.go | 2 +- docs/examples/go/connect/cgoexample/main.go | 7 +- docs/examples/go/connect/connpool/main.go | 33 + docs/examples/go/connect/restexample/main.go | 7 +- docs/examples/go/connect/wsexample/main.go | 23 + docs/examples/go/go.mod | 9 +- docs/examples/go/go.sum | 12 +- docs/examples/go/queryreqid/main.go | 55 + docs/examples/go/schemaless/native/main.go | 41 + docs/examples/go/schemaless/ws/main.go | 57 + docs/examples/go/sqlquery/main.go | 88 ++ docs/examples/go/stmt/native/main.go | 82 ++ docs/examples/go/stmt/ws/main.go | 102 ++ docs/examples/go/tmq/native/main.go | 132 ++ docs/examples/go/tmq/ws/main.go | 137 ++ docs/zh/08-develop/01-connect/index.md | 139 +- docs/zh/08-develop/02-sql.md | 80 ++ docs/zh/08-develop/04-schemaless.md | 43 +- docs/zh/08-develop/05-stmt.md | 16 +- docs/zh/08-develop/07-tmq.md | 121 +- docs/zh/14-reference/05-connector/20-go.mdx | 310 +---- .../14-reference/05-connector/40-csharp.mdx | 1158 +---------------- 64 files changed, 2928 insertions(+), 1708 deletions(-) create mode 100644 docs/examples/csharp/nativesml/Program.cs create mode 100644 docs/examples/csharp/nativesml/nativesml.csproj create mode 100644 docs/examples/csharp/nativesml/obj/nativesml.csproj.nuget.dgspec.json create mode 100644 docs/examples/csharp/nativesml/obj/nativesml.csproj.nuget.g.props create mode 100644 docs/examples/csharp/nativesml/obj/nativesml.csproj.nuget.g.targets create mode 100644 docs/examples/csharp/nativesml/obj/project.assets.json create mode 100644 docs/examples/csharp/nativesml/obj/project.nuget.cache create mode 100644 docs/examples/csharp/nativesml/obj/project.packagespec.json create mode 100644 docs/examples/csharp/nativesml/obj/rider.project.model.nuget.info create mode 100644 docs/examples/csharp/nativesml/obj/rider.project.restore.info create mode 100644 docs/examples/csharp/wssml/Program.cs create mode 100644 docs/examples/csharp/wssml/obj/project.assets.json create mode 100644 docs/examples/csharp/wssml/obj/project.nuget.cache create mode 100644 docs/examples/csharp/wssml/obj/project.packagespec.json create mode 100644 docs/examples/csharp/wssml/obj/rider.project.model.nuget.info create mode 100644 docs/examples/csharp/wssml/obj/rider.project.restore.info create mode 100644 docs/examples/csharp/wssml/obj/wssml.csproj.nuget.dgspec.json create mode 100644 docs/examples/csharp/wssml/obj/wssml.csproj.nuget.g.props create mode 100644 docs/examples/csharp/wssml/obj/wssml.csproj.nuget.g.targets create mode 100644 docs/examples/csharp/wssml/wssml.csproj create mode 100644 docs/examples/csharp/wssubscribe/Program.cs create mode 100644 docs/examples/csharp/wssubscribe/obj/project.assets.json create mode 100644 docs/examples/csharp/wssubscribe/obj/project.nuget.cache create mode 100644 docs/examples/csharp/wssubscribe/obj/project.packagespec.json create mode 100644 docs/examples/csharp/wssubscribe/obj/rider.project.model.nuget.info create mode 100644 docs/examples/csharp/wssubscribe/obj/rider.project.restore.info create mode 100644 docs/examples/csharp/wssubscribe/obj/wssubscribe.csproj.nuget.dgspec.json create mode 100644 docs/examples/csharp/wssubscribe/obj/wssubscribe.csproj.nuget.g.props create mode 100644 docs/examples/csharp/wssubscribe/obj/wssubscribe.csproj.nuget.g.targets create mode 100644 docs/examples/csharp/wssubscribe/wssubscribe.csproj create mode 100644 docs/examples/go/connect/connpool/main.go create mode 100644 docs/examples/go/connect/wsexample/main.go create mode 100644 docs/examples/go/queryreqid/main.go create mode 100644 docs/examples/go/schemaless/native/main.go create mode 100644 docs/examples/go/schemaless/ws/main.go create mode 100644 docs/examples/go/sqlquery/main.go create mode 100644 docs/examples/go/stmt/native/main.go create mode 100644 docs/examples/go/stmt/ws/main.go create mode 100644 docs/examples/go/tmq/native/main.go create mode 100644 docs/examples/go/tmq/ws/main.go diff --git a/docs/en/07-develop/01-connect/index.md b/docs/en/07-develop/01-connect/index.md index ec3ed7b6dd..90b63d96e3 100644 --- a/docs/en/07-develop/01-connect/index.md +++ b/docs/en/07-develop/01-connect/index.md @@ -172,7 +172,7 @@ npm install @tdengine/rest Just need to add the reference to [TDengine.Connector](https://www.nuget.org/packages/TDengine.Connector/) in the project configuration file. -```xml title=csharp.csproj {12} +```xml title=csharp.csproj diff --git a/docs/examples/csharp/connect/Program.cs b/docs/examples/csharp/connect/Program.cs index 0152b61b03..697871573c 100644 --- a/docs/examples/csharp/connect/Program.cs +++ b/docs/examples/csharp/connect/Program.cs @@ -3,16 +3,34 @@ using TDengine.Driver.Client; namespace TDengineExample { - internal class ConnectExample { + // ANCHOR: main static void Main(String[] args) { - var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) + try { - Console.WriteLine("connected"); + // Connect to TDengine server using Native + var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); + // Open connection with using block, it will close the connection automatically + using (var client = DbDriver.Open(builder)) + { + Console.WriteLine("connected"); + } + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; } } + // ANCHOR_END: main } -} +} \ No newline at end of file diff --git a/docs/examples/csharp/csharp.sln b/docs/examples/csharp/csharp.sln index 59c198b4c9..3e8074122c 100644 --- a/docs/examples/csharp/csharp.sln +++ b/docs/examples/csharp/csharp.sln @@ -27,6 +27,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wsStmt", "wsStmt\wsStmt.csp EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "sqlinsert", "sqlInsert\sqlinsert.csproj", "{CD24BD12-8550-4627-A11D-707B446F48C3}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nativesml", "nativesml\nativesml.csproj", "{18ADDBE8-B266-4A66-8CC5-CFF80B530EFD}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wssml", "wssml\wssml.csproj", "{C3E62FDB-CCBC-4F72-ACF6-D3B2C39630E3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wssubscribe", "wssubscribe\wssubscribe.csproj", "{CB4BCBA5-C758-433F-8B90-7389F59E46BD}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -84,5 +90,17 @@ Global {CD24BD12-8550-4627-A11D-707B446F48C3}.Debug|Any CPU.Build.0 = Debug|Any CPU {CD24BD12-8550-4627-A11D-707B446F48C3}.Release|Any CPU.ActiveCfg = Release|Any CPU {CD24BD12-8550-4627-A11D-707B446F48C3}.Release|Any CPU.Build.0 = Release|Any CPU + {18ADDBE8-B266-4A66-8CC5-CFF80B530EFD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {18ADDBE8-B266-4A66-8CC5-CFF80B530EFD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {18ADDBE8-B266-4A66-8CC5-CFF80B530EFD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {18ADDBE8-B266-4A66-8CC5-CFF80B530EFD}.Release|Any CPU.Build.0 = Release|Any CPU + {C3E62FDB-CCBC-4F72-ACF6-D3B2C39630E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C3E62FDB-CCBC-4F72-ACF6-D3B2C39630E3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C3E62FDB-CCBC-4F72-ACF6-D3B2C39630E3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C3E62FDB-CCBC-4F72-ACF6-D3B2C39630E3}.Release|Any CPU.Build.0 = Release|Any CPU + {CB4BCBA5-C758-433F-8B90-7389F59E46BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CB4BCBA5-C758-433F-8B90-7389F59E46BD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CB4BCBA5-C758-433F-8B90-7389F59E46BD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CB4BCBA5-C758-433F-8B90-7389F59E46BD}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/docs/examples/csharp/nativesml/Program.cs b/docs/examples/csharp/nativesml/Program.cs new file mode 100644 index 0000000000..c4925041a1 --- /dev/null +++ b/docs/examples/csharp/nativesml/Program.cs @@ -0,0 +1,57 @@ +using TDengine.Driver; +using TDengine.Driver.Client; + +namespace TDengineExample +{ + internal class NativeSMLExample + { + // ANCHOR: main + public static void Main(string[] args) + { + var host = "127.0.0.1"; + + var lineDemo = + "meters,groupid=2,location=California.SanFrancisco current=10.3000002f64,voltage=219i32,phase=0.31f64 1626006833639"; + + var telnetDemo = "metric_telnet 1707095283260 4 host=host0 interface=eth0"; + + var jsonDemo = + "{\"metric\": \"metric_json\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}"; + try + { + var builder = + new ConnectionStringBuilder( + $"host={host};port=6030;username=root;password=taosdata"); + using (var client = DbDriver.Open(builder)) + { + // create database + client.Exec("CREATE DATABASE IF NOT EXISTS power"); + // use database + client.Exec("USE power"); + // insert influx line protocol data + client.SchemalessInsert(new[]{lineDemo}, TDengineSchemalessProtocol.TSDB_SML_LINE_PROTOCOL, + TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS, 0, ReqId.GetReqId()); + // insert opentsdb telnet protocol data + client.SchemalessInsert(new[]{telnetDemo}, TDengineSchemalessProtocol.TSDB_SML_TELNET_PROTOCOL, + TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS, 0, ReqId.GetReqId()); + // insert json data + client.SchemalessInsert(new []{jsonDemo}, TDengineSchemalessProtocol.TSDB_SML_JSON_PROTOCOL, + TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_NOT_CONFIGURED, 0, ReqId.GetReqId()); + } + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + } + // ANCHOR_END: main + } +} \ No newline at end of file diff --git a/docs/examples/csharp/nativesml/nativesml.csproj b/docs/examples/csharp/nativesml/nativesml.csproj new file mode 100644 index 0000000000..afad009614 --- /dev/null +++ b/docs/examples/csharp/nativesml/nativesml.csproj @@ -0,0 +1,13 @@ + + + + Exe + net6.0 + enable + enable + + + + + + diff --git a/docs/examples/csharp/nativesml/obj/nativesml.csproj.nuget.dgspec.json b/docs/examples/csharp/nativesml/obj/nativesml.csproj.nuget.dgspec.json new file mode 100644 index 0000000000..74b8259305 --- /dev/null +++ b/docs/examples/csharp/nativesml/obj/nativesml.csproj.nuget.dgspec.json @@ -0,0 +1,67 @@ +{ + "format": 1, + "restore": { + "/mnt/e/github/TDengine/docs/examples/csharp/nativesml/nativesml.csproj": {} + }, + "projects": { + "/mnt/e/github/TDengine/docs/examples/csharp/nativesml/nativesml.csproj": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "/mnt/e/github/TDengine/docs/examples/csharp/nativesml/nativesml.csproj", + "projectName": "nativesml", + "projectPath": "/mnt/e/github/TDengine/docs/examples/csharp/nativesml/nativesml.csproj", + "packagesPath": "/root/.nuget/packages/", + "outputPath": "/mnt/e/github/TDengine/docs/examples/csharp/nativesml/obj/", + "projectStyle": "PackageReference", + "configFilePaths": [ + "/root/.nuget/NuGet/NuGet.Config" + ], + "originalTargetFrameworks": [ + "net6.0" + ], + "sources": { + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "net6.0": { + "targetAlias": "net6.0", + "projectReferences": {} + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + } + }, + "frameworks": { + "net6.0": { + "targetAlias": "net6.0", + "dependencies": { + "TDengine.Connector": { + "target": "Package", + "version": "[3.1.*, )" + } + }, + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48", + "net481" + ], + "assetTargetFallback": true, + "warn": true, + "frameworkReferences": { + "Microsoft.NETCore.App": { + "privateAssets": "all" + } + }, + "runtimeIdentifierGraphPath": "/root/.dotnet/sdk/8.0.100/RuntimeIdentifierGraph.json" + } + } + } + } +} \ No newline at end of file diff --git a/docs/examples/csharp/nativesml/obj/nativesml.csproj.nuget.g.props b/docs/examples/csharp/nativesml/obj/nativesml.csproj.nuget.g.props new file mode 100644 index 0000000000..a270b60d2c --- /dev/null +++ b/docs/examples/csharp/nativesml/obj/nativesml.csproj.nuget.g.props @@ -0,0 +1,15 @@ + + + + True + NuGet + $(MSBuildThisFileDirectory)project.assets.json + /root/.nuget/packages/ + /root/.nuget/packages/ + PackageReference + 6.8.0 + + + + + \ No newline at end of file diff --git a/docs/examples/csharp/nativesml/obj/nativesml.csproj.nuget.g.targets b/docs/examples/csharp/nativesml/obj/nativesml.csproj.nuget.g.targets new file mode 100644 index 0000000000..35a7576c5a --- /dev/null +++ b/docs/examples/csharp/nativesml/obj/nativesml.csproj.nuget.g.targets @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/docs/examples/csharp/nativesml/obj/project.assets.json b/docs/examples/csharp/nativesml/obj/project.assets.json new file mode 100644 index 0000000000..652bbd6688 --- /dev/null +++ b/docs/examples/csharp/nativesml/obj/project.assets.json @@ -0,0 +1,149 @@ +{ + "version": 3, + "targets": { + "net6.0": { + "Newtonsoft.Json/13.0.3": { + "type": "package", + "compile": { + "lib/net6.0/Newtonsoft.Json.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net6.0/Newtonsoft.Json.dll": { + "related": ".xml" + } + } + }, + "TDengine.Connector/3.1.3": { + "type": "package", + "dependencies": { + "Newtonsoft.Json": "13.0.3" + }, + "compile": { + "lib/net6.0/TDengine.dll": {} + }, + "runtime": { + "lib/net6.0/TDengine.dll": {} + } + } + } + }, + "libraries": { + "Newtonsoft.Json/13.0.3": { + "sha512": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==", + "type": "package", + "path": "newtonsoft.json/13.0.3", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "LICENSE.md", + "README.md", + "lib/net20/Newtonsoft.Json.dll", + "lib/net20/Newtonsoft.Json.xml", + "lib/net35/Newtonsoft.Json.dll", + "lib/net35/Newtonsoft.Json.xml", + "lib/net40/Newtonsoft.Json.dll", + "lib/net40/Newtonsoft.Json.xml", + "lib/net45/Newtonsoft.Json.dll", + "lib/net45/Newtonsoft.Json.xml", + "lib/net6.0/Newtonsoft.Json.dll", + "lib/net6.0/Newtonsoft.Json.xml", + "lib/netstandard1.0/Newtonsoft.Json.dll", + "lib/netstandard1.0/Newtonsoft.Json.xml", + "lib/netstandard1.3/Newtonsoft.Json.dll", + "lib/netstandard1.3/Newtonsoft.Json.xml", + "lib/netstandard2.0/Newtonsoft.Json.dll", + "lib/netstandard2.0/Newtonsoft.Json.xml", + "newtonsoft.json.13.0.3.nupkg.sha512", + "newtonsoft.json.nuspec", + "packageIcon.png" + ] + }, + "TDengine.Connector/3.1.3": { + "sha512": "dDX+Oex4I0X9yCalU0/YyUN0ecy+8X5xj6N8CoqeLrU6ICYDZgilSGQK9Fh3qmLobhGQvOJWwDpoO73rryHU5Q==", + "type": "package", + "path": "tdengine.connector/3.1.3", + "files": [ + ".nupkg.metadata", + "docs/README.md", + "image/logo.jpg", + "lib/net45/TDengine.dll", + "lib/net451/TDengine.dll", + "lib/net5.0/TDengine.dll", + "lib/net6.0/TDengine.dll", + "lib/netstandard2.0/TDengine.dll", + "lib/netstandard2.1/TDengine.dll", + "tdengine.connector.3.1.3.nupkg.sha512", + "tdengine.connector.nuspec" + ] + } + }, + "projectFileDependencyGroups": { + "net6.0": [ + "TDengine.Connector >= 3.1.*" + ] + }, + "packageFolders": { + "/root/.nuget/packages/": {} + }, + "project": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "/mnt/e/github/TDengine/docs/examples/csharp/nativesml/nativesml.csproj", + "projectName": "nativesml", + "projectPath": "/mnt/e/github/TDengine/docs/examples/csharp/nativesml/nativesml.csproj", + "packagesPath": "/root/.nuget/packages/", + "outputPath": "/mnt/e/github/TDengine/docs/examples/csharp/nativesml/obj/", + "projectStyle": "PackageReference", + "configFilePaths": [ + "/root/.nuget/NuGet/NuGet.Config" + ], + "originalTargetFrameworks": [ + "net6.0" + ], + "sources": { + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "net6.0": { + "targetAlias": "net6.0", + "projectReferences": {} + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + } + }, + "frameworks": { + "net6.0": { + "targetAlias": "net6.0", + "dependencies": { + "TDengine.Connector": { + "target": "Package", + "version": "[3.1.*, )" + } + }, + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48", + "net481" + ], + "assetTargetFallback": true, + "warn": true, + "frameworkReferences": { + "Microsoft.NETCore.App": { + "privateAssets": "all" + } + }, + "runtimeIdentifierGraphPath": "/root/.dotnet/sdk/8.0.100/RuntimeIdentifierGraph.json" + } + } + } +} \ No newline at end of file diff --git a/docs/examples/csharp/nativesml/obj/project.nuget.cache b/docs/examples/csharp/nativesml/obj/project.nuget.cache new file mode 100644 index 0000000000..3c34e78160 --- /dev/null +++ b/docs/examples/csharp/nativesml/obj/project.nuget.cache @@ -0,0 +1,11 @@ +{ + "version": 2, + "dgSpecHash": "xbVzGVQru/qLTE5UBOQoTSR5C+6GFj/M4fcB1h/3W6PsWOVoFQLbV4fwAAKt5f5BKxrV1phiwzm2zGYK0fpXBQ==", + "success": true, + "projectFilePath": "/mnt/e/github/TDengine/docs/examples/csharp/nativesml/nativesml.csproj", + "expectedPackageFiles": [ + "/root/.nuget/packages/newtonsoft.json/13.0.3/newtonsoft.json.13.0.3.nupkg.sha512", + "/root/.nuget/packages/tdengine.connector/3.1.3/tdengine.connector.3.1.3.nupkg.sha512" + ], + "logs": [] +} \ No newline at end of file diff --git a/docs/examples/csharp/nativesml/obj/project.packagespec.json b/docs/examples/csharp/nativesml/obj/project.packagespec.json new file mode 100644 index 0000000000..8c110899d3 --- /dev/null +++ b/docs/examples/csharp/nativesml/obj/project.packagespec.json @@ -0,0 +1 @@ +"restore":{"projectUniqueName":"E:\\github\\TDengine\\docs\\examples\\csharp\\nativesml\\nativesml.csproj","projectName":"nativesml","projectPath":"E:\\github\\TDengine\\docs\\examples\\csharp\\nativesml\\nativesml.csproj","outputPath":"E:\\github\\TDengine\\docs\\examples\\csharp\\nativesml\\obj\\","projectStyle":"PackageReference","originalTargetFrameworks":["net6.0"],"sources":{"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\":{},"E:\\github\\taos-connector-dotnet\\src\\resource":{},"https://api.nuget.org/v3/index.json":{}},"frameworks":{"net6.0":{"targetAlias":"net6.0","projectReferences":{}}},"warningProperties":{"warnAsError":["NU1605"]}}"frameworks":{"net6.0":{"targetAlias":"net6.0","dependencies":{"TDengine.Connector":{"target":"Package","version":"[3.1.*, )"}},"imports":["net461","net462","net47","net471","net472","net48","net481"],"assetTargetFallback":true,"warn":true,"frameworkReferences":{"Microsoft.NETCore.App":{"privateAssets":"all"}},"runtimeIdentifierGraphPath":"C:\\Program Files\\dotnet\\sdk\\8.0.202\\RuntimeIdentifierGraph.json"}} \ No newline at end of file diff --git a/docs/examples/csharp/nativesml/obj/rider.project.model.nuget.info b/docs/examples/csharp/nativesml/obj/rider.project.model.nuget.info new file mode 100644 index 0000000000..c922ea143f --- /dev/null +++ b/docs/examples/csharp/nativesml/obj/rider.project.model.nuget.info @@ -0,0 +1 @@ +17225691407520754 \ No newline at end of file diff --git a/docs/examples/csharp/nativesml/obj/rider.project.restore.info b/docs/examples/csharp/nativesml/obj/rider.project.restore.info new file mode 100644 index 0000000000..7559664705 --- /dev/null +++ b/docs/examples/csharp/nativesml/obj/rider.project.restore.info @@ -0,0 +1 @@ +17225689181017775 \ No newline at end of file diff --git a/docs/examples/csharp/optsJSON/Program.cs b/docs/examples/csharp/optsJSON/Program.cs index a93c4dad0f..747d89c0d3 100644 --- a/docs/examples/csharp/optsJSON/Program.cs +++ b/docs/examples/csharp/optsJSON/Program.cs @@ -7,22 +7,51 @@ namespace TDengineExample { public static void Main(string[] args) { - var builder = - new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) + // ANCHOR: main + var host = "127.0.0.1"; + + var lineDemo = + "meters,groupid=2,location=California.SanFrancisco current=10.3000002f64,voltage=219i32,phase=0.31f64 1626006833639"; + + var telnetDemo = "metric_telnet 1707095283260 4 host=host0 interface=eth0"; + + var jsonDemo = + "{\"metric\": \"metric_json\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}"; + try { - client.Exec("CREATE DATABASE test WAL_RETENTION_PERIOD 3600"); - client.Exec("use test"); - string[] lines = + var builder = + new ConnectionStringBuilder( + $"protocol=WebSocket;host={host};port=6041;username=root;password=taosdata"); + using (var client = DbDriver.Open(builder)) { - "[{\"metric\": \"meters.current\", \"timestamp\": 1648432611249, \"value\": 10.3, \"tags\": {\"location\": \"California.SanFrancisco\", \"groupid\": 2}}," + - " {\"metric\": \"meters.voltage\", \"timestamp\": 1648432611249, \"value\": 219, \"tags\": {\"location\": \"California.LosAngeles\", \"groupid\": 1}}, " + - "{\"metric\": \"meters.current\", \"timestamp\": 1648432611250, \"value\": 12.6, \"tags\": {\"location\": \"California.SanFrancisco\", \"groupid\": 2}}," + - " {\"metric\": \"meters.voltage\", \"timestamp\": 1648432611250, \"value\": 221, \"tags\": {\"location\": \"California.LosAngeles\", \"groupid\": 1}}]" - }; - client.SchemalessInsert(lines, TDengineSchemalessProtocol.TSDB_SML_JSON_PROTOCOL, - TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS, 0, ReqId.GetReqId()); + // create database + client.Exec("CREATE DATABASE IF NOT EXISTS power"); + // use database + client.Exec("USE power"); + // insert influx line protocol data + client.SchemalessInsert(new[]{lineDemo}, TDengineSchemalessProtocol.TSDB_SML_LINE_PROTOCOL, + TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS, 0, ReqId.GetReqId()); + // insert opentsdb telnet protocol data + client.SchemalessInsert(new[]{telnetDemo}, TDengineSchemalessProtocol.TSDB_SML_TELNET_PROTOCOL, + TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS, 0, ReqId.GetReqId()); + // insert json data + client.SchemalessInsert(new []{jsonDemo}, TDengineSchemalessProtocol.TSDB_SML_JSON_PROTOCOL, + TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_NOT_CONFIGURED, 0, ReqId.GetReqId()); + } } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + // ANCHOR_END: main } } } \ No newline at end of file diff --git a/docs/examples/csharp/query/Program.cs b/docs/examples/csharp/query/Program.cs index 4c354d9a5e..c901760f52 100644 --- a/docs/examples/csharp/query/Program.cs +++ b/docs/examples/csharp/query/Program.cs @@ -13,8 +13,7 @@ namespace TDengineExample { try { - client.Exec("use power"); - string query = "SELECT * FROM meters"; + string query = "SELECT * FROM power.meters"; using (var rows = client.Query(query)) { while (rows.Read()) diff --git a/docs/examples/csharp/sqlInsert/Program.cs b/docs/examples/csharp/sqlInsert/Program.cs index c3c700aba2..0ac8d55c5e 100644 --- a/docs/examples/csharp/sqlInsert/Program.cs +++ b/docs/examples/csharp/sqlInsert/Program.cs @@ -6,42 +6,125 @@ namespace TDengineExample { internal class SQLInsertExample { - public static void Main(string[] args) { - var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) + try { - try + + var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); + using (var client = DbDriver.Open(builder)) { - client.Exec("create database power"); - client.Exec("CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); - string insertQuery = - "INSERT INTO " + - "power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " + - "VALUES " + - "('2023-10-03 14:38:05.000', 10.30000, 219, 0.31000) " + - "('2023-10-03 14:38:15.000', 12.60000, 218, 0.33000) " + - "('2023-10-03 14:38:16.800', 12.30000, 221, 0.31000) " + - "power.d1002 USING power.meters TAGS(3, 'California.SanFrancisco') " + - "VALUES " + - "('2023-10-03 14:38:16.650', 10.30000, 218, 0.25000) " + - "power.d1003 USING power.meters TAGS(2,'California.LosAngeles') " + - "VALUES " + - "('2023-10-03 14:38:05.500', 11.80000, 221, 0.28000) " + - "('2023-10-03 14:38:16.600', 13.40000, 223, 0.29000) " + - "power.d1004 USING power.meters TAGS(3,'California.LosAngeles') " + - "VALUES " + - "('2023-10-03 14:38:05.000', 10.80000, 223, 0.29000) " + - "('2023-10-03 14:38:06.500', 11.50000, 221, 0.35000)"; - client.Exec(insertQuery); - } - catch (Exception e) - { - Console.WriteLine(e.ToString()); - throw; + CreateDatabaseAndTable(client); + InsertData(client); + QueryData(client); } } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + } + + private static void CreateDatabaseAndTable(ITDengineClient client) + { + // ANCHOR: create_db_and_table + try + { + // create database + var affected = client.Exec("CREATE DATABASE IF NOT EXISTS power"); + Console.WriteLine($"Create database power, affected rows: {affected}"); + // create table + affected = client.Exec( + "CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); + Console.WriteLine($"Create table meters, affected rows: {affected}"); + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + // ANCHOR_END: create_db_and_table + } + + private static void InsertData(ITDengineClient client) + { + // ANCHOR: insert_data + try + { + // insert data + var insertQuery = "INSERT INTO " + + "power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " + + "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(3, 'California.SanFrancisco') " + + "VALUES " + + "(NOW + 1a, 10.30000, 218, 0.25000) "; + var affectedRows = client.Exec(insertQuery); + Console.WriteLine("inserted into " + affectedRows + " rows to power.meters successfully."); + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + // ANCHOR_END: insert_data + } + + private static void QueryData(ITDengineClient client) + { + // ANCHOR: query_data + try + { + // query data + var query = "SELECT ts, current, location FROM power.meters limit 100"; + using (var rows = client.Query(query)) + { + while (rows.Read()) + { + var ts = (DateTime)rows.GetValue(0); + var current = (float)rows.GetValue(1); + var location = Encoding.UTF8.GetString((byte[])rows.GetValue(2)); + Console.WriteLine($"ts: {ts:yyyy-MM-dd HH:mm:ss.fff}, current: {current}, location: {location}"); + } + } + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + // ANCHOR_END: query_data } } -} +} \ No newline at end of file diff --git a/docs/examples/csharp/stmtInsert/Program.cs b/docs/examples/csharp/stmtInsert/Program.cs index e6b11a63e4..5b4cf2677c 100644 --- a/docs/examples/csharp/stmtInsert/Program.cs +++ b/docs/examples/csharp/stmtInsert/Program.cs @@ -5,34 +5,72 @@ namespace TDengineExample { internal class StmtInsertExample { + // ANCHOR: main public static void Main(string[] args) { - var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) + var host = "127.0.0.1"; + var numOfSubTable = 10; + var numOfRow = 10; + var random = new Random(); + try { - try + var builder = new ConnectionStringBuilder($"host={host};port=6030;username=root;password=taosdata"); + using (var client = DbDriver.Open(builder)) { - client.Exec($"create database power"); + // create database + client.Exec("CREATE DATABASE IF NOT EXISTS power"); + // use database + client.Exec("USE power"); + // create table client.Exec( - "CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); + "CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); using (var stmt = client.StmtInit()) { - stmt.Prepare( - "Insert into power.d1001 using power.meters tags(2,'California.SanFrancisco') values(?,?,?,?)"); - var ts = new DateTime(2023, 10, 03, 14, 38, 05, 000); - stmt.BindRow(new object[] { ts, (float)10.30000, (int)219, (float)0.31000 }); - stmt.AddBatch(); - stmt.Exec(); - var affected = stmt.Affected(); - Console.WriteLine($"affected rows: {affected}"); + String sql = "INSERT INTO ? USING meters TAGS(?,?) VALUES (?,?,?,?)"; + stmt.Prepare(sql); + for (int i = 1; i <= numOfSubTable; i++) + { + var tableName = $"d_bind_{i}"; + // set table name + stmt.SetTableName(tableName); + // set tags + stmt.SetTags(new object[] { i, $"location_{i}" }); + var current = DateTime.Now; + // bind rows + for (int j = 0; j < numOfRow; j++) + { + stmt.BindRow(new object[] + { + current.Add(TimeSpan.FromMilliseconds(j)), + random.NextSingle() * 30, + random.Next(300), + random.NextSingle() + }); + } + // add batch + stmt.AddBatch(); + // execute + stmt.Exec(); + // get affected rows + var affectedRows = stmt.Affected(); + Console.WriteLine($"table {tableName} insert {affectedRows} rows."); + } } } - catch (Exception e) - { - Console.WriteLine(e); - throw; - } + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; } } + // ANCHOR_END: main } } \ No newline at end of file diff --git a/docs/examples/csharp/subscribe/Program.cs b/docs/examples/csharp/subscribe/Program.cs index d7c1a52117..80e25f1acf 100644 --- a/docs/examples/csharp/subscribe/Program.cs +++ b/docs/examples/csharp/subscribe/Program.cs @@ -1,5 +1,4 @@ - -using TDengine.Driver; +using TDengine.Driver; using TDengine.Driver.Client; using TDengine.TMQ; @@ -9,65 +8,221 @@ namespace TMQExample { public static void Main(string[] args) { - var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) + try { - try + var builder = new ConnectionStringBuilder("host=127.0.0.1;port=6030;username=root;password=taosdata"); + using (var client = DbDriver.Open(builder)) { - client.Exec("CREATE DATABASE power"); + client.Exec("CREATE DATABASE IF NOT EXISTS power"); client.Exec("USE power"); client.Exec( - "CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); - client.Exec("CREATE TOPIC topic_meters as SELECT * from power.meters"); - var cfg = new Dictionary() - { - { "group.id", "group1" }, - { "auto.offset.reset", "latest" }, - { "td.connect.ip", "127.0.0.1" }, - { "td.connect.user", "root" }, - { "td.connect.pass", "taosdata" }, - { "td.connect.port", "6030" }, - { "client.id", "tmq_example" }, - { "enable.auto.commit", "true" }, - { "msg.with.table.name", "false" }, - }; - var consumer = new ConsumerBuilder>(cfg).Build(); - consumer.Subscribe(new List() { "topic_meters" }); + "CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); + client.Exec("CREATE TOPIC IF NOT EXISTS topic_meters as SELECT * from power.meters"); + var consumer = CreateConsumer(); + // insert data Task.Run(InsertData); - while (true) - { - using (var cr = consumer.Consume(500)) - { - if (cr == null) continue; - foreach (var message in cr.Message) - { - Console.WriteLine( - $"message {{{((DateTime)message.Value["ts"]).ToString("yyyy-MM-dd HH:mm:ss.fff")}, " + - $"{message.Value["current"]}, {message.Value["voltage"]}, {message.Value["phase"]}}}"); - } - } - } - } - catch (Exception e) - { - Console.WriteLine(e.ToString()); - throw; + // consume message + Consume(consumer); + // seek + Seek(consumer); + // commit + CommitOffset(consumer); + // close + Close(consumer); + Console.WriteLine("Done"); } } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } } static void InsertData() { - var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); + var builder = new ConnectionStringBuilder("host=127.0.0.1;port=6030;username=root;password=taosdata"); using (var client = DbDriver.Open(builder)) { while (true) { - client.Exec("INSERT into power.d1001 using power.meters tags(2,'California.SanFrancisco') values(now,11.5,219,0.30)"); + client.Exec( + "INSERT into power.d1001 using power.meters tags(2,'California.SanFrancisco') values(now,11.5,219,0.30)"); Task.Delay(1000).Wait(); } } } - } -} + static IConsumer> CreateConsumer() + { + // ANCHOR: create_consumer + // consumer config + var cfg = new Dictionary() + { + { "td.connect.port", "6030" }, + { "auto.offset.reset", "latest" }, + { "msg.with.table.name", "true" }, + { "enable.auto.commit", "true" }, + { "auto.commit.interval.ms", "1000" }, + { "group.id", "group2" }, + { "client.id", "1" }, + { "td.connect.ip", "127.0.0.1" }, + { "td.connect.user", "root" }, + { "td.connect.pass", "taosdata" }, + }; + IConsumer> consumer = null!; + try + { + // create consumer + consumer = new ConsumerBuilder>(cfg).Build(); + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + + // ANCHOR_END: create_consumer + return consumer; + } + + static void Consume(IConsumer> consumer) + { + // ANCHOR: subscribe + try + { + // subscribe + consumer.Subscribe(new List() { "topic_meters" }); + for (int i = 0; i < 50; i++) + { + // consume message with using block to ensure the result is disposed + using (var cr = consumer.Consume(100)) + { + if (cr == null) continue; + foreach (var message in cr.Message) + { + // handle message + Console.WriteLine( + $"message {{{((DateTime)message.Value["ts"]).ToString("yyyy-MM-dd HH:mm:ss.fff")}, " + + $"{message.Value["current"]}, {message.Value["voltage"]}, {message.Value["phase"]}}}"); + } + } + } + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + // ANCHOR_END: subscribe + } + + static void Seek(IConsumer> consumer) + { + // ANCHOR: seek + try + { + // get assignment + var assignment = consumer.Assignment; + // seek to the beginning + foreach (var topicPartition in assignment) + { + consumer.Seek(new TopicPartitionOffset(topicPartition.Topic, topicPartition.Partition, 0)); + } + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + // ANCHOR_END: seek + } + + static void CommitOffset(IConsumer> consumer) + { + // ANCHOR: commit_offset + for (int i = 0; i < 5; i++) + { + try + { + // consume message with using block to ensure the result is disposed + using (var cr = consumer.Consume(100)) + { + if (cr == null) continue; + // commit offset + consumer.Commit(new List + { + cr.TopicPartitionOffset, + }); + } + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + } + // ANCHOR_END: commit_offset + } + + static void Close(IConsumer> consumer) + { + // ANCHOR: close + try + { + // unsubscribe + consumer.Unsubscribe(); + // close consumer + consumer.Close(); + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + // ANCHOR_END: close + } + } +} \ No newline at end of file diff --git a/docs/examples/csharp/wsConnect/Program.cs b/docs/examples/csharp/wsConnect/Program.cs index edf0eb31e6..c7423969d8 100644 --- a/docs/examples/csharp/wsConnect/Program.cs +++ b/docs/examples/csharp/wsConnect/Program.cs @@ -6,13 +6,33 @@ namespace Examples { public class WSConnExample { + // ANCHOR: main static void Main(string[] args) { - var builder = new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) + try { - Console.WriteLine("connected"); + // Connect to TDengine server using WebSocket + var builder = new ConnectionStringBuilder( + "protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata"); + // Open connection with using block, it will close the connection automatically + using (var client = DbDriver.Open(builder)) + { + Console.WriteLine("connected"); + } + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; } } + // ANCHOR_END: main } -} +} \ No newline at end of file diff --git a/docs/examples/csharp/wsInsert/Program.cs b/docs/examples/csharp/wsInsert/Program.cs index 73136477e7..d393b775ba 100644 --- a/docs/examples/csharp/wsInsert/Program.cs +++ b/docs/examples/csharp/wsInsert/Program.cs @@ -1,4 +1,5 @@ using System; +using System.Text; using TDengine.Driver; using TDengine.Driver.Client; @@ -8,39 +9,159 @@ namespace Examples { public static void Main(string[] args) { - var builder = new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) + try { - try + var builder = new ConnectionStringBuilder("protocol=WebSocket;host=127.0.0.1;port=6041;useSSL=false;username=root;password=taosdata"); + using (var client = DbDriver.Open(builder)) { - client.Exec("create database power"); - client.Exec("CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); - string insertQuery = - "INSERT INTO " + - "power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " + - "VALUES " + - "('2023-10-03 14:38:05.000', 10.30000, 219, 0.31000) " + - "('2023-10-03 14:38:15.000', 12.60000, 218, 0.33000) " + - "('2023-10-03 14:38:16.800', 12.30000, 221, 0.31000) " + - "power.d1002 USING power.meters TAGS(3, 'California.SanFrancisco') " + - "VALUES " + - "('2023-10-03 14:38:16.650', 10.30000, 218, 0.25000) " + - "power.d1003 USING power.meters TAGS(2,'California.LosAngeles') " + - "VALUES " + - "('2023-10-03 14:38:05.500', 11.80000, 221, 0.28000) " + - "('2023-10-03 14:38:16.600', 13.40000, 223, 0.29000) " + - "power.d1004 USING power.meters TAGS(3,'California.LosAngeles') " + - "VALUES " + - "('2023-10-03 14:38:05.000', 10.80000, 223, 0.29000) " + - "('2023-10-03 14:38:06.500', 11.50000, 221, 0.35000)"; - client.Exec(insertQuery); - } - catch (Exception e) - { - Console.WriteLine(e.ToString()); - throw; + CreateDatabaseAndTable(client); + InsertData(client); + QueryData(client); + QueryWithReqId(client); } } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + } + + private static void CreateDatabaseAndTable(ITDengineClient client) + { + // ANCHOR: create_db_and_table + try + { + // create database + var affected = client.Exec("CREATE DATABASE IF NOT EXISTS power"); + Console.WriteLine($"Create database power, affected rows: {affected}"); + // create table + affected = client.Exec( + "CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); + Console.WriteLine($"Create table meters, affected rows: {affected}"); + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + // ANCHOR_END: create_db_and_table + } + + private static void InsertData(ITDengineClient client) + { + // ANCHOR: insert_data + try + { + // insert data + var insertQuery = "INSERT INTO " + + "power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " + + "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(3, 'California.SanFrancisco') " + + "VALUES " + + "(NOW + 1a, 10.30000, 218, 0.25000) "; + var affectedRows = client.Exec(insertQuery); + Console.WriteLine("inserted " + affectedRows + " rows to power.meters successfully."); + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + // ANCHOR_END: insert_data + } + + private static void QueryData(ITDengineClient client) + { + // ANCHOR: select_data + try + { + // query data + var query = "SELECT ts, current, location FROM power.meters limit 100"; + using (var rows = client.Query(query)) + { + while (rows.Read()) + { + var ts = (DateTime)rows.GetValue(0); + var current = (float)rows.GetValue(1); + var location = Encoding.UTF8.GetString((byte[])rows.GetValue(2)); + Console.WriteLine( + $"ts: {ts:yyyy-MM-dd HH:mm:ss.fff}, current: {current}, location: {location}"); + } + } + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + // ANCHOR_END: select_data + } + + private static void QueryWithReqId(ITDengineClient client) + { + // ANCHOR: query_id + try + { + // query data + var query = "SELECT ts, current, location FROM power.meters limit 1"; + // query with request id 1 + using (var rows = client.Query(query,1)) + { + while (rows.Read()) + { + var ts = (DateTime)rows.GetValue(0); + var current = (float)rows.GetValue(1); + var location = Encoding.UTF8.GetString((byte[])rows.GetValue(2)); + Console.WriteLine( + $"ts: {ts:yyyy-MM-dd HH:mm:ss.fff}, current: {current}, location: {location}"); + } + } + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + // ANCHOR_END: query_id } } -} +} \ No newline at end of file diff --git a/docs/examples/csharp/wsQuery/Program.cs b/docs/examples/csharp/wsQuery/Program.cs index 40aac24597..c58f23626c 100644 --- a/docs/examples/csharp/wsQuery/Program.cs +++ b/docs/examples/csharp/wsQuery/Program.cs @@ -14,8 +14,7 @@ namespace Examples { try { - client.Exec("use power"); - string query = "SELECT * FROM meters"; + string query = "SELECT * FROM power.meters"; using (var rows = client.Query(query)) { while (rows.Read()) diff --git a/docs/examples/csharp/wsStmt/Program.cs b/docs/examples/csharp/wsStmt/Program.cs index 5166dfea92..dfc98d17d6 100644 --- a/docs/examples/csharp/wsStmt/Program.cs +++ b/docs/examples/csharp/wsStmt/Program.cs @@ -6,36 +6,72 @@ namespace Examples { public class WSStmtExample { + // ANCHOR: main public static void Main(string[] args) { - var builder = - new ConnectionStringBuilder( - "protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) + var host = "127.0.0.1"; + var numOfSubTable = 10; + var numOfRow = 10; + var random = new Random(); + try { - try + var builder = new ConnectionStringBuilder($"protocol=WebSocket;host={host};port=6041;useSSL=false;username=root;password=taosdata"); + using (var client = DbDriver.Open(builder)) { - client.Exec($"create database power"); + // create database + client.Exec("CREATE DATABASE IF NOT EXISTS power"); + // use database + client.Exec("USE power"); + // create table client.Exec( - "CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); + "CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); using (var stmt = client.StmtInit()) { - stmt.Prepare( - "Insert into power.d1001 using power.meters tags(2,'California.SanFrancisco') values(?,?,?,?)"); - var ts = new DateTime(2023, 10, 03, 14, 38, 05, 000); - stmt.BindRow(new object[] { ts, (float)10.30000, (int)219, (float)0.31000 }); - stmt.AddBatch(); - stmt.Exec(); - var affected = stmt.Affected(); - Console.WriteLine($"affected rows: {affected}"); + String sql = "INSERT INTO ? USING meters TAGS(?,?) VALUES (?,?,?,?)"; + stmt.Prepare(sql); + for (int i = 1; i <= numOfSubTable; i++) + { + var tableName = $"d_bind_{i}"; + // set table name + stmt.SetTableName(tableName); + // set tags + stmt.SetTags(new object[] { i, $"location_{i}" }); + var current = DateTime.Now; + // bind rows + for (int j = 0; j < numOfRow; j++) + { + stmt.BindRow(new object[] + { + current.Add(TimeSpan.FromMilliseconds(j)), + random.NextSingle() * 30, + random.Next(300), + random.NextSingle() + }); + } + // add batch + stmt.AddBatch(); + // execute + stmt.Exec(); + // get affected rows + var affectedRows = stmt.Affected(); + Console.WriteLine($"table {tableName} insert {affectedRows} rows."); + } } } - catch (Exception e) - { - Console.WriteLine(e); - throw; - } + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; } } + // ANCHOR_END: main } } \ No newline at end of file diff --git a/docs/examples/csharp/wssml/Program.cs b/docs/examples/csharp/wssml/Program.cs new file mode 100644 index 0000000000..5c47c6651b --- /dev/null +++ b/docs/examples/csharp/wssml/Program.cs @@ -0,0 +1,57 @@ +using TDengine.Driver; +using TDengine.Driver.Client; + +namespace TDengineExample +{ + internal class WssmlExample + { + // ANCHOR: main + public static void Main(string[] args) + { + var host = "127.0.0.1"; + + var lineDemo = + "meters,groupid=2,location=California.SanFrancisco current=10.3000002f64,voltage=219i32,phase=0.31f64 1626006833639"; + + var telnetDemo = "metric_telnet 1707095283260 4 host=host0 interface=eth0"; + + var jsonDemo = + "{\"metric\": \"metric_json\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}"; + try + { + var builder = + new ConnectionStringBuilder( + $"protocol=WebSocket;host={host};port=6041;username=root;password=taosdata"); + using (var client = DbDriver.Open(builder)) + { + // create database + client.Exec("CREATE DATABASE IF NOT EXISTS power"); + // use database + client.Exec("USE power"); + // insert influx line protocol data + client.SchemalessInsert(new[]{lineDemo}, TDengineSchemalessProtocol.TSDB_SML_LINE_PROTOCOL, + TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS, 0, ReqId.GetReqId()); + // insert opentsdb telnet protocol data + client.SchemalessInsert(new[]{telnetDemo}, TDengineSchemalessProtocol.TSDB_SML_TELNET_PROTOCOL, + TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS, 0, ReqId.GetReqId()); + // insert json data + client.SchemalessInsert(new []{jsonDemo}, TDengineSchemalessProtocol.TSDB_SML_JSON_PROTOCOL, + TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_NOT_CONFIGURED, 0, ReqId.GetReqId()); + } + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + } + // ANCHOR_END: main + } +} \ No newline at end of file diff --git a/docs/examples/csharp/wssml/obj/project.assets.json b/docs/examples/csharp/wssml/obj/project.assets.json new file mode 100644 index 0000000000..a3062a28a9 --- /dev/null +++ b/docs/examples/csharp/wssml/obj/project.assets.json @@ -0,0 +1,149 @@ +{ + "version": 3, + "targets": { + "net6.0": { + "Newtonsoft.Json/13.0.3": { + "type": "package", + "compile": { + "lib/net6.0/Newtonsoft.Json.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net6.0/Newtonsoft.Json.dll": { + "related": ".xml" + } + } + }, + "TDengine.Connector/3.1.3": { + "type": "package", + "dependencies": { + "Newtonsoft.Json": "13.0.3" + }, + "compile": { + "lib/net6.0/TDengine.dll": {} + }, + "runtime": { + "lib/net6.0/TDengine.dll": {} + } + } + } + }, + "libraries": { + "Newtonsoft.Json/13.0.3": { + "sha512": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==", + "type": "package", + "path": "newtonsoft.json/13.0.3", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "LICENSE.md", + "README.md", + "lib/net20/Newtonsoft.Json.dll", + "lib/net20/Newtonsoft.Json.xml", + "lib/net35/Newtonsoft.Json.dll", + "lib/net35/Newtonsoft.Json.xml", + "lib/net40/Newtonsoft.Json.dll", + "lib/net40/Newtonsoft.Json.xml", + "lib/net45/Newtonsoft.Json.dll", + "lib/net45/Newtonsoft.Json.xml", + "lib/net6.0/Newtonsoft.Json.dll", + "lib/net6.0/Newtonsoft.Json.xml", + "lib/netstandard1.0/Newtonsoft.Json.dll", + "lib/netstandard1.0/Newtonsoft.Json.xml", + "lib/netstandard1.3/Newtonsoft.Json.dll", + "lib/netstandard1.3/Newtonsoft.Json.xml", + "lib/netstandard2.0/Newtonsoft.Json.dll", + "lib/netstandard2.0/Newtonsoft.Json.xml", + "newtonsoft.json.13.0.3.nupkg.sha512", + "newtonsoft.json.nuspec", + "packageIcon.png" + ] + }, + "TDengine.Connector/3.1.3": { + "sha512": "dDX+Oex4I0X9yCalU0/YyUN0ecy+8X5xj6N8CoqeLrU6ICYDZgilSGQK9Fh3qmLobhGQvOJWwDpoO73rryHU5Q==", + "type": "package", + "path": "tdengine.connector/3.1.3", + "files": [ + ".nupkg.metadata", + "docs/README.md", + "image/logo.jpg", + "lib/net45/TDengine.dll", + "lib/net451/TDengine.dll", + "lib/net5.0/TDengine.dll", + "lib/net6.0/TDengine.dll", + "lib/netstandard2.0/TDengine.dll", + "lib/netstandard2.1/TDengine.dll", + "tdengine.connector.3.1.3.nupkg.sha512", + "tdengine.connector.nuspec" + ] + } + }, + "projectFileDependencyGroups": { + "net6.0": [ + "TDengine.Connector >= 3.1.*" + ] + }, + "packageFolders": { + "/root/.nuget/packages/": {} + }, + "project": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "/mnt/e/github/TDengine/docs/examples/csharp/wssml/wssml.csproj", + "projectName": "wssml", + "projectPath": "/mnt/e/github/TDengine/docs/examples/csharp/wssml/wssml.csproj", + "packagesPath": "/root/.nuget/packages/", + "outputPath": "/mnt/e/github/TDengine/docs/examples/csharp/wssml/obj/", + "projectStyle": "PackageReference", + "configFilePaths": [ + "/root/.nuget/NuGet/NuGet.Config" + ], + "originalTargetFrameworks": [ + "net6.0" + ], + "sources": { + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "net6.0": { + "targetAlias": "net6.0", + "projectReferences": {} + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + } + }, + "frameworks": { + "net6.0": { + "targetAlias": "net6.0", + "dependencies": { + "TDengine.Connector": { + "target": "Package", + "version": "[3.1.*, )" + } + }, + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48", + "net481" + ], + "assetTargetFallback": true, + "warn": true, + "frameworkReferences": { + "Microsoft.NETCore.App": { + "privateAssets": "all" + } + }, + "runtimeIdentifierGraphPath": "/root/.dotnet/sdk/8.0.100/RuntimeIdentifierGraph.json" + } + } + } +} \ No newline at end of file diff --git a/docs/examples/csharp/wssml/obj/project.nuget.cache b/docs/examples/csharp/wssml/obj/project.nuget.cache new file mode 100644 index 0000000000..140c7e62da --- /dev/null +++ b/docs/examples/csharp/wssml/obj/project.nuget.cache @@ -0,0 +1,11 @@ +{ + "version": 2, + "dgSpecHash": "f/iAhsDLFU7jI95wf6NFa1XHue7HQsgzzqr1jqfMTnrejkprbps/2toSr4j9kUyRUVdJNr7/TtdHhEsxEhKo+A==", + "success": true, + "projectFilePath": "/mnt/e/github/TDengine/docs/examples/csharp/wssml/wssml.csproj", + "expectedPackageFiles": [ + "/root/.nuget/packages/newtonsoft.json/13.0.3/newtonsoft.json.13.0.3.nupkg.sha512", + "/root/.nuget/packages/tdengine.connector/3.1.3/tdengine.connector.3.1.3.nupkg.sha512" + ], + "logs": [] +} \ No newline at end of file diff --git a/docs/examples/csharp/wssml/obj/project.packagespec.json b/docs/examples/csharp/wssml/obj/project.packagespec.json new file mode 100644 index 0000000000..587dbcda23 --- /dev/null +++ b/docs/examples/csharp/wssml/obj/project.packagespec.json @@ -0,0 +1 @@ +"restore":{"projectUniqueName":"E:\\github\\TDengine\\docs\\examples\\csharp\\wssml\\wssml.csproj","projectName":"wssml","projectPath":"E:\\github\\TDengine\\docs\\examples\\csharp\\wssml\\wssml.csproj","outputPath":"E:\\github\\TDengine\\docs\\examples\\csharp\\wssml\\obj\\","projectStyle":"PackageReference","originalTargetFrameworks":["net6.0"],"sources":{"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\":{},"E:\\github\\taos-connector-dotnet\\src\\resource":{},"https://api.nuget.org/v3/index.json":{}},"frameworks":{"net6.0":{"targetAlias":"net6.0","projectReferences":{}}},"warningProperties":{"warnAsError":["NU1605"]}}"frameworks":{"net6.0":{"targetAlias":"net6.0","dependencies":{"TDengine.Connector":{"target":"Package","version":"[3.1.*, )"}},"imports":["net461","net462","net47","net471","net472","net48","net481"],"assetTargetFallback":true,"warn":true,"frameworkReferences":{"Microsoft.NETCore.App":{"privateAssets":"all"}},"runtimeIdentifierGraphPath":"C:\\Program Files\\dotnet\\sdk\\8.0.202\\RuntimeIdentifierGraph.json"}} \ No newline at end of file diff --git a/docs/examples/csharp/wssml/obj/rider.project.model.nuget.info b/docs/examples/csharp/wssml/obj/rider.project.model.nuget.info new file mode 100644 index 0000000000..8c12f7e019 --- /dev/null +++ b/docs/examples/csharp/wssml/obj/rider.project.model.nuget.info @@ -0,0 +1 @@ +17225691310239873 \ No newline at end of file diff --git a/docs/examples/csharp/wssml/obj/rider.project.restore.info b/docs/examples/csharp/wssml/obj/rider.project.restore.info new file mode 100644 index 0000000000..b11c9dec26 --- /dev/null +++ b/docs/examples/csharp/wssml/obj/rider.project.restore.info @@ -0,0 +1 @@ +17225689180359712 \ No newline at end of file diff --git a/docs/examples/csharp/wssml/obj/wssml.csproj.nuget.dgspec.json b/docs/examples/csharp/wssml/obj/wssml.csproj.nuget.dgspec.json new file mode 100644 index 0000000000..314b2831c6 --- /dev/null +++ b/docs/examples/csharp/wssml/obj/wssml.csproj.nuget.dgspec.json @@ -0,0 +1,67 @@ +{ + "format": 1, + "restore": { + "/mnt/e/github/TDengine/docs/examples/csharp/wssml/wssml.csproj": {} + }, + "projects": { + "/mnt/e/github/TDengine/docs/examples/csharp/wssml/wssml.csproj": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "/mnt/e/github/TDengine/docs/examples/csharp/wssml/wssml.csproj", + "projectName": "wssml", + "projectPath": "/mnt/e/github/TDengine/docs/examples/csharp/wssml/wssml.csproj", + "packagesPath": "/root/.nuget/packages/", + "outputPath": "/mnt/e/github/TDengine/docs/examples/csharp/wssml/obj/", + "projectStyle": "PackageReference", + "configFilePaths": [ + "/root/.nuget/NuGet/NuGet.Config" + ], + "originalTargetFrameworks": [ + "net6.0" + ], + "sources": { + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "net6.0": { + "targetAlias": "net6.0", + "projectReferences": {} + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + } + }, + "frameworks": { + "net6.0": { + "targetAlias": "net6.0", + "dependencies": { + "TDengine.Connector": { + "target": "Package", + "version": "[3.1.*, )" + } + }, + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48", + "net481" + ], + "assetTargetFallback": true, + "warn": true, + "frameworkReferences": { + "Microsoft.NETCore.App": { + "privateAssets": "all" + } + }, + "runtimeIdentifierGraphPath": "/root/.dotnet/sdk/8.0.100/RuntimeIdentifierGraph.json" + } + } + } + } +} \ No newline at end of file diff --git a/docs/examples/csharp/wssml/obj/wssml.csproj.nuget.g.props b/docs/examples/csharp/wssml/obj/wssml.csproj.nuget.g.props new file mode 100644 index 0000000000..a270b60d2c --- /dev/null +++ b/docs/examples/csharp/wssml/obj/wssml.csproj.nuget.g.props @@ -0,0 +1,15 @@ + + + + True + NuGet + $(MSBuildThisFileDirectory)project.assets.json + /root/.nuget/packages/ + /root/.nuget/packages/ + PackageReference + 6.8.0 + + + + + \ No newline at end of file diff --git a/docs/examples/csharp/wssml/obj/wssml.csproj.nuget.g.targets b/docs/examples/csharp/wssml/obj/wssml.csproj.nuget.g.targets new file mode 100644 index 0000000000..35a7576c5a --- /dev/null +++ b/docs/examples/csharp/wssml/obj/wssml.csproj.nuget.g.targets @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/docs/examples/csharp/wssml/wssml.csproj b/docs/examples/csharp/wssml/wssml.csproj new file mode 100644 index 0000000000..0b8df205bb --- /dev/null +++ b/docs/examples/csharp/wssml/wssml.csproj @@ -0,0 +1,12 @@ + + + + Exe + net6.0 + enable + enable + + + + + diff --git a/docs/examples/csharp/wssubscribe/Program.cs b/docs/examples/csharp/wssubscribe/Program.cs new file mode 100644 index 0000000000..269fc4c732 --- /dev/null +++ b/docs/examples/csharp/wssubscribe/Program.cs @@ -0,0 +1,229 @@ +using TDengine.Driver; +using TDengine.Driver.Client; +using TDengine.TMQ; + +namespace TMQExample +{ + internal class SubscribeDemo + { + public static void Main(string[] args) + { + try + { + var builder = new ConnectionStringBuilder("protocol=WebSocket;host=127.0.0.1;port=6041;username=root;password=taosdata"); + using (var client = DbDriver.Open(builder)) + { + client.Exec("CREATE DATABASE IF NOT EXISTS power"); + client.Exec("USE power"); + client.Exec( + "CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); + client.Exec("CREATE TOPIC IF NOT EXISTS topic_meters as SELECT * from power.meters"); + var consumer = CreateConsumer(); + // insert data + Task.Run(InsertData); + // consume message + Consume(consumer); + // seek + Seek(consumer); + // commit + CommitOffset(consumer); + // close + Close(consumer); + Console.WriteLine("Done"); + } + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + } + + static void InsertData() + { + var builder = new ConnectionStringBuilder("protocol=WebSocket;host=127.0.0.1;port=6041;username=root;password=taosdata"); + using (var client = DbDriver.Open(builder)) + { + while (true) + { + client.Exec( + "INSERT into power.d1001 using power.meters tags(2,'California.SanFrancisco') values(now,11.5,219,0.30)"); + Task.Delay(1000).Wait(); + } + } + } + + static IConsumer> CreateConsumer() + { + // ANCHOR: create_consumer + // consumer config + var cfg = new Dictionary() + { + {"td.connect.type", "WebSocket"}, + { "td.connect.port", "6041" }, + { "auto.offset.reset", "latest" }, + { "msg.with.table.name", "true" }, + { "enable.auto.commit", "true" }, + { "auto.commit.interval.ms", "1000" }, + { "group.id", "group2" }, + { "client.id", "1" }, + { "td.connect.ip", "127.0.0.1" }, + { "td.connect.user", "root" }, + { "td.connect.pass", "taosdata" }, + }; + IConsumer> consumer = null!; + try + { + // create consumer + consumer = new ConsumerBuilder>(cfg).Build(); + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + + // ANCHOR_END: create_consumer + return consumer; + } + + static void Consume(IConsumer> consumer) + { + // ANCHOR: subscribe + try + { + // subscribe + consumer.Subscribe(new List() { "topic_meters" }); + for (int i = 0; i < 50; i++) + { + // consume message with using block to ensure the result is disposed + using (var cr = consumer.Consume(100)) + { + if (cr == null) continue; + foreach (var message in cr.Message) + { + // handle message + Console.WriteLine( + $"message {{{((DateTime)message.Value["ts"]).ToString("yyyy-MM-dd HH:mm:ss.fff")}, " + + $"{message.Value["current"]}, {message.Value["voltage"]}, {message.Value["phase"]}}}"); + } + } + } + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + // ANCHOR_END: subscribe + } + + static void Seek(IConsumer> consumer) + { + // ANCHOR: seek + try + { + // get assignment + var assignment = consumer.Assignment; + // seek to the beginning + foreach (var topicPartition in assignment) + { + consumer.Seek(new TopicPartitionOffset(topicPartition.Topic, topicPartition.Partition, 0)); + } + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + // ANCHOR_END: seek + } + + static void CommitOffset(IConsumer> consumer) + { + // ANCHOR: commit_offset + for (int i = 0; i < 5; i++) + { + try + { + // consume message with using block to ensure the result is disposed + using (var cr = consumer.Consume(100)) + { + if (cr == null) continue; + // commit offset + consumer.Commit(new List + { + cr.TopicPartitionOffset, + }); + } + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + } + // ANCHOR_END: commit_offset + } + + static void Close(IConsumer> consumer) + { + // ANCHOR: close + try + { + // unsubscribe + consumer.Unsubscribe(); + // close consumer + consumer.Close(); + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + // ANCHOR_END: close + } + } +} \ No newline at end of file diff --git a/docs/examples/csharp/wssubscribe/obj/project.assets.json b/docs/examples/csharp/wssubscribe/obj/project.assets.json new file mode 100644 index 0000000000..8335d20e65 --- /dev/null +++ b/docs/examples/csharp/wssubscribe/obj/project.assets.json @@ -0,0 +1,150 @@ +{ + "version": 3, + "targets": { + "net6.0": { + "Newtonsoft.Json/13.0.3": { + "type": "package", + "compile": { + "lib/net6.0/Newtonsoft.Json.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net6.0/Newtonsoft.Json.dll": { + "related": ".xml" + } + } + }, + "TDengine.Connector/3.1.3": { + "type": "package", + "dependencies": { + "Newtonsoft.Json": "13.0.3" + }, + "compile": { + "lib/net6.0/TDengine.dll": {} + }, + "runtime": { + "lib/net6.0/TDengine.dll": {} + } + } + } + }, + "libraries": { + "Newtonsoft.Json/13.0.3": { + "sha512": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==", + "type": "package", + "path": "newtonsoft.json/13.0.3", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "LICENSE.md", + "README.md", + "lib/net20/Newtonsoft.Json.dll", + "lib/net20/Newtonsoft.Json.xml", + "lib/net35/Newtonsoft.Json.dll", + "lib/net35/Newtonsoft.Json.xml", + "lib/net40/Newtonsoft.Json.dll", + "lib/net40/Newtonsoft.Json.xml", + "lib/net45/Newtonsoft.Json.dll", + "lib/net45/Newtonsoft.Json.xml", + "lib/net6.0/Newtonsoft.Json.dll", + "lib/net6.0/Newtonsoft.Json.xml", + "lib/netstandard1.0/Newtonsoft.Json.dll", + "lib/netstandard1.0/Newtonsoft.Json.xml", + "lib/netstandard1.3/Newtonsoft.Json.dll", + "lib/netstandard1.3/Newtonsoft.Json.xml", + "lib/netstandard2.0/Newtonsoft.Json.dll", + "lib/netstandard2.0/Newtonsoft.Json.xml", + "newtonsoft.json.13.0.3.nupkg.sha512", + "newtonsoft.json.nuspec", + "packageIcon.png" + ] + }, + "TDengine.Connector/3.1.3": { + "sha512": "dDX+Oex4I0X9yCalU0/YyUN0ecy+8X5xj6N8CoqeLrU6ICYDZgilSGQK9Fh3qmLobhGQvOJWwDpoO73rryHU5Q==", + "type": "package", + "path": "tdengine.connector/3.1.3", + "files": [ + ".nupkg.metadata", + "docs/README.md", + "image/logo.jpg", + "lib/net45/TDengine.dll", + "lib/net451/TDengine.dll", + "lib/net5.0/TDengine.dll", + "lib/net6.0/TDengine.dll", + "lib/netstandard2.0/TDengine.dll", + "lib/netstandard2.1/TDengine.dll", + "tdengine.connector.3.1.3.nupkg.sha512", + "tdengine.connector.nuspec" + ] + } + }, + "projectFileDependencyGroups": { + "net6.0": [ + "TDengine.Connector >= 3.1.*" + ] + }, + "packageFolders": { + "/root/.nuget/packages/": {} + }, + "project": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "/mnt/e/github/TDengine/docs/examples/csharp/wssubscribe/wssubscribe.csproj", + "projectName": "wssubscribe", + "projectPath": "/mnt/e/github/TDengine/docs/examples/csharp/wssubscribe/wssubscribe.csproj", + "packagesPath": "/root/.nuget/packages/", + "outputPath": "/mnt/e/github/TDengine/docs/examples/csharp/wssubscribe/obj/", + "projectStyle": "PackageReference", + "configFilePaths": [ + "/root/.nuget/NuGet/NuGet.Config" + ], + "originalTargetFrameworks": [ + "net6.0" + ], + "sources": { + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "net6.0": { + "targetAlias": "net6.0", + "projectReferences": {} + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + } + }, + "frameworks": { + "net6.0": { + "targetAlias": "net6.0", + "dependencies": { + "TDengine.Connector": { + "target": "Package", + "version": "[3.1.*, )", + "generatePathProperty": true + } + }, + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48", + "net481" + ], + "assetTargetFallback": true, + "warn": true, + "frameworkReferences": { + "Microsoft.NETCore.App": { + "privateAssets": "all" + } + }, + "runtimeIdentifierGraphPath": "/root/.dotnet/sdk/8.0.100/RuntimeIdentifierGraph.json" + } + } + } +} \ No newline at end of file diff --git a/docs/examples/csharp/wssubscribe/obj/project.nuget.cache b/docs/examples/csharp/wssubscribe/obj/project.nuget.cache new file mode 100644 index 0000000000..07a2d75f6b --- /dev/null +++ b/docs/examples/csharp/wssubscribe/obj/project.nuget.cache @@ -0,0 +1,11 @@ +{ + "version": 2, + "dgSpecHash": "iYS3B811DdocWqUXN2aMJdEwvfDVCixB5mK4XYN+98yFFNdPOU8hN4wQCxaOSFM7xKpvlmJvQPwkMetGBbFO8g==", + "success": true, + "projectFilePath": "/mnt/e/github/TDengine/docs/examples/csharp/wssubscribe/wssubscribe.csproj", + "expectedPackageFiles": [ + "/root/.nuget/packages/newtonsoft.json/13.0.3/newtonsoft.json.13.0.3.nupkg.sha512", + "/root/.nuget/packages/tdengine.connector/3.1.3/tdengine.connector.3.1.3.nupkg.sha512" + ], + "logs": [] +} \ No newline at end of file diff --git a/docs/examples/csharp/wssubscribe/obj/project.packagespec.json b/docs/examples/csharp/wssubscribe/obj/project.packagespec.json new file mode 100644 index 0000000000..319dd58c7f --- /dev/null +++ b/docs/examples/csharp/wssubscribe/obj/project.packagespec.json @@ -0,0 +1 @@ +"restore":{"projectUniqueName":"E:\\github\\TDengine\\docs\\examples\\csharp\\wssubscribe\\wssubscribe.csproj","projectName":"wssubscribe","projectPath":"E:\\github\\TDengine\\docs\\examples\\csharp\\wssubscribe\\wssubscribe.csproj","outputPath":"E:\\github\\TDengine\\docs\\examples\\csharp\\wssubscribe\\obj\\","projectStyle":"PackageReference","originalTargetFrameworks":["net6.0"],"sources":{"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\":{},"E:\\github\\taos-connector-dotnet\\src\\resource":{},"https://api.nuget.org/v3/index.json":{}},"frameworks":{"net6.0":{"targetAlias":"net6.0","projectReferences":{}}},"warningProperties":{"warnAsError":["NU1605"]}}"frameworks":{"net6.0":{"targetAlias":"net6.0","dependencies":{"TDengine.Connector":{"target":"Package","version":"[3.1.*, )","generatePathProperty":true}},"imports":["net461","net462","net47","net471","net472","net48","net481"],"assetTargetFallback":true,"warn":true,"frameworkReferences":{"Microsoft.NETCore.App":{"privateAssets":"all"}},"runtimeIdentifierGraphPath":"C:\\Program Files\\dotnet\\sdk\\8.0.202\\RuntimeIdentifierGraph.json"}} \ No newline at end of file diff --git a/docs/examples/csharp/wssubscribe/obj/rider.project.model.nuget.info b/docs/examples/csharp/wssubscribe/obj/rider.project.model.nuget.info new file mode 100644 index 0000000000..4a9bcd784b --- /dev/null +++ b/docs/examples/csharp/wssubscribe/obj/rider.project.model.nuget.info @@ -0,0 +1 @@ +17225691490262111 \ No newline at end of file diff --git a/docs/examples/csharp/wssubscribe/obj/rider.project.restore.info b/docs/examples/csharp/wssubscribe/obj/rider.project.restore.info new file mode 100644 index 0000000000..b8e44bdfbe --- /dev/null +++ b/docs/examples/csharp/wssubscribe/obj/rider.project.restore.info @@ -0,0 +1 @@ +17225689180408669 \ No newline at end of file diff --git a/docs/examples/csharp/wssubscribe/obj/wssubscribe.csproj.nuget.dgspec.json b/docs/examples/csharp/wssubscribe/obj/wssubscribe.csproj.nuget.dgspec.json new file mode 100644 index 0000000000..0825170a7d --- /dev/null +++ b/docs/examples/csharp/wssubscribe/obj/wssubscribe.csproj.nuget.dgspec.json @@ -0,0 +1,68 @@ +{ + "format": 1, + "restore": { + "/mnt/e/github/TDengine/docs/examples/csharp/wssubscribe/wssubscribe.csproj": {} + }, + "projects": { + "/mnt/e/github/TDengine/docs/examples/csharp/wssubscribe/wssubscribe.csproj": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "/mnt/e/github/TDengine/docs/examples/csharp/wssubscribe/wssubscribe.csproj", + "projectName": "wssubscribe", + "projectPath": "/mnt/e/github/TDengine/docs/examples/csharp/wssubscribe/wssubscribe.csproj", + "packagesPath": "/root/.nuget/packages/", + "outputPath": "/mnt/e/github/TDengine/docs/examples/csharp/wssubscribe/obj/", + "projectStyle": "PackageReference", + "configFilePaths": [ + "/root/.nuget/NuGet/NuGet.Config" + ], + "originalTargetFrameworks": [ + "net6.0" + ], + "sources": { + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "net6.0": { + "targetAlias": "net6.0", + "projectReferences": {} + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + } + }, + "frameworks": { + "net6.0": { + "targetAlias": "net6.0", + "dependencies": { + "TDengine.Connector": { + "target": "Package", + "version": "[3.1.*, )", + "generatePathProperty": true + } + }, + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48", + "net481" + ], + "assetTargetFallback": true, + "warn": true, + "frameworkReferences": { + "Microsoft.NETCore.App": { + "privateAssets": "all" + } + }, + "runtimeIdentifierGraphPath": "/root/.dotnet/sdk/8.0.100/RuntimeIdentifierGraph.json" + } + } + } + } +} \ No newline at end of file diff --git a/docs/examples/csharp/wssubscribe/obj/wssubscribe.csproj.nuget.g.props b/docs/examples/csharp/wssubscribe/obj/wssubscribe.csproj.nuget.g.props new file mode 100644 index 0000000000..939669445d --- /dev/null +++ b/docs/examples/csharp/wssubscribe/obj/wssubscribe.csproj.nuget.g.props @@ -0,0 +1,18 @@ + + + + True + NuGet + $(MSBuildThisFileDirectory)project.assets.json + /root/.nuget/packages/ + /root/.nuget/packages/ + PackageReference + 6.8.0 + + + + + + /root/.nuget/packages/tdengine.connector/3.1.3 + + \ No newline at end of file diff --git a/docs/examples/csharp/wssubscribe/obj/wssubscribe.csproj.nuget.g.targets b/docs/examples/csharp/wssubscribe/obj/wssubscribe.csproj.nuget.g.targets new file mode 100644 index 0000000000..35a7576c5a --- /dev/null +++ b/docs/examples/csharp/wssubscribe/obj/wssubscribe.csproj.nuget.g.targets @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/docs/examples/csharp/wssubscribe/wssubscribe.csproj b/docs/examples/csharp/wssubscribe/wssubscribe.csproj new file mode 100644 index 0000000000..3a2796a3af --- /dev/null +++ b/docs/examples/csharp/wssubscribe/wssubscribe.csproj @@ -0,0 +1,12 @@ + + + + Exe + net6.0 + enable + enable + + + + + diff --git a/docs/examples/go/connect/afconn/main.go b/docs/examples/go/connect/afconn/main.go index bb2574a01b..3e4dff43ac 100644 --- a/docs/examples/go/connect/afconn/main.go +++ b/docs/examples/go/connect/afconn/main.go @@ -13,6 +13,6 @@ func main() { if err != nil { log.Fatalln("failed to connect, err:", err) } else { - fmt.Println("connected") + fmt.Println("Connected") } } diff --git a/docs/examples/go/connect/cgoexample/main.go b/docs/examples/go/connect/cgoexample/main.go index 881cf15ee3..9c9b414b47 100644 --- a/docs/examples/go/connect/cgoexample/main.go +++ b/docs/examples/go/connect/cgoexample/main.go @@ -9,6 +9,9 @@ import ( ) func main() { + // use + // var taosDSN = "root:taosdata@tcp(localhost:6030)/dbName" + // if you want to connect a specified database named "dbName". var taosDSN = "root:taosdata@tcp(localhost:6030)/" taos, err := sql.Open("taosSql", taosDSN) if err != nil { @@ -18,7 +21,3 @@ func main() { fmt.Println("Connected") defer taos.Close() } - -// use -// var taosDSN = "root:taosdata@tcp(localhost:6030)/dbName" -// if you want to connect a specified database named "dbName". diff --git a/docs/examples/go/connect/connpool/main.go b/docs/examples/go/connect/connpool/main.go new file mode 100644 index 0000000000..e3058fca3f --- /dev/null +++ b/docs/examples/go/connect/connpool/main.go @@ -0,0 +1,33 @@ +package main + +import ( + "database/sql" + "fmt" + "log" + + _ "github.com/taosdata/driver-go/v3/taosSql" +) + +func main() { + // use + // var taosDSN = "root:taosdata@tcp(localhost:6030)/dbName" + // if you want to connect a specified database named "dbName". + var taosDSN = "root:taosdata@tcp(localhost:6030)/" + taos, err := sql.Open("taosSql", taosDSN) + if err != nil { + log.Fatalln("failed to connect TDengine, err:", err) + return + } + fmt.Println("Connected") + defer taos.Close() + // ANCHOR: pool + // SetMaxOpenConns sets the maximum number of open connections to the database. 0 means unlimited. + taos.SetMaxOpenConns(0) + // SetMaxIdleConns sets the maximum number of connections in the idle connection pool. + taos.SetMaxIdleConns(2) + // SetConnMaxLifetime sets the maximum amount of time a connection may be reused. + taos.SetConnMaxLifetime(0) + // SetConnMaxIdleTime sets the maximum amount of time a connection may be idle. + taos.SetConnMaxIdleTime(0) + // ANCHOR_END: pool +} diff --git a/docs/examples/go/connect/restexample/main.go b/docs/examples/go/connect/restexample/main.go index 67a129bf9c..ecc5110c60 100644 --- a/docs/examples/go/connect/restexample/main.go +++ b/docs/examples/go/connect/restexample/main.go @@ -9,6 +9,9 @@ import ( ) func main() { + // use + // var taosDSN = "root:taosdata@http(localhost:6041)/dbName" + // if you want to connect a specified database named "dbName". var taosDSN = "root:taosdata@http(localhost:6041)/" taos, err := sql.Open("taosRestful", taosDSN) if err != nil { @@ -18,7 +21,3 @@ func main() { fmt.Println("Connected") defer taos.Close() } - -// use -// var taosDSN = "root:taosdata@http(localhost:6041)/dbName" -// if you want to connect a specified database named "dbName". diff --git a/docs/examples/go/connect/wsexample/main.go b/docs/examples/go/connect/wsexample/main.go new file mode 100644 index 0000000000..c815f0aec5 --- /dev/null +++ b/docs/examples/go/connect/wsexample/main.go @@ -0,0 +1,23 @@ +package main + +import ( + "database/sql" + "fmt" + "log" + + _ "github.com/taosdata/driver-go/v3/taosWS" +) + +func main() { + // use + // var taosDSN = "root:taosdata@ws(localhost:6041)/dbName" + // if you want to connect a specified database named "dbName". + var taosDSN = "root:taosdata@ws(localhost:6041)/" + taos, err := sql.Open("taosWS", taosDSN) + if err != nil { + log.Fatalln("failed to connect TDengine, err:", err) + return + } + fmt.Println("Connected") + defer taos.Close() +} diff --git a/docs/examples/go/go.mod b/docs/examples/go/go.mod index 716a0ef5dc..ed8fde2d9f 100644 --- a/docs/examples/go/go.mod +++ b/docs/examples/go/go.mod @@ -2,5 +2,12 @@ module goexample go 1.17 -require github.com/taosdata/driver-go/v3 v3.1.0 +require github.com/taosdata/driver-go/v3 v3.5.6 +require ( + github.com/google/uuid v1.3.0 // indirect + github.com/gorilla/websocket v1.5.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect +) diff --git a/docs/examples/go/go.sum b/docs/examples/go/go.sum index 13e13adaa1..61841429ee 100644 --- a/docs/examples/go/go.sum +++ b/docs/examples/go/go.sum @@ -1,15 +1,25 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/taosdata/driver-go/v3 v3.1.0/go.mod h1:H2vo/At+rOPY1aMzUV9P49SVX7NlXb3LAbKw+MCLrmU= +github.com/taosdata/driver-go/v3 v3.5.6 h1:LDVtMyT3B9p2VREsd5KKM91D4Y7P4kSdh2SQumXi8bk= +github.com/taosdata/driver-go/v3 v3.5.6/go.mod h1:H2vo/At+rOPY1aMzUV9P49SVX7NlXb3LAbKw+MCLrmU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/docs/examples/go/queryreqid/main.go b/docs/examples/go/queryreqid/main.go new file mode 100644 index 0000000000..c7dd3d9215 --- /dev/null +++ b/docs/examples/go/queryreqid/main.go @@ -0,0 +1,55 @@ +package main + +import ( + "context" + "database/sql" + "fmt" + "time" + + _ "github.com/taosdata/driver-go/v3/taosSql" +) + +func main() { + db, err := sql.Open("taosSql", "root:taosdata@tcp(localhost:6030)/") + if err != nil { + panic(err) + } + defer db.Close() + initEnv(db) + // ANCHOR: query_id + // use context to set request id + ctx := context.WithValue(context.Background(), "taos_req_id", int64(3)) + // execute query with context + rows, err := db.QueryContext(ctx, "SELECT ts, current, location FROM power.meters limit 1") + if err != nil { + panic(err) + } + for rows.Next() { + var ( + ts time.Time + current float32 + location string + ) + err = rows.Scan(&ts, ¤t, &location) + if err != nil { + panic(err) + } + fmt.Printf("ts: %s, current: %f, location: %s\n", ts, current, location) + } + // ANCHOR_END: query_id +} + +func initEnv(conn *sql.DB) { + _, err := conn.Exec("CREATE DATABASE IF NOT EXISTS power") + if err != nil { + panic(err) + } + _, err = conn.Exec("CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))") + if err != nil { + panic(err) + } + _, err = conn.Exec("INSERT INTO power.d1001 USING power.meters TAGS (2, 'California.SanFrancisco') VALUES (NOW , 10.2, 219, 0.32)") + if err != nil { + panic(err) + } +} diff --git a/docs/examples/go/schemaless/native/main.go b/docs/examples/go/schemaless/native/main.go new file mode 100644 index 0000000000..b9cd70ef14 --- /dev/null +++ b/docs/examples/go/schemaless/native/main.go @@ -0,0 +1,41 @@ +package main + +import ( + "github.com/taosdata/driver-go/v3/af" +) + +func main() { + host := "127.0.0.1" + lineDemo := "meters,groupid=2,location=California.SanFrancisco current=10.3000002f64,voltage=219i32,phase=0.31f64 1626006833639" + telnetDemo := "metric_telnet 1707095283260 4 host=host0 interface=eth0" + jsonDemo := "{\"metric\": \"metric_json\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}" + + conn, err := af.Open(host, "root", "taosdata", "", 0) + if err != nil { + panic(err) + } + defer conn.Close() + _, err = conn.Exec("CREATE DATABASE IF NOT EXISTS power") + if err != nil { + panic(err) + } + _, err = conn.Exec("USE power") + if err != nil { + panic(err) + } + // insert influxdb line protocol + err = conn.InfluxDBInsertLines([]string{lineDemo}, "ms") + if err != nil { + panic(err) + } + // insert opentsdb telnet protocol + err = conn.OpenTSDBInsertTelnetLines([]string{telnetDemo}) + if err != nil { + panic(err) + } + // insert opentsdb json protocol + err = conn.OpenTSDBInsertJsonPayload(jsonDemo) + if err != nil { + panic(err) + } +} diff --git a/docs/examples/go/schemaless/ws/main.go b/docs/examples/go/schemaless/ws/main.go new file mode 100644 index 0000000000..c6807f213c --- /dev/null +++ b/docs/examples/go/schemaless/ws/main.go @@ -0,0 +1,57 @@ +package main + +import ( + "database/sql" + "fmt" + "log" + "time" + + "github.com/taosdata/driver-go/v3/common" + _ "github.com/taosdata/driver-go/v3/taosWS" + "github.com/taosdata/driver-go/v3/ws/schemaless" +) + +func main() { + host := "127.0.0.1" + lineDemo := "meters,groupid=2,location=California.SanFrancisco current=10.3000002f64,voltage=219i32,phase=0.31f64 1626006833639" + telnetDemo := "metric_telnet 1707095283260 4 host=host0 interface=eth0" + jsonDemo := "{\"metric\": \"metric_json\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}" + + db, err := sql.Open("taosWS", fmt.Sprintf("root:taosdata@ws(%s:6041)/", host)) + if err != nil { + log.Fatal(err) + } + defer db.Close() + _, err = db.Exec("CREATE DATABASE IF NOT EXISTS power") + if err != nil { + log.Fatal(err) + } + s, err := schemaless.NewSchemaless(schemaless.NewConfig("ws://localhost:6041", 1, + schemaless.SetDb("power"), + schemaless.SetReadTimeout(10*time.Second), + schemaless.SetWriteTimeout(10*time.Second), + schemaless.SetUser("root"), + schemaless.SetPassword("taosdata"), + schemaless.SetErrorHandler(func(err error) { + log.Fatal(err) + }), + )) + if err != nil { + panic(err) + } + // insert influxdb line protocol + err = s.Insert(lineDemo, schemaless.InfluxDBLineProtocol, "ms", 0, common.GetReqID()) + if err != nil { + panic(err) + } + // insert opentsdb telnet line protocol + err = s.Insert(telnetDemo, schemaless.OpenTSDBTelnetLineProtocol, "ms", 0, common.GetReqID()) + if err != nil { + panic(err) + } + // insert opentsdb json format protocol + err = s.Insert(jsonDemo, schemaless.OpenTSDBJsonFormatProtocol, "s", 0, common.GetReqID()) + if err != nil { + panic(err) + } +} diff --git a/docs/examples/go/sqlquery/main.go b/docs/examples/go/sqlquery/main.go new file mode 100644 index 0000000000..12e1732b31 --- /dev/null +++ b/docs/examples/go/sqlquery/main.go @@ -0,0 +1,88 @@ +package main + +import ( + "database/sql" + "fmt" + "time" + + _ "github.com/taosdata/driver-go/v3/taosSql" +) + +func main() { + db, err := sql.Open("taosSql", "root:taosdata@tcp(localhost:6030)/") + if err != nil { + panic(err) + } + defer db.Close() + // ANCHOR: create_db_and_table + // create database + res, err := db.Exec("CREATE DATABASE IF NOT EXISTS power") + if err != nil { + panic(err) + } + affected, err := res.RowsAffected() + if err != nil { + panic(err) + } + fmt.Println("create database affected:", affected) + // use database + res, err = db.Exec("USE power") + if err != nil { + panic(err) + } + affected, err = res.RowsAffected() + if err != nil { + panic(err) + } + fmt.Println("use database affected:", affected) + // create table + res, err = db.Exec("CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))") + affected, err = res.RowsAffected() + if err != nil { + panic(err) + } + fmt.Println("create table affected:", affected) + // ANCHOR_END: create_db_and_table + // ANCHOR: insert_data + // insert data, please make sure the database and table are created before + insertQuery := "INSERT INTO " + + "power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " + + "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(3, 'California.SanFrancisco') " + + "VALUES " + + "(NOW + 1a, 10.30000, 218, 0.25000) " + res, err = db.Exec(insertQuery) + if err != nil { + panic(err) + } + affected, err = res.RowsAffected() + if err != nil { + panic(err) + } + // you can check affectedRows here + fmt.Println("insert data affected:", affected) + // ANCHOR_END: insert_data + // ANCHOR: select_data + // query data, make sure the database and table are created before + rows, err := db.Query("SELECT ts, current, location FROM power.meters limit 100") + if err != nil { + panic(err) + } + for rows.Next() { + var ( + ts time.Time + current float32 + location string + ) + err = rows.Scan(&ts, ¤t, &location) + if err != nil { + panic(err) + } + // you can check data here + fmt.Printf("ts: %s, current: %f, location: %s\n", ts, current, location) + } + // ANCHOR_END: select_data +} diff --git a/docs/examples/go/stmt/native/main.go b/docs/examples/go/stmt/native/main.go new file mode 100644 index 0000000000..63986912da --- /dev/null +++ b/docs/examples/go/stmt/native/main.go @@ -0,0 +1,82 @@ +package main + +import ( + "fmt" + "math/rand" + "time" + + "github.com/taosdata/driver-go/v3/af" + "github.com/taosdata/driver-go/v3/common" + "github.com/taosdata/driver-go/v3/common/param" +) + +func main() { + host := "127.0.0.1" + numOfSubTable := 10 + numOfRow := 10 + db, err := af.Open(host, "root", "taosdata", "", 0) + if err != nil { + panic(err) + } + defer db.Close() + // prepare database and table + _, err = db.Exec("CREATE DATABASE IF NOT EXISTS power") + if err != nil { + panic(err) + } + _, err = db.Exec("USE power") + if err != nil { + panic(err) + } + _, err = db.Exec("CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))") + if err != nil { + panic(err) + } + // prepare statement + sql := "INSERT INTO ? USING meters TAGS(?,?) VALUES (?,?,?,?)" + stmt := db.Stmt() + err = stmt.Prepare(sql) + if err != nil { + panic(err) + } + for i := 1; i <= numOfSubTable; i++ { + tableName := fmt.Sprintf("d_bind_%d", i) + tags := param.NewParam(2).AddInt(i).AddBinary([]byte(fmt.Sprintf("location_%d", i))) + // set tableName and tags + err = stmt.SetTableNameWithTags(tableName, tags) + if err != nil { + panic(err) + } + // bind column data + current := time.Now() + for j := 0; j < numOfRow; j++ { + row := param.NewParam(4). + AddTimestamp(current.Add(time.Millisecond*time.Duration(j)), common.PrecisionMilliSecond). + AddFloat(rand.Float32() * 30). + AddInt(rand.Intn(300)). + AddFloat(rand.Float32()) + err = stmt.BindRow(row) + if err != nil { + panic(err) + } + } + // add batch + err = stmt.AddBatch() + if err != nil { + panic(err) + } + // execute batch + err = stmt.Execute() + if err != nil { + panic(err) + } + // get affected rows + affected := stmt.GetAffectedRows() + // you can check exeResult here + fmt.Printf("table %s insert %d rows.\n", tableName, affected) + } + err = stmt.Close() + if err != nil { + panic(err) + } +} diff --git a/docs/examples/go/stmt/ws/main.go b/docs/examples/go/stmt/ws/main.go new file mode 100644 index 0000000000..ddb1d6e2a7 --- /dev/null +++ b/docs/examples/go/stmt/ws/main.go @@ -0,0 +1,102 @@ +package main + +import ( + "database/sql" + "fmt" + "math/rand" + "time" + + "github.com/taosdata/driver-go/v3/common" + "github.com/taosdata/driver-go/v3/common/param" + _ "github.com/taosdata/driver-go/v3/taosRestful" + "github.com/taosdata/driver-go/v3/ws/stmt" +) + +func main() { + host := "127.0.0.1" + numOfSubTable := 10 + numOfRow := 10 + db, err := sql.Open("taosRestful", fmt.Sprintf("root:taosdata@http(%s:6041)/", host)) + if err != nil { + panic(err) + } + defer db.Close() + // prepare database and table + _, err = db.Exec("CREATE DATABASE IF NOT EXISTS power") + if err != nil { + panic(err) + } + _, err = db.Exec("CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))") + if err != nil { + panic(err) + } + + config := stmt.NewConfig(fmt.Sprintf("ws://%s:6041", host), 0) + config.SetConnectUser("root") + config.SetConnectPass("taosdata") + config.SetConnectDB("power") + config.SetMessageTimeout(common.DefaultMessageTimeout) + config.SetWriteWait(common.DefaultWriteWait) + + connector, err := stmt.NewConnector(config) + if err != nil { + panic(err) + } + // // prepare statement + sql := "INSERT INTO ? USING meters TAGS(?,?) VALUES (?,?,?,?)" + stmt, err := connector.Init() + if err != nil { + panic(err) + } + err = stmt.Prepare(sql) + if err != nil { + panic(err) + } + for i := 1; i <= numOfSubTable; i++ { + tableName := fmt.Sprintf("d_bind_%d", i) + tags := param.NewParam(2).AddInt(i).AddBinary([]byte(fmt.Sprintf("location_%d", i))) + tagsType := param.NewColumnType(2).AddInt().AddBinary(24) + columnType := param.NewColumnType(4).AddTimestamp().AddFloat().AddInt().AddFloat() + // set tableName + err = stmt.SetTableName(tableName) + if err != nil { + panic(err) + } + // set tags + err = stmt.SetTags(tags, tagsType) + if err != nil { + panic(err) + } + // bind column data + current := time.Now() + for j := 0; j < numOfRow; j++ { + columnData := make([]*param.Param, 4) + columnData[0] = param.NewParam(1).AddTimestamp(current.Add(time.Millisecond*time.Duration(j)), common.PrecisionMilliSecond) + columnData[1] = param.NewParam(1).AddFloat(rand.Float32() * 30) + columnData[2] = param.NewParam(1).AddInt(rand.Intn(300)) + columnData[3] = param.NewParam(1).AddFloat(rand.Float32()) + err = stmt.BindParam(columnData, columnType) + if err != nil { + panic(err) + } + } + // add batch + err = stmt.AddBatch() + if err != nil { + panic(err) + } + // execute batch + err = stmt.Exec() + if err != nil { + panic(err) + } + // get affected rows + affected := stmt.GetAffectedRows() + // you can check exeResult here + fmt.Printf("table %s insert %d rows.\n", tableName, affected) + } + err = stmt.Close() + if err != nil { + panic(err) + } +} diff --git a/docs/examples/go/tmq/native/main.go b/docs/examples/go/tmq/native/main.go new file mode 100644 index 0000000000..668898239e --- /dev/null +++ b/docs/examples/go/tmq/native/main.go @@ -0,0 +1,132 @@ +package main + +import ( + "database/sql" + "fmt" + "time" + + "github.com/taosdata/driver-go/v3/af/tmq" + tmqcommon "github.com/taosdata/driver-go/v3/common/tmq" + _ "github.com/taosdata/driver-go/v3/taosSql" +) + +var done = make(chan struct{}) + +func main() { + // init env + conn, err := sql.Open("taosSql", "root:taosdata@tcp(127.0.0.1:6030)/") + if err != nil { + panic(err) + } + defer func() { + conn.Close() + }() + initEnv(conn) + // ANCHOR: create_consumer + // create consumer + consumer, err := tmq.NewConsumer(&tmqcommon.ConfigMap{ + "td.connect.user": "root", + "td.connect.pass": "taosdata", + "auto.offset.reset": "latest", + "msg.with.table.name": "true", + "enable.auto.commit": "true", + "auto.commit.interval.ms": "1000", + "group.id": "group2", + "client.id": "1", + }) + if err != nil { + panic(err) + } + // ANCHOR_END: create_consumer + // ANCHOR: subscribe + err = consumer.Subscribe("topic_meters", nil) + if err != nil { + panic(err) + } + for i := 0; i < 50; i++ { + ev := consumer.Poll(100) + if ev != nil { + switch e := ev.(type) { + case *tmqcommon.DataMessage: + // process your data here + fmt.Printf("get message:%v\n", e) + // ANCHOR: commit_offset + // commit offset + topicPartition, err := consumer.CommitOffsets([]tmqcommon.TopicPartition{e.TopicPartition}) + if err != nil { + panic(err) + } + fmt.Println(topicPartition) + // ANCHOR_END: commit_offset + case tmqcommon.Error: + fmt.Printf("%% Error: %v: %v\n", e.Code(), e) + panic(e) + } + // commit all offsets + topicPartition, err := consumer.Commit() + if err != nil { + panic(err) + } + fmt.Println(topicPartition) + + } + } + // ANCHOR_END: subscribe + // ANCHOR: seek + // get assignment + partitions, err := consumer.Assignment() + if err != nil { + panic(err) + } + for i := 0; i < len(partitions); i++ { + fmt.Println(partitions[i]) + // seek to the beginning + err = consumer.Seek(tmqcommon.TopicPartition{ + Topic: partitions[i].Topic, + Partition: partitions[i].Partition, + Offset: 0, + }, 0) + if err != nil { + panic(err) + } + } + // ANCHOR_END: seek + // ANCHOR: close + // unsubscribe + err = consumer.Unsubscribe() + if err != nil { + panic(err) + } + // close consumer + err = consumer.Close() + if err != nil { + panic(err) + } + // ANCHOR_END: close + <-done +} + +func initEnv(conn *sql.DB) { + _, err := conn.Exec("CREATE DATABASE IF NOT EXISTS power") + if err != nil { + panic(err) + } + _, err = conn.Exec("CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))") + if err != nil { + panic(err) + } + _, err = conn.Exec("CREATE TOPIC IF NOT EXISTS topic_meters AS SELECT ts, current, voltage, phase, groupid, location FROM power.meters") + if err != nil { + panic(err) + } + go func() { + for i := 0; i < 10; i++ { + time.Sleep(time.Second) + _, err = conn.Exec("INSERT INTO power.d1001 USING power.meters TAGS (2, 'California.SanFrancisco') VALUES (NOW , 10.2, 219, 0.32)") + if err != nil { + panic(err) + } + } + done <- struct{}{} + }() +} diff --git a/docs/examples/go/tmq/ws/main.go b/docs/examples/go/tmq/ws/main.go new file mode 100644 index 0000000000..48e6714957 --- /dev/null +++ b/docs/examples/go/tmq/ws/main.go @@ -0,0 +1,137 @@ +package main + +import ( + "database/sql" + "fmt" + "time" + + "github.com/taosdata/driver-go/v3/common" + tmqcommon "github.com/taosdata/driver-go/v3/common/tmq" + _ "github.com/taosdata/driver-go/v3/taosWS" + "github.com/taosdata/driver-go/v3/ws/tmq" +) + +var done = make(chan struct{}) + +func main() { + // init env + conn, err := sql.Open("taosWS", "root:taosdata@ws(127.0.0.1:6041)/") + if err != nil { + panic(err) + } + defer func() { + conn.Close() + }() + initEnv(conn) + // ANCHOR: create_consumer + // create consumer + consumer, err := tmq.NewConsumer(&tmqcommon.ConfigMap{ + "ws.url": "ws://127.0.0.1:6041", + "ws.message.channelLen": uint(0), + "ws.message.timeout": common.DefaultMessageTimeout, + "ws.message.writeWait": common.DefaultWriteWait, + "td.connect.user": "root", + "td.connect.pass": "taosdata", + "auto.offset.reset": "latest", + "msg.with.table.name": "true", + "enable.auto.commit": "true", + "auto.commit.interval.ms": "1000", + "group.id": "group2", + "client.id": "1", + }) + if err != nil { + panic(err) + } + // ANCHOR_END: create_consumer + // ANCHOR: subscribe + err = consumer.Subscribe("topic_meters", nil) + if err != nil { + panic(err) + } + for i := 0; i < 50; i++ { + ev := consumer.Poll(100) + if ev != nil { + switch e := ev.(type) { + case *tmqcommon.DataMessage: + // process your data here + fmt.Printf("get message:%v\n", e) + // ANCHOR: commit_offset + // commit offset + topicPartition, err := consumer.CommitOffsets([]tmqcommon.TopicPartition{e.TopicPartition}) + if err != nil { + panic(err) + } + fmt.Println(topicPartition) + // ANCHOR_END: commit_offset + case tmqcommon.Error: + fmt.Printf("%% Error: %v: %v\n", e.Code(), e) + panic(e) + } + // commit all offsets + topicPartition, err := consumer.Commit() + if err != nil { + panic(err) + } + fmt.Println(topicPartition) + + } + } + // ANCHOR_END: subscribe + // ANCHOR: seek + // get assignment + partitions, err := consumer.Assignment() + if err != nil { + panic(err) + } + for i := 0; i < len(partitions); i++ { + fmt.Println(partitions[i]) + // seek to the beginning + err = consumer.Seek(tmqcommon.TopicPartition{ + Topic: partitions[i].Topic, + Partition: partitions[i].Partition, + Offset: 0, + }, 0) + if err != nil { + panic(err) + } + } + // ANCHOR_END: seek + // ANCHOR: close + // unsubscribe + err = consumer.Unsubscribe() + if err != nil { + panic(err) + } + // close consumer + err = consumer.Close() + if err != nil { + panic(err) + } + // ANCHOR_END: close + <-done +} + +func initEnv(conn *sql.DB) { + _, err := conn.Exec("CREATE DATABASE IF NOT EXISTS power") + if err != nil { + panic(err) + } + _, err = conn.Exec("CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))") + if err != nil { + panic(err) + } + _, err = conn.Exec("CREATE TOPIC IF NOT EXISTS topic_meters AS SELECT ts, current, voltage, phase, groupid, location FROM power.meters") + if err != nil { + panic(err) + } + go func() { + for i := 0; i < 10; i++ { + time.Sleep(time.Second) + _, err = conn.Exec("INSERT INTO power.d1001 USING power.meters TAGS (2, 'California.SanFrancisco') VALUES (NOW , 10.2, 219, 0.32)") + if err != nil { + panic(err) + } + } + done <- struct{}{} + }() +} diff --git a/docs/zh/08-develop/01-connect/index.md b/docs/zh/08-develop/01-connect/index.md index 48af1f7a63..89c3dd7f69 100644 --- a/docs/zh/08-develop/01-connect/index.md +++ b/docs/zh/08-develop/01-connect/index.md @@ -220,7 +220,7 @@ taos = { version = "*", default-features = false, features = ["ws"] } 编辑项目配置文件中添加 [TDengine.Connector](https://www.nuget.org/packages/TDengine.Connector/) 的引用即可: -```xml title=csharp.csproj {12} +```xml title=csharp.csproj @@ -327,6 +327,40 @@ URL 和 Properties 的详细参数说明和如何使用详见 [url 规范](../.. + + 数据源名称具有通用格式,例如 [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 + ``` + + 支持的 DSN 参数如下 + + 原生连接: + + - `cfg` 指定 taos.cfg 目录 + - `cgoThread` 指定 cgo 同时执行的数量,默认为系统核数 + - `cgoAsyncHandlerPoolSize` 指定异步函数的 handle 大小,默认为 10000 + + REST 连接: + + - `disableCompression` 是否接受压缩数据,默认为 true 不接受压缩数据,如果传输数据使用 gzip 压缩设置为 false。 + - `readBufferSize` 读取数据的缓存区大小默认为 4K(4096),当查询结果数据量多时可以适当调大该值。 + - `token` 连接云服务时使用的 token。 + - `skipVerify` 是否跳过证书验证,默认为 false 不跳过证书验证,如果连接的是不安全的服务设置为 true。 + + WebSocket 连接: + + - `enableCompression` 是否发送压缩数据,默认为 false 不发送压缩数据,如果传输数据使用压缩设置为 true。 + - `readTimeout` 读取数据的超时时间,默认为 5m。 + - `writeTimeout` 写入数据的超时时间,默认为 10s。 + Rust 连接器使用 DSN 来创建连接, DSN 描述字符串基本结构如下: @@ -341,6 +375,34 @@ DSN 的详细说明和如何使用详见 [连接功能](../../reference/connecto + ConnectionStringBuilder 使用 key-value 对方式设置连接参数,key 为参数名,value 为参数值,不同参数之间使用分号 `;` 分割。 + + 例如: + + ```csharp + "protocol=WebSocket;host=127.0.0.1;port=6041;useSSL=false" + ``` + 支持的参数如下: + + - `host`:TDengine 运行实例的地址。 + - `port`:TDengine 运行实例的端口。 + - `username`:连接的用户名。 + - `password`:连接的密码。 + - `protocol`:连接的协议,可选值为 Native 或 WebSocket,默认为 Native。 + - `db`:连接的数据库。 + - `timezone`:时区,默认为本地时区。 + - `connTimeout`:连接超时时间,默认为 1 分钟。 + + WebSocket 连接额外支持以下参数: + + - `readTimeout`:读取超时时间,默认为 5 分钟。 + - `writeTimeout`:发送超时时间,默认为 10 秒。 + - `token`:连接 TDengine cloud 的 token。 + - `useSSL`:是否使用 SSL 连接,默认为 false。 + - `enableCompression`:是否启用 WebSocket 压缩,默认为 false。 + - `autoReconnect`:是否自动重连,默认为 false。 + - `reconnectRetryCount`:重连次数,默认为 3。 + - `reconnectIntervalMs`:重连间隔毫秒时间,默认为 2000。 @@ -383,7 +445,7 @@ DSN 的详细说明和如何使用详见 [连接功能](../../reference/connecto 下面是各语言连接器建立 Websocket 连接代码样例。演示了如何使用 Websocket 连接方式连接到 TDengine 数据库,并对连接设定一些参数。整个过程主要涉及到数据库连接的建立和异常处理。 - + ```java {{#include docs/examples/java/src/main/java/com/taos/example/WSConnectExample.java:main}} ``` @@ -394,7 +456,9 @@ DSN 的详细说明和如何使用详见 [连接功能](../../reference/connecto ``` - +```go +{{#include docs/examples/go/connect/wsexample/main.go}} +``` ```rust @@ -407,7 +471,9 @@ DSN 的详细说明和如何使用详见 [连接功能](../../reference/connecto ``` - +```csharp +{{#include docs/examples/csharp/wsConnect/Program.cs:main}} +``` @@ -428,36 +494,39 @@ DSN 的详细说明和如何使用详见 [连接功能](../../reference/connecto ```java {{#include docs/examples/java/src/main/java/com/taos/example/JNIConnectExample.java:main}} ``` - - - - - - - - + + + + + +```go +{{#include docs/examples/go/connect/cgoexample/main.go}} +``` + + ```rust {{#include docs/examples/rust/nativeexample/examples/connect.rs}} ``` - - - - - - - - - - - - - - + + +```csharp title="WebSocket 连接" +{{#include docs/examples/csharp/connect/Program.cs:main}} +``` + + + + + + + + + + ### REST 连接 -下面是各语言连接器建立 RESt 连接代码样例。演示了如何使用 REST 连接方式连接到 TDengine 数据库。整个过程主要涉及到数据库连接的建立和异常处理。 +下面是各语言连接器建立 REST 连接代码样例。演示了如何使用 REST 连接方式连接到 TDengine 数据库。整个过程主要涉及到数据库连接的建立和异常处理。 @@ -471,13 +540,15 @@ DSN 的详细说明和如何使用详见 [连接功能](../../reference/connecto ``` - + ```go + {{#include docs/examples/go/connect/restexample/main.go}} + ``` 不支持 - + C# 只支持 WebSocket 连接与原生连接 @@ -531,7 +602,13 @@ DSN 的详细说明和如何使用详见 [连接功能](../../reference/connecto - + +使用 `sql.Open` 创建出来的连接已经实现了连接池,可以通过 API 设置连接池参数,样例如下 + +```go +{{#include docs/examples/go/connect/connpool/main.go:pool}} +``` + @@ -563,7 +640,7 @@ let taos = pool.get()?; - + 不支持 diff --git a/docs/zh/08-develop/02-sql.md b/docs/zh/08-develop/02-sql.md index f24a35eb75..5476154158 100644 --- a/docs/zh/08-develop/02-sql.md +++ b/docs/zh/08-develop/02-sql.md @@ -11,6 +11,15 @@ TDengine 对 SQL 语言提供了全面的支持,允许用户以熟悉的 SQL 下面介绍使用各语言连接器通过执行 SQL 完成建库、建表、写入数据和查询数据。 +:::note + +REST 连接:各编程语言的连接器封装使用 `HTTP` 请求的连接,支持数据写入和查询操作。 + +REST API:通过 `curl` 命令进行数据写入和查询操作。 + +::: + + ## 建库和表 下面以智能电表为例,展示使用各语言连接器如何执行 SQL 命令创建一个名为 `power` 的数据库,然后使用 `power` 数据库为默认数据库。 接着创建一个名为 `meters` 的超级表(STABLE),其表结构包含时间戳、电流、电压、相位等列,以及分组 ID 和位置作为标签。 @@ -28,6 +37,9 @@ TDengine 对 SQL 语言提供了全面的支持,允许用户以熟悉的 SQL +```go +{{#include docs/examples/go/queryreqid/main.go:query_id}} +``` @@ -37,6 +49,9 @@ TDengine 对 SQL 语言提供了全面的支持,允许用户以熟悉的 SQL +```csharp +{{#include docs/examples/csharp/wsInsert/Program.cs:create_db_and_table}} +``` @@ -47,6 +62,23 @@ TDengine 对 SQL 语言提供了全面的支持,允许用户以熟悉的 SQL > **注意**:如果不使用 `USE power` 指定数据库,则后续对表的操作都需要增加数据库名称作为前缀,如 power.meters。 + + + +创建数据库 + +```bash +curl --location -uroot:taosdata 'http://127.0.0.1:6041/rest/sql' \ +--data 'CREATE DATABASE IF NOT EXISTS power' +``` + +创建表,在 url 中指定数据库为 `power` + +```bash +curl --location -uroot:taosdata 'http://127.0.0.1:6041/rest/sql/power' \ +--data 'CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))' +``` + > **注意**:如果不使用 `USE power` 指定数据库,则后续对表的操作都需要增加数据库名称作为前缀,如 `power.meters`。 @@ -68,6 +100,9 @@ NOW 为系统内部函数,默认为客户端所在计算机当前时间。 NOW +```go +{{#include docs/examples/go/sqlquery/main.go:create_db_and_table}} +``` @@ -77,6 +112,9 @@ NOW 为系统内部函数,默认为客户端所在计算机当前时间。 NOW +```csharp +{{#include docs/examples/csharp/wsInsert/Program.cs:insert_data}} +``` @@ -89,6 +127,16 @@ NOW 为系统内部函数,默认为客户端所在计算机当前时间。 NOW NOW 为系统内部函数,默认为客户端所在计算机当前时间。 NOW + 1s 代表客户端当前时间往后加 1 秒,数字后面代表时间单位:a(毫秒),s(秒),m(分),h(小时),d(天),w(周),n(月),y(年)。 + + + +写入数据 + +```bash +curl --location -uroot:taosdata 'http://127.0.0.1:6041/rest/sql' \ +--data 'INSERT INTO power.d1001 USING power.meters TAGS(2,'\''California.SanFrancisco'\'') 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(3, '\''California.SanFrancisco'\'') VALUES (NOW + 1a, 10.30000, 218, 0.25000)' +``` + @@ -108,6 +156,9 @@ NOW 为系统内部函数,默认为客户端所在计算机当前时间。 NOW +```go +{{#include docs/examples/go/sqlquery/main.go:insert_data}} +``` @@ -117,6 +168,9 @@ NOW 为系统内部函数,默认为客户端所在计算机当前时间。 NOW +```csharp +{{#include docs/examples/csharp/wsInsert/Program.cs:select_data}} +``` @@ -126,6 +180,16 @@ NOW 为系统内部函数,默认为客户端所在计算机当前时间。 NOW ``` + + + +查询数据 + +```bash +curl --location -uroot:taosdata 'http://127.0.0.1:6041/rest/sql' \ +--data 'SELECT ts, current, location FROM power.meters limit 100' +``` + @@ -153,6 +217,9 @@ reqId 可用于请求链路追踪,reqId 就像分布式系统中的 traceId +```go +{{#include docs/examples/go/sqlquery/main.go:select_data}} +``` @@ -162,6 +229,9 @@ reqId 可用于请求链路追踪,reqId 就像分布式系统中的 traceId +```csharp +{{#include docs/examples/csharp/wsInsert/Program.cs:query_id}} +``` @@ -171,5 +241,15 @@ reqId 可用于请求链路追踪,reqId 就像分布式系统中的 traceId ``` + + + +查询数据,指定 reqId 为 3 + +```bash +curl --location -uroot:taosdata 'http://127.0.0.1:6041/rest/sql?req_id=3' \ +--data 'SELECT ts, current, location FROM power.meters limit 1' +``` + diff --git a/docs/zh/08-develop/04-schemaless.md b/docs/zh/08-develop/04-schemaless.md index 9c136cb109..71c9a5e1bd 100644 --- a/docs/zh/08-develop/04-schemaless.md +++ b/docs/zh/08-develop/04-schemaless.md @@ -179,6 +179,9 @@ writer.write(lineDemo, SchemalessProtocolType.LINE, SchemalessTimestampType.NANO +```go +{{#include docs/examples/go/schemaless/ws/main.go}} +``` @@ -188,6 +191,9 @@ writer.write(lineDemo, SchemalessProtocolType.LINE, SchemalessTimestampType.NANO +```csharp +{{#include docs/examples/csharp/wssml/Program.cs:main}} +``` @@ -210,22 +216,25 @@ writer.write(lineDemo, SchemalessProtocolType.LINE, SchemalessTimestampType.NANO writer.write(lineDemo, SchemalessProtocolType.LINE, SchemalessTimestampType.NANO_SECONDS, 1L); ``` - - - - - - + + + + + + 除 DSN 不同,其余同 Websocket 代码示例。 - - - - - - - - - + + +```csharp +{{#include docs/examples/csharp/nativesml/Program.cs:main}} +``` + + + + + + + @@ -238,11 +247,15 @@ writer.write(lineDemo, SchemalessProtocolType.LINE, SchemalessTimestampType.NANO + ```go + {{#include docs/examples/go/schemaless/native/main.go}} + ``` 不支持 + 不支持 diff --git a/docs/zh/08-develop/05-stmt.md b/docs/zh/08-develop/05-stmt.md index 5dd9daaed5..b8c3c60d47 100644 --- a/docs/zh/08-develop/05-stmt.md +++ b/docs/zh/08-develop/05-stmt.md @@ -39,7 +39,9 @@ import TabItem from "@theme/TabItem"; ``` - +```go +{{#include docs/examples/go/stmt/ws/main.go}} +``` @@ -55,7 +57,9 @@ import TabItem from "@theme/TabItem"; ``` - +```csharp +{{#include docs/examples/csharp/wsStmt/Program.cs:main}} +``` @@ -83,13 +87,17 @@ import TabItem from "@theme/TabItem"; - +```go +{{#include docs/examples/go/stmt/native/main.go}} +``` 除 DSN 不同,其余同 Websocket 代码示例。 - +```csharp +{{#include docs/examples/csharp/stmtInsert/Program.cs:main}} +``` diff --git a/docs/zh/08-develop/07-tmq.md b/docs/zh/08-develop/07-tmq.md index 405d227e8e..cce21522cf 100644 --- a/docs/zh/08-develop/07-tmq.md +++ b/docs/zh/08-develop/07-tmq.md @@ -56,6 +56,19 @@ Java 连接器创建消费者的参数为 Properties, 可以设置的参数列 +创建消费者支持属性列表: + +- `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。 + +其他参数见上表。 + Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请参考 [DSN](../../reference/connector/rust/#dsn) @@ -66,6 +79,16 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 +创建消费者支持属性列表: + +- `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。 + +其他参数见上表。 @@ -99,7 +122,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```go +{{#include docs/examples/go/tmq/ws/main.go:create_consumer}} +``` @@ -116,7 +141,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```csharp +{{#include docs/examples/csharp/wssubscribe/Program.cs:create_consumer}} +``` @@ -156,7 +183,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```go +{{#include docs/examples/go/tmq/native/main.go:create_consumer}} +``` @@ -164,7 +193,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```csharp +{{#include docs/examples/csharp/subscribe/Program.cs:create_consumer}} +``` @@ -204,7 +235,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```go +{{#include docs/examples/go/tmq/ws/main.go:subscribe}} +``` @@ -216,7 +249,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```csharp +{{#include docs/examples/csharp/wssubscribe/Program.cs:subscribe}} +``` @@ -248,7 +283,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```go +{{#include docs/examples/go/tmq/native/main.go:subscribe}} +``` @@ -256,7 +293,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```csharp +{{#include docs/examples/csharp/subscribe/Program.cs:subscribe}} +``` @@ -293,7 +332,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```go +{{#include docs/examples/go/tmq/ws/main.go:seek}} +``` @@ -305,7 +346,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```csharp +{{#include docs/examples/csharp/wssubscribe/Program.cs:seek}} +``` @@ -337,7 +380,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```go +{{#include docs/examples/go/tmq/native/main.go:seek}} +``` @@ -345,7 +390,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```csharp +{{#include docs/examples/csharp/subscribe/Program.cs:seek}} +``` @@ -384,7 +431,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```go +{{#include docs/examples/go/tmq/ws/main.go:commit_offset}} +``` @@ -396,7 +445,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```csharp +{{#include docs/examples/csharp/wssubscribe/Program.cs:commit_offset}} +``` @@ -430,7 +481,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```go +{{#include docs/examples/go/tmq/native/main.go:commit_offset}} +``` @@ -442,7 +495,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```csharp +{{#include docs/examples/csharp/subscribe/Program.cs:commit_offset}} +``` @@ -481,7 +536,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```go +{{#include docs/examples/go/tmq/ws/main.go:close}} +``` @@ -493,7 +550,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```csharp +{{#include docs/examples/csharp/wssubscribe/Program.cs:close}} +``` @@ -511,7 +570,7 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 ### 原生连接 - + 同 Websocket 代码样例。 @@ -526,7 +585,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```go +{{#include docs/examples/go/tmq/native/main.go:close}} +``` @@ -538,7 +599,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```csharp +{{#include docs/examples/csharp/subscribe/Program.cs:close}} +``` @@ -578,7 +641,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```go +{{#include docs/examples/go/tmq/ws/main.go}} +``` @@ -590,7 +655,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```csharp +{{#include docs/examples/csharp/wssubscribe/Program.cs}} +``` @@ -631,7 +698,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```go +{{#include docs/examples/go/tmq/native/main.go}} +``` @@ -643,7 +712,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```csharp +{{#include docs/examples/csharp/subscribe/Program.cs}} +``` diff --git a/docs/zh/14-reference/05-connector/20-go.mdx b/docs/zh/14-reference/05-connector/20-go.mdx index c53f681f06..ff10a31124 100644 --- a/docs/zh/14-reference/05-connector/20-go.mdx +++ b/docs/zh/14-reference/05-connector/20-go.mdx @@ -12,16 +12,6 @@ import RequestId from "./_request_id.mdx"; `driver-go` 是 TDengine 的官方 Go 语言连接器,实现了 Go 语言 [database/sql](https://golang.org/pkg/database/sql/) 包的接口。Go 开发人员可以通过它开发存取 TDengine 集群数据的应用软件。 -## 连接方式 - -`driver-go` 提供三种建立连接的方式。 - -* **原生连接**,通过 TDengine 客户端驱动程序(taosc)原生连接 TDengine 实例,支持数据写入、查询、数据订阅、schemaless 接口和参数绑定接口等功能。 -* **REST 连接**,通过 taosAdapter 提供的 HTTP 接口连接 TDengine 实例,不支持 schemaless 和数据订阅等特性。 -* **Websocket 连接**,通过 taosAdapter 提供的 Websocket 接口连接 TDengine 实例,WebSocket 连接实现的功能集合和原生连接有少量不同。 - -连接方式的详细介绍请参考:[连接器建立连接的方式](../../develop/connect/#连接器建立连接的方式) - ## 兼容性 支持最低 Go 版本 1.14,建议使用最新 Go 版本 @@ -74,300 +64,6 @@ REST 连接支持所有能运行 Go 的平台。 **注意**:JSON 类型仅在 tag 中支持。 -## 安装步骤 - -### 安装前准备 - -* 安装 Go 开发环境(Go 1.14 及以上,GCC 4.8.5 及以上) -* 如果使用原生连接器,请安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../#安装客户端驱动) - -配置好环境变量,检查命令: - -* ```go env``` -* ```gcc -v``` - -### 安装连接器 - -1. 使用 `go mod` 命令初始化项目: - - ```text - go mod init taos-demo - ``` - -2. 引入 taosSql : - - ```go - import ( - "database/sql" - _ "github.com/taosdata/driver-go/v3/taosSql" - ) - ``` - -3. 使用 `go mod tidy` 更新依赖包: - - ```text - go mod tidy - ``` - -4. 使用 `go run taos-demo` 运行程序或使用 `go build` 命令编译出二进制文件。 - - ```text - go run taos-demo - go build - ``` - -## 建立连接 - -数据源名称具有通用格式,例如 [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 -``` - - - - -_taosSql_ 通过 cgo 实现了 Go 的 `database/sql/driver` 接口。只需要引入驱动就可以使用 [`database/sql`](https://golang.org/pkg/database/sql/) 的接口。 - -使用 `taosSql` 作为 `driverName` 并且使用一个正确的 [DSN](#DSN) 作为 `dataSourceName`,DSN 支持的参数: - -* cfg 指定 taos.cfg 目录 - -示例: - -```go -package main - -import ( - "database/sql" - "fmt" - - _ "github.com/taosdata/driver-go/v3/taosSql" -) - -func main() { - var taosUri = "root:taosdata@tcp(localhost:6030)/" - taos, err := sql.Open("taosSql", taosUri) - if err != nil { - fmt.Println("failed to connect TDengine, err:", err) - return - } -} -``` - - - - -_taosRestful_ 通过 `http client` 实现了 Go 的 `database/sql/driver` 接口。只需要引入驱动就可以使用[`database/sql`](https://golang.org/pkg/database/sql/)的接口。 - -使用 `taosRestful` 作为 `driverName` 并且使用一个正确的 [DSN](#DSN) 作为 `dataSourceName`,DSN 支持的参数: - -* `disableCompression` 是否接受压缩数据,默认为 true 不接受压缩数据,如果传输数据使用 gzip 压缩设置为 false。 -* `readBufferSize` 读取数据的缓存区大小默认为 4K(4096),当查询结果数据量多时可以适当调大该值。 - -示例: - -```go -package main - -import ( - "database/sql" - "fmt" - - _ "github.com/taosdata/driver-go/v3/taosRestful" -) - -func main() { - var taosUri = "root:taosdata@http(localhost:6041)/" - taos, err := sql.Open("taosRestful", taosUri) - if err != nil { - fmt.Println("failed to connect TDengine, err:", err) - return - } -} -``` - - - - -_taosWS_ 通过 `WebSocket` 实现了 Go 的 `database/sql/driver` 接口。只需要引入驱动(driver-go 最低版本 3.0.2)就可以使用[`database/sql`](https://golang.org/pkg/database/sql/)的接口。 - -使用 `taosWS` 作为 `driverName` 并且使用一个正确的 [DSN](#DSN) 作为 `dataSourceName`,DSN 支持的参数: - -* `writeTimeout` 通过 WebSocket 发送数据的超时时间。 -* `readTimeout` 通过 WebSocket 接收响应数据的超时时间。 - -示例: - -```go -package main - -import ( - "database/sql" - "fmt" - - _ "github.com/taosdata/driver-go/v3/taosWS" -) - -func main() { - var taosUri = "root:taosdata@ws(localhost:6041)/" - taos, err := sql.Open("taosWS", taosUri) - if err != nil { - fmt.Println("failed to connect TDengine, err:", err) - return - } -} -``` - - - - -### 指定 URL 和 Properties 获取连接 - -Go 连接器不支持此功能 - -### 配置参数的优先级 - -Go 连接器不支持此功能 - -## 使用示例 - -### 创建数据库和表 - -```go -{{#include docs/examples/go/demo/query/main.go:create_db_and_table}} -``` - -### 插入数据 - -```go -{{#include docs/examples/go/demo/query/main.go:insert_data}} -``` - -### 查询数据 - -```go -{{#include docs/examples/go/demo/query/main.go:query_data}} -``` - -### 执行带有 reqId 的 SQL - - - -```go -{{#include docs/examples/go/demo/query/main.go:with_reqid}} -``` - -### 通过参数绑定写入数据 - - - - -```go -{{#include docs/examples/go/demo/stmt/main.go}} -``` - - - - -```go -{{#include docs/examples/go/demo/stmtws/main.go}} -``` - - - - -### 无模式写入 - - - - -```go -{{#include docs/examples/go/demo/sml/main.go}} -``` - - - - -```go -{{#include docs/examples/go/demo/smlws/main.go}} -``` - - - - -### 执行带有 reqId 的无模式写入 - -```go -func (s *Schemaless) Insert(lines string, protocol int, precision string, ttl int, reqID int64) error -``` - -可以通过 `common.GetReqID()` 获取唯一 id。 - -### 数据订阅 - -TDengine Go 连接器支持订阅功能,应用 API 如下: - -#### 创建 Topic - -```go -{{#include docs/examples/go/demo/consumer/main.go:create_topic}} -``` - -#### 创建 Consumer - -```go -{{#include docs/examples/go/demo/consumer/main.go:create_consumer}} -``` - -#### 订阅消费数据 - -```go -{{#include docs/examples/go/demo/consumer/main.go:poll_data}} -``` - -#### 指定订阅 Offset - -```go -{{#include docs/examples/go/demo/consumer/main.go:consumer_seek}} -``` - -#### 关闭订阅 - -```go -{{#include docs/examples/go/demo/consumer/main.go:consumer_close}} -``` - -#### 完整示例 - - - - -```go -{{#include docs/examples/go/demo/consumer/main.go}} -``` - - - - -```go -{{#include docs/examples/go/demo/consumerws/main.go}} -``` - - - - -### 更多示例程序 - -* [示例程序](https://github.com/taosdata/driver-go/tree/3.0/examples) -* [视频教程](https://www.taosdata.com/blog/2020/11/11/1951.html)。 - ## 常见问题 1. database/sql 中 stmt(参数绑定)相关接口崩溃 @@ -1065,7 +761,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` - **接口说明**:订阅主题。 @@ -1195,4 +891,6 @@ type TopicPartition struct { ## 附录 -[driver-go 文档](https://pkg.go.dev/github.com/taosdata/driver-go/v3) +* [driver-go 文档](https://pkg.go.dev/github.com/taosdata/driver-go/v3)。 +* [示例程序](https://github.com/taosdata/driver-go/tree/3.0/examples)。 +* [视频教程](https://www.taosdata.com/blog/2020/11/11/1951.html)。 diff --git a/docs/zh/14-reference/05-connector/40-csharp.mdx b/docs/zh/14-reference/05-connector/40-csharp.mdx index ad316d581c..9ac4369c57 100644 --- a/docs/zh/14-reference/05-connector/40-csharp.mdx +++ b/docs/zh/14-reference/05-connector/40-csharp.mdx @@ -70,1144 +70,6 @@ TDengine 不再支持 32 位 Windows 平台。 JSON 类型仅在 tag 中支持。 ::: -## 安装步骤 - -### 安装前准备 - -* 安装 [.NET SDK](https://dotnet.microsoft.com/download) -* [Nuget 客户端](https://docs.microsoft.com/en-us/nuget/install-nuget-client-tools) (可选安装) -* 对于 Native 连接方式,需要安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../#安装客户端驱动),WebSocket 连接方式无需安装。 - -### 安装连接器 - -可以在当前 .NET 项目的路径下,通过 dotnet CLI 添加 Nuget package `TDengine.Connector` 到当前项目。 - -``` bash -dotnet add package TDengine.Connector -``` - -也可以修改当前项目的 `.csproj` 文件,添加如下 ItemGroup。 - -``` XML - - - -``` - -## 建立连接 - - - - -``` csharp -var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); -using (var client = DbDriver.Open(builder)) -{ - Console.WriteLine("connected"); -} -``` - - - - -```csharp -var builder = new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata"); -using (var client = DbDriver.Open(builder)) -{ - Console.WriteLine("connected"); -} -``` - - - -ConnectionStringBuilder 支持的参数如下: -* protocol: 连接协议,可选值为 Native 或 WebSocket,默认为 Native -* host: TDengine 或 taosadapter 运行实例的地址 -* port: TDengine 或 taosadapter 运行实例的端口 - * 当 protocol 为 WebSocket 时 useSSL 为 false 时,port 默认为 6041 - * 当 protocol 为 WebSocket 时 useSSL 为 true 时,port 默认为 443 -* useSSL: 是否使用 SSL 连接,仅当 protocol 为 WebSocket 时有效,默认为 false -* token: 连接 TDengine cloud 的 token,仅当 protocol 为 WebSocket 时有效 -* username: 连接 TDengine 的用户名 -* password: 连接 TDengine 的密码 -* db: 连接 TDengine 的数据库 -* timezone: 解析时间结果的时区,默认为 `TimeZoneInfo.Local`,使用 `TimeZoneInfo.FindSystemTimeZoneById` 方法解析字符串为 `TimeZoneInfo` 对象。 -* connTimeout: WebSocket 连接超时时间,仅当 protocol 为 WebSocket 时有效,默认为 1 分钟,使用 `TimeSpan.Parse` 方法解析字符串为 `TimeSpan` 对象。 -* readTimeout: WebSocket 读超时时间,仅当 protocol 为 WebSocket 时有效,默认为 5 分钟,使用 `TimeSpan.Parse` 方法解析字符串为 `TimeSpan` 对象。 -* writeTimeout: WebSocket 写超时时间,仅当 protocol 为 WebSocket 时有效,默认为 10 秒,使用 `TimeSpan.Parse` 方法解析字符串为 `TimeSpan` 对象。 -* autoReconnect: 是否自动重连(连接器版本 3.1.3 及以上生效),默认为 false -> **注意**:启用自动重连仅对简单执行 SQL 语句以及 无模式写入、数据订阅有效。对于参数绑定无效。自动重连仅对连接建立时通过参数指定数据库有效,对后面的 `use db` 语句切换数据库无效。 - -* reconnectRetryCount: 重连次数(连接器版本 3.1.3 及以上生效),默认为 3 -* reconnectIntervalMs: 重连间隔时间(连接器版本 3.1.3 及以上生效),默认为 2000 - -### 指定 URL 和 Properties 获取连接 - -C# 连接器不支持此功能 - -### 配置参数的优先级 - -C# 连接器不支持此功能 - -## 使用示例 - -### 创建数据库和表 - - - - -```csharp -using System; -using System.Text; -using TDengine.Driver; -using TDengine.Driver.Client; - -namespace NativeQuery -{ - internal class Query - { - public static void Main(string[] args) - { - var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) - { - try - { - client.Exec("create database power"); - client.Exec("CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); - } - catch (Exception e) - { - Console.WriteLine(e.ToString()); - throw; - } - } - } - } -} -``` - - - - -```csharp -using System; -using System.Text; -using TDengine.Driver; -using TDengine.Driver.Client; - -namespace WSQuery -{ - internal class Query - { - public static void Main(string[] args) - { - var builder = new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) - { - try - { - client.Exec("create database power"); - client.Exec("CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); - } - catch (Exception e) - { - Console.WriteLine(e.ToString()); - throw; - } - } - } - } -} -``` - - - - -### 插入数据 - - - - -```csharp -using System; -using System.Text; -using TDengine.Driver; -using TDengine.Driver.Client; - -namespace NativeQuery -{ - internal class Query - { - public static void Main(string[] args) - { - var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) - { - try - { - string insertQuery = - "INSERT INTO " + - "power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " + - "VALUES " + - "('2023-10-03 14:38:05.000', 10.30000, 219, 0.31000) " + - "('2023-10-03 14:38:15.000', 12.60000, 218, 0.33000) " + - "('2023-10-03 14:38:16.800', 12.30000, 221, 0.31000) " + - "power.d1002 USING power.meters TAGS(3, 'California.SanFrancisco') " + - "VALUES " + - "('2023-10-03 14:38:16.650', 10.30000, 218, 0.25000) " + - "power.d1003 USING power.meters TAGS(2,'California.LosAngeles') " + - "VALUES " + - "('2023-10-03 14:38:05.500', 11.80000, 221, 0.28000) " + - "('2023-10-03 14:38:16.600', 13.40000, 223, 0.29000) " + - "power.d1004 USING power.meters TAGS(3,'California.LosAngeles') " + - "VALUES " + - "('2023-10-03 14:38:05.000', 10.80000, 223, 0.29000) " + - "('2023-10-03 14:38:06.500', 11.50000, 221, 0.35000)"; - client.Exec(insertQuery); - } - catch (Exception e) - { - Console.WriteLine(e.ToString()); - throw; - } - } - } - } -} -``` - - - - -```csharp -using System; -using System.Text; -using TDengine.Driver; -using TDengine.Driver.Client; - -namespace WSQuery -{ - internal class Query - { - public static void Main(string[] args) - { - var builder = new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) - { - try - { - string insertQuery = - "INSERT INTO " + - "power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " + - "VALUES " + - "('2023-10-03 14:38:05.000', 10.30000, 219, 0.31000) " + - "('2023-10-03 14:38:15.000', 12.60000, 218, 0.33000) " + - "('2023-10-03 14:38:16.800', 12.30000, 221, 0.31000) " + - "power.d1002 USING power.meters TAGS(3, 'California.SanFrancisco') " + - "VALUES " + - "('2023-10-03 14:38:16.650', 10.30000, 218, 0.25000) " + - "power.d1003 USING power.meters TAGS(2,'California.LosAngeles') " + - "VALUES " + - "('2023-10-03 14:38:05.500', 11.80000, 221, 0.28000) " + - "('2023-10-03 14:38:16.600', 13.40000, 223, 0.29000) " + - "power.d1004 USING power.meters TAGS(3,'California.LosAngeles') " + - "VALUES " + - "('2023-10-03 14:38:05.000', 10.80000, 223, 0.29000) " + - "('2023-10-03 14:38:06.500', 11.50000, 221, 0.35000)"; - client.Exec(insertQuery); - } - catch (Exception e) - { - Console.WriteLine(e.ToString()); - throw; - } - } - } - } -} -``` - - - - -### 查询数据 - - - - -```csharp -using System; -using System.Text; -using TDengine.Driver; -using TDengine.Driver.Client; - -namespace NativeQuery -{ - internal class Query - { - public static void Main(string[] args) - { - var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) - { - try - { - client.Exec("use power"); - string query = "SELECT * FROM meters"; - using (var rows = client.Query(query)) - { - while (rows.Read()) - { - Console.WriteLine($"{((DateTime)rows.GetValue(0)):yyyy-MM-dd HH:mm:ss.fff}, {rows.GetValue(1)}, {rows.GetValue(2)}, {rows.GetValue(3)}, {rows.GetValue(4)}, {Encoding.UTF8.GetString((byte[])rows.GetValue(5))}"); - } - } - } - catch (Exception e) - { - Console.WriteLine(e.ToString()); - throw; - } - } - } - } -} -``` - - - - -```csharp -using System; -using System.Text; -using TDengine.Driver; -using TDengine.Driver.Client; - -namespace WSQuery -{ - internal class Query - { - public static void Main(string[] args) - { - var builder = new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) - { - try - { - client.Exec("use power"); - string query = "SELECT * FROM meters"; - using (var rows = client.Query(query)) - { - while (rows.Read()) - { - Console.WriteLine($"{((DateTime)rows.GetValue(0)):yyyy-MM-dd HH:mm:ss.fff}, {rows.GetValue(1)}, {rows.GetValue(2)}, {rows.GetValue(3)}, {rows.GetValue(4)}, {Encoding.UTF8.GetString((byte[])rows.GetValue(5))}"); - } - } - } - catch (Exception e) - { - Console.WriteLine(e.ToString()); - throw; - } - } - } - } -} -``` - - - - -### 执行带有 reqId 的 SQL - - - - - - -```csharp -using System; -using System.Text; -using TDengine.Driver; -using TDengine.Driver.Client; - -namespace NativeQueryWithReqID -{ - internal abstract class QueryWithReqID - { - public static void Main(string[] args) - { - var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) - { - try - { - client.Exec($"create database if not exists test_db",ReqId.GetReqId()); - } - catch (Exception e) - { - Console.WriteLine(e.ToString()); - throw; - } - } - } - } -} -``` - - - - -```csharp -using System; -using System.Text; -using TDengine.Driver; -using TDengine.Driver.Client; - -namespace WSQueryWithReqID -{ - internal abstract class QueryWithReqID - { - public static void Main(string[] args) - { - var builder = new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) - { - try - { - client.Exec($"create database if not exists test_db",ReqId.GetReqId()); - } - catch (Exception e) - { - Console.WriteLine(e.ToString()); - throw; - } - } - } - } -} -``` - - - - -### 通过参数绑定写入数据 - - - - -```csharp -using System; -using TDengine.Driver; -using TDengine.Driver.Client; - -namespace NativeStmt -{ - internal abstract class NativeStmt - { - public static void Main(string[] args) - { - var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) - { - try - { - client.Exec("create database power"); - client.Exec( - "CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); - using (var stmt = client.StmtInit()) - { - stmt.Prepare( - "Insert into power.d1001 using power.meters tags(2,'California.SanFrancisco') values(?,?,?,?)"); - var ts = new DateTime(2023, 10, 03, 14, 38, 05, 000); - stmt.BindRow(new object[] { ts, (float)10.30000, (int)219, (float)0.31000 }); - stmt.AddBatch(); - stmt.Exec(); - var affected = stmt.Affected(); - Console.WriteLine($"affected rows: {affected}"); - } - } - catch (Exception e) - { - Console.WriteLine(e); - throw; - } - } - } - } -} -``` - - - - -```csharp -using System; -using TDengine.Driver; -using TDengine.Driver.Client; - -namespace WSStmt -{ - internal abstract class WSStmt - { - public static void Main(string[] args) - { - var builder = new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) - { - try - { - client.Exec("create database power"); - client.Exec( - "CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); - using (var stmt = client.StmtInit()) - { - stmt.Prepare( - "Insert into power.d1001 using power.meters tags(2,'California.SanFrancisco') values(?,?,?,?)"); - var ts = new DateTime(2023, 10, 03, 14, 38, 05, 000); - stmt.BindRow(new object[] { ts, (float)10.30000, (int)219, (float)0.31000 }); - stmt.AddBatch(); - stmt.Exec(); - var affected = stmt.Affected(); - Console.WriteLine($"affected rows: {affected}"); - } - } - catch (Exception e) - { - Console.WriteLine(e); - throw; - } - } - } - } -} -``` - - - - -注意:使用 BindRow 需要注意原始 C# 列类型与 TDengine 列类型的需要一一对应,具体对应关系请参考 [TDengine DataType 和 C# DataType](#tdengine-datatype-和-c-datatype)。 - -### 无模式写入 - - - - -```csharp -using TDengine.Driver; -using TDengine.Driver.Client; - -namespace NativeSchemaless -{ - internal class Program - { - public static void Main(string[] args) - { - var builder = - new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) - { - client.Exec("create database sml"); - client.Exec("use sml"); - var influxDBData = - "st,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000"; - client.SchemalessInsert(new string[] { influxDBData }, - TDengineSchemalessProtocol.TSDB_SML_LINE_PROTOCOL, - TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_NANO_SECONDS, 0, ReqId.GetReqId()); - var telnetData = "stb0_0 1626006833 4 host=host0 interface=eth0"; - client.SchemalessInsert(new string[] { telnetData }, - TDengineSchemalessProtocol.TSDB_SML_TELNET_PROTOCOL, - TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS, 0, ReqId.GetReqId()); - var jsonData = - "{\"metric\": \"meter_current\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}"; - client.SchemalessInsert(new string[] { jsonData }, TDengineSchemalessProtocol.TSDB_SML_JSON_PROTOCOL, - TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS, 0, ReqId.GetReqId()); - } - } - } -} -``` - - - - -```csharp -using TDengine.Driver; -using TDengine.Driver.Client; - -namespace WSSchemaless -{ - internal class Program - { - public static void Main(string[] args) - { - var builder = - new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) - { - client.Exec("create database sml"); - client.Exec("use sml"); - var influxDBData = - "st,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000"; - client.SchemalessInsert(new string[] { influxDBData }, - TDengineSchemalessProtocol.TSDB_SML_LINE_PROTOCOL, - TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_NANO_SECONDS, 0, ReqId.GetReqId()); - var telnetData = "stb0_0 1626006833 4 host=host0 interface=eth0"; - client.SchemalessInsert(new string[] { telnetData }, - TDengineSchemalessProtocol.TSDB_SML_TELNET_PROTOCOL, - TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS, 0, ReqId.GetReqId()); - var jsonData = - "{\"metric\": \"meter_current\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}"; - client.SchemalessInsert(new string[] { jsonData }, TDengineSchemalessProtocol.TSDB_SML_JSON_PROTOCOL, - TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS, 0, ReqId.GetReqId()); - } - } - } -} -``` - - - - -### 执行带有 reqId 的无模式写入 - -```csharp -public void SchemalessInsert(string[] lines, TDengineSchemalessProtocol protocol, - TDengineSchemalessPrecision precision, - int ttl, long reqId) -``` - -### 数据订阅 - -#### 创建 Topic - - - - -```csharp -using System; -using System.Text; -using TDengine.Driver; -using TDengine.Driver.Client; - -namespace NativeSubscription -{ - internal class Program - { - public static void Main(string[] args) - { - var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) - { - try - { - client.Exec("create database power"); - client.Exec("CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); - client.Exec("CREATE TOPIC topic_meters as SELECT * from power.meters"); - } - catch (Exception e) - { - Console.WriteLine(e.ToString()); - throw; - } - } - } - } -} -``` - - - - -```csharp -using System; -using System.Text; -using TDengine.Driver; -using TDengine.Driver.Client; - -namespace WSSubscription -{ - internal class Program - { - public static void Main(string[] args) - { - var builder = new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) - { - try - { - client.Exec("create database power"); - client.Exec("CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); - client.Exec("CREATE TOPIC topic_meters as SELECT * from power.meters"); - } - catch (Exception e) - { - Console.WriteLine(e.ToString()); - throw; - } - } - } - } -} -``` - - - - -#### 创建 Consumer - - - - -```csharp -var cfg = new Dictionary() -{ - { "group.id", "group1" }, - { "auto.offset.reset", "latest" }, - { "td.connect.ip", "127.0.0.1" }, - { "td.connect.user", "root" }, - { "td.connect.pass", "taosdata" }, - { "td.connect.port", "6030" }, - { "client.id", "tmq_example" }, - { "enable.auto.commit", "true" }, - { "msg.with.table.name", "false" }, -}; -var consumer = new ConsumerBuilder>(cfg).Build(); -``` - - - - -```csharp -var cfg = new Dictionary() -{ - { "td.connect.type", "WebSocket" }, - { "group.id", "group1" }, - { "auto.offset.reset", "latest" }, - { "td.connect.ip", "localhost" }, - { "td.connect.port", "6041" }, - { "useSSL", "false" }, - { "td.connect.user", "root" }, - { "td.connect.pass", "taosdata" }, - { "client.id", "tmq_example" }, - { "enable.auto.commit", "true" }, - { "msg.with.table.name", "false" }, -}; -var consumer = new ConsumerBuilder>(cfg).Build(); -``` - - - - -consumer 支持的配置参数如下: -* td.connect.type: 连接类型,可选值为 Native 或 WebSocket,默认为 Native -* td.connect.ip: TDengine 或 taosadapter 运行实例的地址 -* td.connect.port: TDengine 或 taosadapter 运行实例的端口 - * 当 td.connect.type 为 WebSocket 且 useSSL 为 false 时,td.connect.port 默认为 6041 - * 当 td.connect.type 为 WebSocket 且 useSSL 为 true 时,td.connect.port 默认为 443 -* useSSL: 是否使用 SSL 连接,仅当 td.connect.type 为 WebSocket 时有效,默认为 false -* token: 连接 TDengine cloud 的 token,仅当 td.connect.type 为 WebSocket 时有效 - -* td.connect.user: 连接 TDengine 的用户名 -* td.connect.pass: 连接 TDengine 的密码 -* group.id: 消费者组 ID -* client.id: 消费者 ID -* enable.auto.commit: 是否自动提交 offset,默认为 true -* auto.commit.interval.ms: 自动提交 offset 的间隔时间,默认为 5000 毫秒 -* auto.offset.reset: 当 offset 不存在时,从哪里开始消费,可选值为 earliest 或 latest,默认为 latest -* msg.with.table.name: 消息是否包含表名 -* ws.message.enableCompression: 是否启用 WebSocket 压缩(dotnet 版本 6 及以上,连接器版本 3.1.1 及以上生效),默认为 false -* ws.autoReconnect: 是否自动重连(连接器版本 3.1.3 及以上生效),默认为 false -* ws.reconnect.retry.count: 重连次数(连接器版本 3.1.3 及以上生效),默认为 3 -* ws.reconnect.interval.ms: 重连间隔时间(连接器版本 3.1.3 及以上生效),默认为 2000 - - -支持订阅结果集 `Dictionary` key 为列名,value 为列值。 - -如果使用 object 接收列值,需要注意: -* 原始 C# 列类型与 TDengine 列类型的需要一一对应,具体对应关系请参考 [TDengine DataType 和 C# DataType](#tdengine-datatype-和-c-datatype)。 -* 列名与 class 属性名一致,并可读写。 -* 明确设置 value 解析器`ConsumerBuilder.SetValueDeserializer(new ReferenceDeserializer());` - -样例如下 - -结果 class - -```csharp - class Result - { - public DateTime ts { get; set; } - public float current { get; set; } - public int voltage { get; set; } - public float phase { get; set; } - } -``` - -设置解析器 - -```csharp -var tmqBuilder = new ConsumerBuilder(cfg); -tmqBuilder.SetValueDeserializer(new ReferenceDeserializer()); -var consumer = tmqBuilder.Build(); -``` - -也可实现自定义解析器,实现 `IDeserializer` 接口并通过`ConsumerBuilder.SetValueDeserializer`方法传入。 - -```csharp - public interface IDeserializer - { - T Deserialize(ITMQRows data, bool isNull, SerializationContext context); - } -``` - -#### 订阅消费数据 - -```csharp -consumer.Subscribe(new List() { "topic_meters" }); -while (true) -{ - using (var cr = consumer.Consume(500)) - { - if (cr == null) continue; - foreach (var message in cr.Message) - { - Console.WriteLine( - $"message {{{((DateTime)message.Value["ts"]).ToString("yyyy-MM-dd HH:mm:ss.fff")}, " + - $"{message.Value["current"]}, {message.Value["voltage"]}, {message.Value["phase"]}}}"); - } - } -} -``` - -#### 指定订阅 Offset - -```csharp -consumer.Assignment.ForEach(a => -{ - Console.WriteLine($"{a}, seek to 0"); - consumer.Seek(new TopicPartitionOffset(a.Topic, a.Partition, 0)); - Thread.Sleep(TimeSpan.FromSeconds(1)); -}); -``` - -#### 提交 Offset - -```csharp -public void Commit(ConsumeResult consumerResult) -public List Commit() -public void Commit(IEnumerable offsets) -``` - -#### 关闭订阅 - -```csharp -consumer.Unsubscribe(); -consumer.Close(); -``` - -#### 完整示例 - - - - -```csharp -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using TDengine.Driver; -using TDengine.Driver.Client; -using TDengine.TMQ; - -namespace NativeSubscription -{ - internal class Program - { - public static void Main(string[] args) - { - var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) - { - try - { - client.Exec("CREATE DATABASE power"); - client.Exec("USE power"); - client.Exec( - "CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); - client.Exec("CREATE TOPIC topic_meters as SELECT * from power.meters"); - var cfg = new Dictionary() - { - { "group.id", "group1" }, - { "auto.offset.reset", "latest" }, - { "td.connect.ip", "127.0.0.1" }, - { "td.connect.user", "root" }, - { "td.connect.pass", "taosdata" }, - { "td.connect.port", "6030" }, - { "client.id", "tmq_example" }, - { "enable.auto.commit", "true" }, - { "msg.with.table.name", "false" }, - }; - var consumer = new ConsumerBuilder>(cfg).Build(); - consumer.Subscribe(new List() { "topic_meters" }); - Task.Run(InsertData); - while (true) - { - using (var cr = consumer.Consume(500)) - { - if (cr == null) continue; - foreach (var message in cr.Message) - { - Console.WriteLine( - $"message {{{((DateTime)message.Value["ts"]).ToString("yyyy-MM-dd HH:mm:ss.fff")}, " + - $"{message.Value["current"]}, {message.Value["voltage"]}, {message.Value["phase"]}}}"); - } - consumer.Commit(); - } - } - } - catch (Exception e) - { - Console.WriteLine(e.ToString()); - throw; - } - } - } - - static void InsertData() - { - var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) - { - while (true) - { - client.Exec("INSERT into power.d1001 using power.meters tags(2,'California.SanFrancisco') values(now,11.5,219,0.30)"); - Task.Delay(1000).Wait(); - } - } - } - } -} -``` - - - - -```csharp -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using TDengine.Driver; -using TDengine.Driver.Client; -using TDengine.TMQ; - -namespace WSSubscription -{ - internal class Program - { - public static void Main(string[] args) - { - var builder = new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) - { - try - { - client.Exec("CREATE DATABASE power"); - client.Exec("USE power"); - client.Exec( - "CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); - client.Exec("CREATE TOPIC topic_meters as SELECT * from power.meters"); - var cfg = new Dictionary() - { - { "td.connect.type", "WebSocket" }, - { "group.id", "group1" }, - { "auto.offset.reset", "latest" }, - { "td.connect.ip", "localhost" }, - { "td.connect.port", "6041" }, - { "useSSL", "false" }, - { "td.connect.user", "root" }, - { "td.connect.pass", "taosdata" }, - { "client.id", "tmq_example" }, - { "enable.auto.commit", "true" }, - { "msg.with.table.name", "false" }, - }; - var consumer = new ConsumerBuilder>(cfg).Build(); - consumer.Subscribe(new List() { "topic_meters" }); - Task.Run(InsertData); - while (true) - { - using (var cr = consumer.Consume(500)) - { - if (cr == null) continue; - foreach (var message in cr.Message) - { - Console.WriteLine( - $"message {{{((DateTime)message.Value["ts"]).ToString("yyyy-MM-dd HH:mm:ss.fff")}, " + - $"{message.Value["current"]}, {message.Value["voltage"]}, {message.Value["phase"]}}}"); - } - consumer.Commit(); - } - } - } - catch (Exception e) - { - Console.WriteLine(e.ToString()); - throw; - } - } - } - - static void InsertData() - { - var builder = new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) - { - while (true) - { - client.Exec("INSERT into power.d1001 using power.meters tags(2,'California.SanFrancisco') values(now,11.5,219,0.30)"); - Task.Delay(1000).Wait(); - } - } - } - } -} -``` - - - - -### ADO.NET - -C# 连接器支持 ADO.NET 接口,可以通过 ADO.NET 接口连接 TDengine 运行实例,进行数据写入、查询等操作。 - - - - -```csharp -using System; -using TDengine.Data.Client; - -namespace NativeADO -{ - internal class Program - { - public static void Main(string[] args) - { - const string connectionString = "host=localhost;port=6030;username=root;password=taosdata"; - using (var connection = new TDengineConnection(connectionString)) - { - try - { - connection.Open(); - using (var command = new TDengineCommand(connection)) - { - command.CommandText = "create database power"; - command.ExecuteNonQuery(); - connection.ChangeDatabase("power"); - command.CommandText = - "CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"; - command.ExecuteNonQuery(); - command.CommandText = "INSERT INTO " + - "power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " + - "VALUES " + - "(?,?,?,?)"; - var parameters = command.Parameters; - parameters.Add(new TDengineParameter("@0", new DateTime(2023,10,03,14,38,05,000))); - parameters.Add(new TDengineParameter("@1", (float)10.30000)); - parameters.Add(new TDengineParameter("@2", (int)219)); - parameters.Add(new TDengineParameter("@3", (float)0.31000)); - command.ExecuteNonQuery(); - command.Parameters.Clear(); - command.CommandText = "SELECT * FROM meters"; - using (var reader = command.ExecuteReader()) - { - while (reader.Read()) - { - Console.WriteLine( - $"{((DateTime) reader.GetValue(0)):yyyy-MM-dd HH:mm:ss.fff}, {reader.GetValue(1)}, {reader.GetValue(2)}, {reader.GetValue(3)}, {reader.GetValue(4)}, {System.Text.Encoding.UTF8.GetString((byte[]) reader.GetValue(5))}"); - } - } - } - } - catch (Exception e) - { - Console.WriteLine(e); - throw; - } - } - } - } -} -``` - - - - -```csharp -using System; -using TDengine.Data.Client; - -namespace WSADO -{ - internal class Program - { - public static void Main(string[] args) - { - const string connectionString = "protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata"; - using (var connection = new TDengineConnection(connectionString)) - { - try - { - connection.Open(); - using (var command = new TDengineCommand(connection)) - { - command.CommandText = "create database power"; - command.ExecuteNonQuery(); - connection.ChangeDatabase("power"); - command.CommandText = - "CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"; - command.ExecuteNonQuery(); - command.CommandText = "INSERT INTO " + - "power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " + - "VALUES " + - "(?,?,?,?)"; - var parameters = command.Parameters; - parameters.Add(new TDengineParameter("@0", new DateTime(2023,10,03,14,38,05,000))); - parameters.Add(new TDengineParameter("@1", (float)10.30000)); - parameters.Add(new TDengineParameter("@2", (int)219)); - parameters.Add(new TDengineParameter("@3", (float)0.31000)); - command.ExecuteNonQuery(); - command.Parameters.Clear(); - command.CommandText = "SELECT * FROM meters"; - using (var reader = command.ExecuteReader()) - { - while (reader.Read()) - { - Console.WriteLine( - $"{((DateTime) reader.GetValue(0)):yyyy-MM-dd HH:mm:ss.fff}, {reader.GetValue(1)}, {reader.GetValue(2)}, {reader.GetValue(3)}, {reader.GetValue(4)}, {System.Text.Encoding.UTF8.GetString((byte[]) reader.GetValue(5))}"); - } - } - } - } - catch (Exception e) - { - Console.WriteLine(e); - throw; - } - } - } - } -} -``` - - - - -* 连接参数与[建立连接](#建立连接)中的连接参数一致。 -* TDengineParameter 的 name 需要以 @ 开头,如 @0、@1、@2 等,value 需要 C# 列类型与 TDengine 列类型一一对应,具体对应关系请参考 [TDengine DataType 和 C# DataType](#tdengine-datatype-和-c-datatype)。 - -### 更多示例程序 - -[示例程序](https://github.com/taosdata/taos-connector-dotnet/tree/3.0/examples) - ## API 参考 ### ADO.NET 驱动 @@ -1781,14 +643,14 @@ C# 驱动提供了符合 ADO.NET 标准的 `DbDataReader` 接口,提供了用 创建消费者支持属性列表: -- `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 +- `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 默认值发生变化。 +其他参数请参考:[Consumer 参数列表](../../../develop/tmq/#创建参数), 注意TDengine服务端自 3.2.0.0 版本开始消息订阅中的 auto.offset.reset 默认值发生变化。 - `public IConsumer Build()` - **接口说明**:构建消费者。 @@ -1944,4 +806,8 @@ ReferenceDeserializer 用来将消费到的一条记录反序列化为一个对 DictionaryDeserializer 则会将消费到的一行数据反序列化为一个 `Dictionary` 对象,其 key 为列名,值为对象。 -ReferenceDeserializer 和 DictionaryDeserializer 的接口不会被用户直接调用,请参考使用样例。 \ No newline at end of file +ReferenceDeserializer 和 DictionaryDeserializer 的接口不会被用户直接调用,请参考使用样例。 + +## 附录 + +[更多示例程序](https://github.com/taosdata/taos-connector-dotnet/tree/3.0/examples)。 \ No newline at end of file From b70d0c66b3c3bec258bff915f452f6d5780b51db Mon Sep 17 00:00:00 2001 From: sheyanjie-qq <249478495@qq.com> Date: Fri, 2 Aug 2024 14:50:07 +0800 Subject: [PATCH 05/15] mod java code --- .../rust/nativeexample/examples/query.rs | 97 +++-- .../rust/nativeexample/examples/tmq.rs | 8 +- .../examples/rust/restexample/examples/tmq.rs | 10 +- docs/zh/08-develop/07-tmq.md | 5 +- .../com/taosdata/example/AbsConsumerLoop.java | 146 ++++---- .../taosdata/example/ConsumerLoopFull.java | 209 +++++------ .../com/taosdata/example/ConsumerLoopImp.java | 6 +- .../taosdata/example/ConsumerOffsetSeek.java | 42 +-- .../com/taosdata/example/JdbcBasicDemo.java | 118 +++--- .../com/taosdata/example/JdbcCreatDBDemo.java | 48 +-- .../taosdata/example/JdbcInsertDataDemo.java | 50 +-- .../com/taosdata/example/JdbcQueryDemo.java | 50 +-- .../com/taosdata/example/JdbcReqIdDemo.java | 38 +- .../taosdata/example/WsConsumerLoopFull.java | 337 +++++++++--------- 14 files changed, 592 insertions(+), 572 deletions(-) diff --git a/docs/examples/rust/nativeexample/examples/query.rs b/docs/examples/rust/nativeexample/examples/query.rs index a493e7c729..55c2feb7b7 100644 --- a/docs/examples/rust/nativeexample/examples/query.rs +++ b/docs/examples/rust/nativeexample/examples/query.rs @@ -7,62 +7,61 @@ async fn main() -> anyhow::Result<()> { let taos = builder.build()?; -// ANCHOR: create_db_and_table -let db = "power"; -// create database -taos.exec_many([ - format!("CREATE DATABASE IF NOT EXISTS `{db}`"), - format!("USE `{db}`"), -]) -.await?; -println!("Create database power successfully."); + // ANCHOR: create_db_and_table + let db = "power"; + // create database + taos.exec_many([ + format!("CREATE DATABASE IF NOT EXISTS `{db}`"), + format!("USE `{db}`"), + ]) + .await?; + println!("Create database power successfully."); -// create super table -taos.exec_many([ - "CREATE TABLE `meters` (`ts` TIMESTAMP, `current` FLOAT, `voltage` INT, `phase` FLOAT) \ - TAGS (`groupid` INT, `location` BINARY(24))", -]).await?; -println!("Create stable meters successfully."); + // create super table + taos.exec_many([ + "CREATE TABLE `meters` (`ts` TIMESTAMP, `current` FLOAT, `voltage` INT, `phase` FLOAT) \ + TAGS (`groupid` INT, `location` BINARY(24))", + ]).await?; + println!("Create stable meters successfully."); -// ANCHOR_END: create_db_and_table + // ANCHOR_END: create_db_and_table -// ANCHOR: insert_data -let inserted = taos.exec("INSERT INTO " + -"power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " + -"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(3, 'California.SanFrancisco') " + -"VALUES " + -"(NOW + 1a, 10.30000, 218, 0.25000) ").await?; + // ANCHOR: insert_data + let inserted = taos.exec("INSERT INTO " + + "power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " + + "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(3, 'California.SanFrancisco') " + + "VALUES " + + "(NOW + 1a, 10.30000, 218, 0.25000) ").await?; -println!("inserted: {} rows to power.meters successfully.", inserted); -// ANCHOR_END: insert_data + println!("inserted: {} rows to power.meters successfully.", inserted); + // ANCHOR_END: insert_data -// ANCHOR: query_data -// query data, make sure the database and table are created before -let mut result = taos.query("SELECT ts, current, location FROM power.meters limit 100").await?; + // ANCHOR: query_data + // query data, make sure the database and table are created before + let mut result = taos.query("SELECT ts, current, location FROM power.meters limit 100").await?; -for field in result.fields() { - println!("got field: {}", field.name()); -} - -let mut rows = result.rows(); -let mut nrows = 0; -while let Some(row) = rows.try_next().await? { - for (col, (name, value)) in row.enumerate() { - println!( - "[{}] got value in col {} (named `{:>8}`): {}", - nrows, col, name, value - ); + for field in result.fields() { + println!("got field: {}", field.name()); } - nrows += 1; -} -// ANCHOR_END: query_data -// ANCHOR: query_with_req_id -let result = taos.query_with_req_id("SELECT ts, current, location FROM power.meters limit 1", 1).await?; -// ANCHOR_END: query_with_req_id + let mut rows = result.rows(); + let mut nrows = 0; + while let Some(row) = rows.try_next().await? { + for (col, (name, value)) in row.enumerate() { + println!( + "[{}] got value in col {} (named `{:>8}`): {}", + nrows, col, name, value + ); + } + nrows += 1; + } + // ANCHOR_END: query_data + // ANCHOR: query_with_req_id + let result = taos.query_with_req_id("SELECT ts, current, location FROM power.meters limit 1", 1).await?; + // ANCHOR_END: query_with_req_id } diff --git a/docs/examples/rust/nativeexample/examples/tmq.rs b/docs/examples/rust/nativeexample/examples/tmq.rs index 764c0c1fc8..04bf66b2ef 100644 --- a/docs/examples/rust/nativeexample/examples/tmq.rs +++ b/docs/examples/rust/nativeexample/examples/tmq.rs @@ -44,8 +44,12 @@ async fn main() -> anyhow::Result<()> { // ANCHOR_END: create_topic // ANCHOR: create_consumer - dsn.params.insert("group.id".to_string(), "abc".to_string()); - dsn.params.insert("auto.offset.reset".to_string(), "earliest".to_string()); + dsn.params.insert("auto.offset.reset".to_string(), "latest".to_string()); + dsn.params.insert("msg.with.table.name".to_string(), "true".to_string()); + dsn.params.insert("enable.auto.commit".to_string(), "true".to_string()); + dsn.params.insert("auto.commit.interval.ms".to_string(), "1000".to_string()); + dsn.params.insert("group.id".to_string(), "group1".to_string()); + dsn.params.insert("client.id".to_string(), "client1".to_string()); let builder = TmqBuilder::from_dsn(&dsn)?; let mut consumer = builder.build().await?; diff --git a/docs/examples/rust/restexample/examples/tmq.rs b/docs/examples/rust/restexample/examples/tmq.rs index 8f195e1629..0438e47515 100644 --- a/docs/examples/rust/restexample/examples/tmq.rs +++ b/docs/examples/rust/restexample/examples/tmq.rs @@ -9,9 +9,11 @@ async fn main() -> anyhow::Result<()> { .filter_level(log::LevelFilter::Info) .init(); use taos_query::prelude::*; + // ANCHOR: create_consumer_dsn let dsn = "ws://localhost:6041".to_string(); log::info!("dsn: {}", dsn); let mut dsn = Dsn::from_str(&dsn)?; + // ANCHOR_END: create_consumer_dsn let taos = TaosBuilder::from_dsn(&dsn)?.build().await?; @@ -41,8 +43,12 @@ async fn main() -> anyhow::Result<()> { // ANCHOR_END: create_topic // ANCHOR: create_consumer - dsn.params.insert("group.id".to_string(), "abc".to_string()); - dsn.params.insert("auto.offset.reset".to_string(), "earliest".to_string()); + dsn.params.insert("auto.offset.reset".to_string(), "latest".to_string()); + dsn.params.insert("msg.with.table.name".to_string(), "true".to_string()); + dsn.params.insert("enable.auto.commit".to_string(), "true".to_string()); + dsn.params.insert("auto.commit.interval.ms".to_string(), "1000".to_string()); + dsn.params.insert("group.id".to_string(), "group1".to_string()); + dsn.params.insert("client.id".to_string(), "client1".to_string()); let builder = TmqBuilder::from_dsn(&dsn)?; let mut consumer = builder.build().await?; diff --git a/docs/zh/08-develop/07-tmq.md b/docs/zh/08-develop/07-tmq.md index 405d227e8e..a5795b5b6e 100644 --- a/docs/zh/08-develop/07-tmq.md +++ b/docs/zh/08-develop/07-tmq.md @@ -104,9 +104,10 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - ```rust -{{#include docs/examples/rust/nativeexample/examples/tmq.rs:create_consumer}} +{{#include docs/examples/rust/restexample/examples/tmq.rs:create_consumer_dsn}} + +{{#include docs/examples/rust/restexample/examples/tmq.rs:create_consumer}} ``` 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 f7570c742a..842abb4086 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 @@ -24,24 +24,24 @@ public abstract class AbsConsumerLoop { public AbsConsumerLoop() 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", "client1"); -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 with " + config.getProperty("bootstrap.servers") + " ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); - throw new SQLException("Failed to create consumer", ex); -} + 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", "client1"); + 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 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"); @@ -53,65 +53,65 @@ try { public void pollDataCodePiece() throws SQLException { // ANCHOR: poll_data_code_piece -try { - consumer.subscribe(topics); - while (!shutdown.get()) { - ConsumerRecords records = consumer.poll(Duration.ofMillis(100)); - for (ConsumerRecord record : records) { - ResultBean bean = record.value(); - // process your data here - process(bean); + try { + consumer.subscribe(topics); + while (!shutdown.get()) { + ConsumerRecords records = consumer.poll(Duration.ofMillis(100)); + for (ConsumerRecord record : records) { + ResultBean bean = record.value(); + // process your data here + process(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); + } finally { + consumer.close(); + shutdownLatch.countDown(); } - } -} 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); -} finally { - consumer.close(); - shutdownLatch.countDown(); -} // ANCHOR_END: poll_data_code_piece } public void commitCodePiece() throws SQLException { // ANCHOR: commit_code_piece -try { - consumer.subscribe(topics); - while (!shutdown.get()) { - ConsumerRecords records = consumer.poll(Duration.ofMillis(100)); - for (ConsumerRecord record : records) { - ResultBean bean = record.value(); - // process your data here - process(bean); + try { + consumer.subscribe(topics); + while (!shutdown.get()) { + ConsumerRecords records = consumer.poll(Duration.ofMillis(100)); + for (ConsumerRecord record : records) { + ResultBean bean = record.value(); + // process your data here + process(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); + } finally { + consumer.close(); + shutdownLatch.countDown(); } - 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); -} finally { - consumer.close(); - shutdownLatch.countDown(); -} // ANCHOR_END: commit_code_piece } public void unsubscribeCodePiece() throws SQLException { // 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(); -} + 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 } @@ -119,14 +119,14 @@ try { try { // ANCHOR: poll_data -consumer.subscribe(topics); -while (!shutdown.get()) { - ConsumerRecords records = consumer.poll(Duration.ofMillis(100)); - for (ConsumerRecord record : records) { - ResultBean bean = record.value(); - process(bean); - } -} + consumer.subscribe(topics); + while (!shutdown.get()) { + ConsumerRecords records = consumer.poll(Duration.ofMillis(100)); + for (ConsumerRecord record : records) { + ResultBean bean = record.value(); + process(bean); + } + } // ANCHOR_END: poll_data consumer.unsubscribe(); 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 index 4012f2e679..c78a875ab6 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ConsumerLoopFull.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ConsumerLoopFull.java @@ -15,37 +15,38 @@ import java.util.concurrent.TimeUnit; 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); -} + 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()){ + try (TaosConsumer consumer = getConsumer()) { // subscribe to the topics List topics = Collections.singletonList("topic_meters"); @@ -72,96 +73,97 @@ try { public static void pollExample() throws SQLException { // ANCHOR: poll_data_code_piece -try (TaosConsumer consumer = getConsumer()){ - List topics = Collections.singletonList("topic_meters"); + 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)); + // 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); } - } - -} 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"); + 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)); - } + // 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; - } + 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; - } + // 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); -} + } 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"); + 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)); + 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); } - 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"); @@ -169,7 +171,7 @@ try (TaosConsumer consumer = getConsumer()){ // ANCHOR: unsubscribe_data_code_piece try { consumer.unsubscribe(); - } catch (SQLException ex){ + } 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); @@ -182,6 +184,7 @@ try (TaosConsumer consumer = getConsumer()){ 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; @@ -240,12 +243,12 @@ try (TaosConsumer consumer = getConsumer()){ } } - public static void prepareData() throws SQLException{ + 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++){ + for (int i = 0; i < 10000; i++) { insertQuery.append("(NOW + ").append(i).append("a, 10.30000, 219, 0.31000) "); } try { @@ -256,7 +259,8 @@ try (TaosConsumer consumer = getConsumer()){ throw new SQLException("Failed to insert data to power.meters", ex); } } - public static void prepareMeta() throws SQLException{ + + public static void prepareMeta() throws SQLException { try { statement.executeUpdate("CREATE DATABASE IF NOT EXISTS power"); statement.executeUpdate("USE power"); @@ -288,6 +292,7 @@ try (TaosConsumer consumer = getConsumer()){ } System.out.println("Connection created successfully."); } + public static void closeConnection() throws SQLException { try { if (statement != null) { @@ -337,16 +342,16 @@ try (TaosConsumer consumer = getConsumer()){ System.out.println("Data prepared successfully"); - // 关闭线程池,不再接收新任务 + // close the executor, which will make the executor reject new tasks executor.shutdown(); try { - // 等待直到所有任务完成 + // wait for the executor to terminate boolean result = executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); assert result; } catch (InterruptedException e) { Thread.currentThread().interrupt(); - } catch (Exception e){ + } catch (Exception e) { e.printStackTrace(); System.out.println("Wait executor termination failed."); } diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ConsumerLoopImp.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ConsumerLoopImp.java index 22f96841e6..84d84f062b 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ConsumerLoopImp.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ConsumerLoopImp.java @@ -20,9 +20,9 @@ public class ConsumerLoopImp { properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); // ANCHOR: create_topic -Connection connection = DriverManager.getConnection(url, properties); -Statement statement = connection.createStatement(); -statement.executeUpdate("CREATE TOPIC IF NOT EXISTS topic_meters AS SELECT ts, current, voltage, phase, groupid, location FROM meters"); + Connection connection = DriverManager.getConnection(url, properties); + Statement statement = connection.createStatement(); + statement.executeUpdate("CREATE TOPIC IF NOT EXISTS topic_meters AS SELECT ts, current, voltage, phase, groupid, location FROM meters"); // ANCHOR_END: create_topic statement.close(); 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 b9463d30f7..73901aba49 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 @@ -35,29 +35,29 @@ public class ConsumerOffsetSeek { config.setProperty("value.deserializer.encoding", "UTF-8"); // ANCHOR: consumer_seek -String topic = "topic_meters"; -Map offset = null; -try (TaosConsumer consumer = new TaosConsumer<>(config)) { - consumer.subscribe(Collections.singletonList(topic)); - for (int i = 0; i < 10; i++) { - if (i == 3) { - // Saving consumption position - offset = consumer.position(topic); - } - if (i == 5) { - // reset consumption to the previously saved position - for (Map.Entry entry : offset.entrySet()) { - consumer.seek(entry.getKey(), entry.getValue()); + String topic = "topic_meters"; + Map offset = null; + try (TaosConsumer consumer = new TaosConsumer<>(config)) { + consumer.subscribe(Collections.singletonList(topic)); + for (int i = 0; i < 10; i++) { + if (i == 3) { + // Saving consumption position + offset = consumer.position(topic); + } + if (i == 5) { + // reset consumption to the previously saved position + for (Map.Entry entry : offset.entrySet()) { + consumer.seek(entry.getKey(), entry.getValue()); + } + } + ConsumerRecords records = consumer.poll(Duration.ofMillis(500)); + // you can handle data here } + } catch (SQLException 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); } - ConsumerRecords records = consumer.poll(Duration.ofMillis(500)); - // you can handle data here - } -} catch (SQLException 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 } } \ No newline at end of file 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 4831567eab..945c321260 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 @@ -16,97 +16,97 @@ public class JdbcBasicDemo { public static void main(String[] args) throws SQLException { -final String url = "jdbc:TAOS://" + host + ":6030/?user=" + user + "&password=" + password; + final String url = "jdbc:TAOS://" + host + ":6030/?user=" + user + "&password=" + password; // get connection -Properties properties = new Properties(); -properties.setProperty("charset", "UTF-8"); -properties.setProperty("locale", "en_US.UTF-8"); -properties.setProperty("timezone", "UTC-8"); -System.out.println("get connection starting..."); -try(Connection connection = DriverManager.getConnection(url, properties)){ + Properties properties = new Properties(); + properties.setProperty("charset", "UTF-8"); + properties.setProperty("locale", "en_US.UTF-8"); + properties.setProperty("timezone", "UTC-8"); + System.out.println("get connection starting..."); + try (Connection connection = DriverManager.getConnection(url, properties)) { -if (connection != null){ - System.out.println("[ OK ] Connection established."); -} else { - System.out.println("[ ERR ] Connection can not be established."); - return; -} + if (connection != null) { + System.out.println("[ OK ] Connection established."); + } else { + System.out.println("[ ERR ] Connection can not be established."); + return; + } -Statement stmt = connection.createStatement(); + Statement stmt = connection.createStatement(); // ANCHOR: create_db_and_table // create database -stmt.executeUpdate("CREATE DATABASE IF NOT EXISTS power"); + stmt.executeUpdate("CREATE DATABASE IF NOT EXISTS power"); // use database -stmt.executeUpdate("USE power"); + stmt.executeUpdate("USE power"); // create table -stmt.executeUpdate("CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); + stmt.executeUpdate("CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); // ANCHOR_END: create_db_and_table // ANCHOR: insert_data // insert data -String insertQuery = "INSERT INTO " + - "power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " + - "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(3, 'California.SanFrancisco') " + - "VALUES " + - "(NOW + 1a, 10.30000, 218, 0.25000) "; -int affectedRows = stmt.executeUpdate(insertQuery); -System.out.println("insert " + affectedRows + " rows."); + String insertQuery = "INSERT INTO " + + "power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " + + "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(3, 'California.SanFrancisco') " + + "VALUES " + + "(NOW + 1a, 10.30000, 218, 0.25000) "; + int affectedRows = stmt.executeUpdate(insertQuery); + System.out.println("insert " + affectedRows + " rows."); // ANCHOR_END: insert_data // ANCHOR: query_data // query data -ResultSet resultSet = stmt.executeQuery("SELECT * FROM meters"); + ResultSet resultSet = stmt.executeQuery("SELECT * FROM meters"); -Timestamp ts; -float current; -String location; -while(resultSet.next()){ - ts = resultSet.getTimestamp(1); - current = resultSet.getFloat(2); - location = resultSet.getString("location"); + Timestamp ts; + float current; + String location; + while (resultSet.next()) { + ts = resultSet.getTimestamp(1); + current = resultSet.getFloat(2); + location = resultSet.getString("location"); - System.out.printf("%s, %f, %s\n", ts, current, location); -} + System.out.printf("%s, %f, %s\n", ts, current, location); + } // ANCHOR_END: query_data // ANCHOR: with_reqid -AbstractStatement aStmt = (AbstractStatement) connection.createStatement(); -aStmt.execute("CREATE DATABASE IF NOT EXISTS power", 1L); -aStmt.executeUpdate("USE power", 2L); -try (ResultSet rs = aStmt.executeQuery("SELECT * FROM meters limit 1", 3L)) { - while(rs.next()){ - Timestamp timestamp = rs.getTimestamp(1); - System.out.println("timestamp = " + timestamp); - } -} -aStmt.close(); + AbstractStatement aStmt = (AbstractStatement) connection.createStatement(); + aStmt.execute("CREATE DATABASE IF NOT EXISTS power", 1L); + aStmt.executeUpdate("USE power", 2L); + try (ResultSet rs = aStmt.executeQuery("SELECT * FROM meters limit 1", 3L)) { + while (rs.next()) { + Timestamp timestamp = rs.getTimestamp(1); + System.out.println("timestamp = " + timestamp); + } + } + aStmt.close(); // ANCHOR_END: with_reqid -String sql = "SELECT * FROM meters limit 2;"; + String sql = "SELECT * FROM meters limit 2;"; // ANCHOR: jdbc_exception -try (Statement statement = connection.createStatement(); - // executeQuery - ResultSet tempResultSet = statement.executeQuery(sql)) { + try (Statement statement = connection.createStatement(); + // executeQuery + ResultSet tempResultSet = statement.executeQuery(sql)) { - // print result - printResult(tempResultSet); -} catch (SQLException e) { - System.out.println("ERROR Message: " + e.getMessage()); - System.out.println("ERROR Code: " + e.getErrorCode()); - e.printStackTrace(); -} + // print result + printResult(tempResultSet); + } catch (SQLException e) { + System.out.println("ERROR Message: " + e.getMessage()); + System.out.println("ERROR Code: " + e.getErrorCode()); + e.printStackTrace(); + } // ANCHOR_END: jdbc_exception } 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/JdbcCreatDBDemo.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcCreatDBDemo.java index d02b3c8789..f5f5b1c62c 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,37 +15,37 @@ public class JdbcCreatDBDemo { public static void main(String[] args) throws SQLException { -final String jdbcUrl = "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(); -properties.setProperty("charset", "UTF-8"); -properties.setProperty("locale", "en_US.UTF-8"); -properties.setProperty("timezone", "UTC-8"); -System.out.println("get connection starting..."); + Properties properties = new Properties(); + properties.setProperty("charset", "UTF-8"); + 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(jdbcUrl, properties); - Statement stmt = connection.createStatement()) { + try (Connection connection = DriverManager.getConnection(jdbcUrl, properties); + Statement stmt = connection.createStatement()) { - // create database - int rowsAffected = stmt.executeUpdate("CREATE DATABASE IF NOT EXISTS power"); - // you can check rowsAffected here - assert rowsAffected == 0; + // create database + int rowsAffected = stmt.executeUpdate("CREATE DATABASE IF NOT EXISTS power"); + // you can check rowsAffected here + assert rowsAffected == 0; - // use database - rowsAffected = stmt.executeUpdate("USE power"); - // you can check rowsAffected here - assert rowsAffected == 0; + // use database + rowsAffected = stmt.executeUpdate("USE power"); + // you can check rowsAffected here + assert rowsAffected == 0; - // create table - rowsAffected = stmt.executeUpdate("CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); - // you can check rowsAffected here - assert rowsAffected == 0; + // create table + rowsAffected = stmt.executeUpdate("CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); + // you can check rowsAffected here + assert rowsAffected == 0; -} catch (SQLException ex) { - // handle any errors, please refer to the JDBC specifications for detailed exceptions info - System.out.println("Failed to create db and table, url:" + jdbcUrl + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); -} + } catch (SQLException ex) { + // handle any errors, please refer to the JDBC specifications for detailed exceptions info + 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 7fc6d5137d..f8e11a8f41 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,36 +15,36 @@ public class JdbcInsertDataDemo { public static void main(String[] args) throws SQLException { -final String jdbcUrl = "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(); -properties.setProperty("charset", "UTF-8"); -properties.setProperty("locale", "en_US.UTF-8"); -properties.setProperty("timezone", "UTC-8"); -System.out.println("get connection starting..."); + Properties properties = new Properties(); + properties.setProperty("charset", "UTF-8"); + 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(jdbcUrl, properties); - Statement stmt = connection.createStatement()) { + try (Connection connection = DriverManager.getConnection(jdbcUrl, properties); + Statement stmt = connection.createStatement()) { - // insert data, please make sure the database and table are created before - String insertQuery = "INSERT INTO " + - "power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " + - "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(3, 'California.SanFrancisco') " + - "VALUES " + - "(NOW + 1a, 10.30000, 218, 0.25000) "; - int affectedRows = stmt.executeUpdate(insertQuery); - // you can check affectedRows here - 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("Failed to insert data to power.meters, url:" + jdbcUrl + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + // insert data, please make sure the database and table are created before + String insertQuery = "INSERT INTO " + + "power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " + + "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(3, 'California.SanFrancisco') " + + "VALUES " + + "(NOW + 1a, 10.30000, 218, 0.25000) "; + int affectedRows = stmt.executeUpdate(insertQuery); + // you can check affectedRows here + 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("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 30a835bb11..a4749afed5 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,36 +15,36 @@ public class JdbcQueryDemo { public static void main(String[] args) throws SQLException { -final String jdbcUrl = "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(); -properties.setProperty("charset", "UTF-8"); -properties.setProperty("locale", "en_US.UTF-8"); -properties.setProperty("timezone", "UTC-8"); -System.out.println("get connection starting..."); + Properties properties = new Properties(); + properties.setProperty("charset", "UTF-8"); + 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(jdbcUrl, properties); - Statement stmt = connection.createStatement(); - // query data, make sure the database and table are created before - ResultSet resultSet = stmt.executeQuery("SELECT ts, current, location FROM power.meters limit 100")) { + 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 ts, current, location FROM power.meters limit 100")) { - Timestamp ts; - float current; - String location; - while (resultSet.next()) { - ts = resultSet.getTimestamp(1); - current = resultSet.getFloat(2); - // we recommend using the column name to get the value - location = resultSet.getString("location"); + Timestamp ts; + float current; + String location; + while (resultSet.next()) { + ts = resultSet.getTimestamp(1); + current = resultSet.getFloat(2); + // we recommend using the column name to get the value + location = resultSet.getString("location"); - // you can check data here - 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("Failed to query data from power.meters, url:" + jdbcUrl + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); -} + // you can check data here + 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("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 cc557c18c5..3705e0aac2 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,31 +15,31 @@ public class JdbcReqIdDemo { public static void main(String[] args) throws SQLException { -final String jdbcUrl = "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(); -properties.setProperty("charset", "UTF-8"); -properties.setProperty("locale", "en_US.UTF-8"); -properties.setProperty("timezone", "UTC-8"); -System.out.println("get connection starting..."); + Properties properties = new Properties(); + properties.setProperty("charset", "UTF-8"); + properties.setProperty("locale", "en_US.UTF-8"); + properties.setProperty("timezone", "UTC-8"); + System.out.println("get connection starting..."); // ANCHOR: with_reqid -try (Connection connection = DriverManager.getConnection(jdbcUrl, properties); - // Create a statement that allows specifying a request ID - AbstractStatement aStmt = (AbstractStatement) connection.createStatement()) { + try (Connection connection = DriverManager.getConnection(jdbcUrl, properties); + // Create a statement that allows specifying a request ID + AbstractStatement aStmt = (AbstractStatement) connection.createStatement()) { + + 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); + } + } + } catch (SQLException ex) { + // handle any errors, please refer to the JDBC specifications for detailed exceptions info + System.out.println("Failed to execute sql with reqId, url:" + jdbcUrl + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); - 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); } - } -} catch (SQLException ex) { - // handle any errors, please refer to the JDBC specifications for detailed exceptions info - 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/WsConsumerLoopFull.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WsConsumerLoopFull.java index d8084eb9f6..6caa42b1c1 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WsConsumerLoopFull.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WsConsumerLoopFull.java @@ -18,37 +18,38 @@ import java.util.concurrent.TimeUnit; 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); - } + 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()){ + try (TaosConsumer consumer = getConsumer()) { // subscribe to the topics List topics = Collections.singletonList("topic_meters"); @@ -75,178 +76,180 @@ try { public static void pollExample() throws SQLException { // ANCHOR: poll_data_code_piece -try (TaosConsumer consumer = getConsumer()){ - List topics = Collections.singletonList("topic_meters"); + 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)); + // 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); } - } - -} 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"); + 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)); - } + // 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; - } + 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); -} + // 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"); + 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)); + 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); } - 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(); -} + 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 { + 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; + // 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 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{ + 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++){ + for (int i = 0; i < 10000; i++) { insertQuery.append("(NOW + ").append(i).append("a, 10.30000, 219, 0.31000) "); } try { @@ -257,7 +260,8 @@ public static class ResultBean { throw new SQLException("Failed to insert data to power.meters", ex); } } - public static void prepareMeta() throws SQLException{ + + public static void prepareMeta() throws SQLException { try { statement.executeUpdate("CREATE DATABASE IF NOT EXISTS power"); statement.executeUpdate("USE power"); @@ -289,6 +293,7 @@ public static class ResultBean { } System.out.println("Connection created successfully."); } + public static void closeConnection() throws SQLException { try { if (statement != null) { @@ -338,16 +343,16 @@ public static class ResultBean { System.out.println("Data prepared successfully"); - // 关闭线程池,不再接收新任务 + // close the executor, which will make the executor reject new tasks executor.shutdown(); try { - // 等待直到所有任务完成 + // wait for the executor to terminate boolean result = executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); assert result; } catch (InterruptedException e) { Thread.currentThread().interrupt(); - } catch (Exception e){ + } catch (Exception e) { e.printStackTrace(); System.out.println("Wait executor termination failed."); } From d86043fde0a59739a6443a8fb308036c437a6f66 Mon Sep 17 00:00:00 2001 From: menshibin Date: Fri, 2 Aug 2024 15:14:08 +0800 Subject: [PATCH 06/15] nodejs example modify --- .../node/websocketexample/stmt_example.js | 60 +++++++----- .../node/websocketexample/tmq_example.js | 18 ++-- docs/examples/python/connect_example.py | 6 +- .../connect_rest_with_req_id_examples.py | 9 +- .../python/connect_websocket_examples.py | 9 +- docs/examples/python/create_db_native.py | 47 ++++++---- docs/examples/python/create_db_rest.py | 36 +++++--- docs/examples/python/create_db_ws.py | 42 ++++++--- docs/examples/python/insert_native.py | 92 +++++-------------- docs/examples/python/insert_rest.py | 64 +++++-------- docs/examples/python/insert_ws.py | 87 +++++------------- docs/zh/08-develop/01-connect/index.md | 2 +- docs/zh/08-develop/02-sql.md | 57 +++++++++++- docs/zh/08-develop/04-schemaless.md | 5 + docs/zh/08-develop/05-stmt.md | 6 +- docs/zh/08-develop/07-tmq.md | 3 + 16 files changed, 269 insertions(+), 274 deletions(-) diff --git a/docs/examples/node/websocketexample/stmt_example.js b/docs/examples/node/websocketexample/stmt_example.js index 842a8a4c3d..1b78e4bccd 100644 --- a/docs/examples/node/websocketexample/stmt_example.js +++ b/docs/examples/node/websocketexample/stmt_example.js @@ -2,13 +2,13 @@ const taos = require("@tdengine/websocket"); let db = 'power'; let stable = 'meters'; -let tags = ['California.SanFrancisco', 3]; -let values = [ - [1706786044994, 1706786044995, 1706786044996], - [10.2, 10.3, 10.4], - [292, 293, 294], - [0.32, 0.33, 0.34], -]; +let numOfSubTable = 10; +let numOfRow = 10; +function getRandomInt(min, max) { + min = Math.ceil(min); + max = Math.floor(max); + return Math.floor(Math.random() * (max - min + 1)) + min; +} async function prepare() { let dsn = 'ws://localhost:6041' @@ -29,24 +29,36 @@ async function prepare() { connector = await prepare(); stmt = await connector.stmtInit(); await stmt.prepare(`INSERT INTO ? USING ${db}.${stable} (location, groupId) TAGS (?, ?) VALUES (?, ?, ?, ?)`); - await stmt.setTableName('d1001'); - let tagParams = stmt.newStmtParam(); - tagParams.setVarchar([tags[0]]); - tagParams.setInt([tags[1]]); - await stmt.setTags(tagParams); - - let bindParams = stmt.newStmtParam(); - bindParams.setTimestamp(values[0]); - bindParams.setFloat(values[1]); - bindParams.setInt(values[2]); - bindParams.setFloat(values[3]); - await stmt.bind(bindParams); - await stmt.batch(); - await stmt.exec(); - console.log(stmt.getLastAffected()); + for (let i = 0; i < numOfSubTable; i++) { + await stmt.setTableName(`d_bind_${i}`); + let tagParams = stmt.newStmtParam(); + tagParams.setVarchar([`location_${i}`]); + tagParams.setInt([i]); + await stmt.setTags(tagParams); + let timestampParams = []; + let currentParams = []; + let voltageParams = []; + let phaseParams = []; + const currentMillis = new Date().getTime(); + for (let j = 0; j < numOfRow; j++) { + timestampParams.push(currentMillis + j); + currentParams.push(Math.random() * 30); + voltageParams.push(getRandomInt(100, 300)); + phaseParams.push(Math.random()); + } + let bindParams = stmt.newStmtParam(); + bindParams.setTimestamp(timestampParams); + bindParams.setFloat(currentParams); + bindParams.setInt(voltageParams); + bindParams.setFloat(phaseParams); + await stmt.bind(bindParams); + await stmt.batch(); + await stmt.exec(); + console.log(`d_bind_${i} insert ` + stmt.getLastAffected() + " rows."); + } } - catch (err) { - console.error(err.code, err.message); + catch (e) { + console.error(e); } finally { if (stmt) { diff --git a/docs/examples/node/websocketexample/tmq_example.js b/docs/examples/node/websocketexample/tmq_example.js index 9b77abe4d0..b7a8d13809 100644 --- a/docs/examples/node/websocketexample/tmq_example.js +++ b/docs/examples/node/websocketexample/tmq_example.js @@ -7,24 +7,30 @@ const topics = ['power_meters_topic']; // ANCHOR: create_consumer async function createConsumer() { let configMap = new Map([ - [taos.TMQConstants.GROUP_ID, "gId"], + [taos.TMQConstants.GROUP_ID, "group1"], + [taos.TMQConstants.CLIENT_ID, 'client1'], [taos.TMQConstants.CONNECT_USER, "root"], [taos.TMQConstants.CONNECT_PASS, "taosdata"], [taos.TMQConstants.AUTO_OFFSET_RESET, "latest"], - [taos.TMQConstants.CLIENT_ID, 'test_tmq_client'], [taos.TMQConstants.WS_URL, 'ws://localhost:6041'], [taos.TMQConstants.ENABLE_AUTO_COMMIT, 'true'], [taos.TMQConstants.AUTO_COMMIT_INTERVAL_MS, '1000'] ]); - return await taos.tmqConnect(configMap); + try { + return await taos.tmqConnect(configMap); + }catch (err) { + console.log(err); + throw err; + } + } // ANCHOR_END: create_consumer async function prepare() { let conf = new taos.WSConfig('ws://localhost:6041'); - conf.setUser('root') - conf.setPwd('taosdata') - conf.setDb('power') + conf.setUser('root'); + conf.setPwd('taosdata'); + conf.setDb('power'); const createDB = `CREATE DATABASE IF NOT EXISTS POWER ${db} KEEP 3650 DURATION 10 BUFFER 16 WAL_LEVEL 1;`; const createStable = `CREATE STABLE IF NOT EXISTS ${db}.${stable} (ts timestamp, current float, voltage int, phase float) TAGS (location binary(64), groupId int);`; diff --git a/docs/examples/python/connect_example.py b/docs/examples/python/connect_example.py index 493cd512ee..744f2aa49e 100644 --- a/docs/examples/python/connect_example.py +++ b/docs/examples/python/connect_example.py @@ -4,14 +4,14 @@ def create_connection(): # all parameters are optional. conn = None try: - conn = taosws.connect( + conn = taos.connect( user="root", password="taosdata", - host="192.168.1.98", + host="localhost", port=6041, ) except Exception as err: - print(f'Exception {err}') + print(err) finally: if conn: conn.close() diff --git a/docs/examples/python/connect_rest_with_req_id_examples.py b/docs/examples/python/connect_rest_with_req_id_examples.py index 568cbea168..7d90bef158 100644 --- a/docs/examples/python/connect_rest_with_req_id_examples.py +++ b/docs/examples/python/connect_rest_with_req_id_examples.py @@ -1,11 +1,12 @@ # ANCHOR: connect from taosrest import connect, TaosRestConnection, TaosRestCursor -conn = connect(url="http://localhost:6041", - user="root", - password="taosdata", - timeout=30) +conn = connect(url="http://localhost:6041", + user="root", + password="taosdata", + timeout=30) + # ANCHOR_END: connect # ANCHOR: basic # create STable diff --git a/docs/examples/python/connect_websocket_examples.py b/docs/examples/python/connect_websocket_examples.py index 69c3900187..3d93634bcc 100644 --- a/docs/examples/python/connect_websocket_examples.py +++ b/docs/examples/python/connect_websocket_examples.py @@ -1,19 +1,20 @@ +# ANCHOR: connect import taosws def create_connection(): conn = None -# ANCHOR: connect try: conn = taosws.connect( user="root", password="taosdata", - host="192.168.1.98", + host="localhost", port=6041, ) except Exception as err: - print(f'Exception {err}') -# ANCHOR_END: connect + print(err) + return conn + # ANCHOR_END: connect def create_db_table(conn): # ANCHOR: create_db diff --git a/docs/examples/python/create_db_native.py b/docs/examples/python/create_db_native.py index 6eeb94b879..3404363dc3 100644 --- a/docs/examples/python/create_db_native.py +++ b/docs/examples/python/create_db_native.py @@ -1,26 +1,33 @@ import taos -conn = taos.connect( - host="localhost", - user="root", - password="taosdata", - port=6030, -) +conn = None +try: + conn = taos.connect(host="localhost", + user="root", + password="taosdata", + port=6030) -db = "power" + db = "power" + # create database + rowsAffected = conn.execute(f"CREATE DATABASE IF NOT EXISTS {db}") + assert rowsAffected == 0 -conn.execute(f"DROP DATABASE IF EXISTS {db}") -conn.execute(f"CREATE DATABASE {db}") + # change database. same as execute "USE db" + rowsAffected = conn.select_db(db) + assert rowsAffected == 0 + + # create super table + rowsAffected = conn.execute( + "CREATE TABLE IF NOT EXISTS `meters` (`ts` TIMESTAMP, `current` FLOAT, `voltage` INT, `phase` FLOAT) TAGS (`groupid` INT, `location` BINARY(16))" + ) + assert rowsAffected == 0 -# change database. same as execute "USE db" -conn.select_db(db) + # create table + rowsAffected = conn.execute("CREATE TABLE IF NOT EXISTS `d0` USING `meters` (groupid, location) TAGS(0, 'Los Angles')") + assert rowsAffected == 0 -# create super table -conn.execute( - "CREATE TABLE `meters` (`ts` TIMESTAMP, `current` FLOAT, `voltage` INT, `phase` FLOAT) TAGS (`groupid` INT, `location` BINARY(16))" -) - -# create table -conn.execute("CREATE TABLE `d0` USING `meters` TAGS(0, 'Los Angles')") - -conn.close() +except Exception as err: + print(err) +finally: + if conn: + conn.close() diff --git a/docs/examples/python/create_db_rest.py b/docs/examples/python/create_db_rest.py index fc262b30f8..818fa748ad 100644 --- a/docs/examples/python/create_db_rest.py +++ b/docs/examples/python/create_db_rest.py @@ -1,18 +1,28 @@ import taosrest -conn = taosrest.connect(url="http://localhost:6041") +conn = None +try: + conn = taosrest.connect(url="http://localhost:6041", + user="root", + password="taosdata", + timeout=30) -db = "power" + db = "power" + # create database + rowsAffected = conn.execute(f"CREATE DATABASE IF NOT EXISTS {db}") + assert rowsAffected == 0 -conn.execute(f"DROP DATABASE IF EXISTS {db}") -conn.execute(f"CREATE DATABASE {db}") + # create super table + rowsAffected = conn.execute( + f"CREATE TABLE IF NOT EXISTS `{db}`.`meters` (`ts` TIMESTAMP, `current` FLOAT, `voltage` INT, `phase` FLOAT) TAGS (`groupid` INT, `location` BINARY(16))" + ) + assert rowsAffected == 0 + # create table + rowsAffected = conn.execute(f"CREATE TABLE IF NOT EXISTS `{db}`.`d0` USING `{db}`.`meters` (groupid, location) TAGS(0, 'Los Angles')") + assert rowsAffected == 0 -# create super table -conn.execute( - f"CREATE TABLE `{db}`.`meters` (`ts` TIMESTAMP, `current` FLOAT, `voltage` INT, `phase` FLOAT) TAGS (`groupid` INT, `location` BINARY(16))" -) - -# create table -conn.execute(f"CREATE TABLE `{db}`.`d0` USING `{db}`.`meters` TAGS(0, 'Los Angles')") - -conn.close() +except Exception as err: + print(err) +finally: + if conn: + conn.close() diff --git a/docs/examples/python/create_db_ws.py b/docs/examples/python/create_db_ws.py index 844f7a56e3..8c43af8db2 100644 --- a/docs/examples/python/create_db_ws.py +++ b/docs/examples/python/create_db_ws.py @@ -1,22 +1,34 @@ import taosws -dsn = "taosws://root:taosdata@localhost:6041" -conn = taosws.connect(dsn) +conn = None -db = "power" +try: + conn = taosws.connect(user="root", + password="taosdata", + host="localhost", + port=6041) -conn.execute(f"DROP DATABASE IF EXISTS {db}") -conn.execute(f"CREATE DATABASE {db}") + db = "power" + # create database + rowsAffected = conn.execute(f"CREATE DATABASE IF NOT EXISTS {db}") + assert rowsAffected == 0 -# change database. -conn.execute(f"USE {db}") + # change database. + rowsAffected = conn.execute(f"USE {db}") + assert rowsAffected == 0 + + # create super table + rowsAffected = conn.execute( + "CREATE TABLE IF NOT EXISTS `meters` (`ts` TIMESTAMP, `current` FLOAT, `voltage` INT, `phase` FLOAT) TAGS (`groupid` INT, `location` BINARY(16))" + ) + assert rowsAffected == 0 -# create super table -conn.execute( - "CREATE TABLE `meters` (`ts` TIMESTAMP, `current` FLOAT, `voltage` INT, `phase` FLOAT) TAGS (`groupid` INT, `location` BINARY(16))" -) + # create table + rowsAffected = conn.execute("CREATE TABLE IF NOT EXISTS `d0` USING `meters` (groupid, location) TAGS(0, 'Los Angles')") + assert rowsAffected == 0 -# create table -conn.execute("CREATE TABLE `d0` USING `meters` TAGS(0, 'Los Angles')") - -conn.close() +except Exception as err: + print(err) +finally: + if conn: + conn.close() diff --git a/docs/examples/python/insert_native.py b/docs/examples/python/insert_native.py index 37bbb807ec..faf4554437 100644 --- a/docs/examples/python/insert_native.py +++ b/docs/examples/python/insert_native.py @@ -1,76 +1,26 @@ import taos -conn = taos.connect( - host="localhost", - user="root", - password="taosdata", - port=6030, -) +conn = None -db = "power" +try: + conn = taos.connect(user="root", + password="taosdata", + host="localhost", + port=6041) -conn.execute(f"DROP DATABASE IF EXISTS {db}") -conn.execute(f"CREATE DATABASE {db}") + sql = """ + INSERT INTO + power.d1001 USING power.meters (groupid, location) TAGS(2, 'California.SanFrancisco') + 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 (groupid, location) TAGS(3, 'California.SanFrancisco') + VALUES (NOW + 1a, 10.30000, 218, 0.25000) + """ + inserted = conn.execute(sql) + print("inserted into {affectedRows} rows to power.meters successfully.") -# change database. same as execute "USE db" -conn.select_db(db) - -# create super table -conn.execute( - "CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)" -) - -# ANCHOR: insert -# insert data -sql = """ -INSERT INTO -power.d1001 USING power.meters TAGS('California.SanFrancisco', 2) - VALUES ('2018-10-03 14:38:05.000', 10.30000, 219, 0.31000) - ('2018-10-03 14:38:15.000', 12.60000, 218, 0.33000) ('2018-10-03 14:38:16.800', 12.30000, 221, 0.31000) -power.d1002 USING power.meters TAGS('California.SanFrancisco', 3) - VALUES ('2018-10-03 14:38:16.650', 10.30000, 218, 0.25000) -power.d1003 USING power.meters TAGS('California.LosAngeles', 2) - VALUES ('2018-10-03 14:38:05.500', 11.80000, 221, 0.28000) ('2018-10-03 14:38:16.600', 13.40000, 223, 0.29000) -power.d1004 USING power.meters TAGS('California.LosAngeles', 3) - VALUES ('2018-10-03 14:38:05.000', 10.80000, 223, 0.29000) ('2018-10-03 14:38:06.500', 11.50000, 221, 0.35000) -""" - -inserted = conn.execute(sql) -assert inserted == 8 -# ANCHOR_END: insert - -# ANCHOR: query -# Execute a sql and get its result set. It's useful for SELECT statement -result = conn.query("SELECT * from meters") - -# Get fields from result -fields = result.fields -for field in fields: - print(field) - -""" -output: -{name: ts, type: 9, bytes: 8} -{name: current, type: 6, bytes: 4} -{name: voltage, type: 4, bytes: 4} -{name: phase, type: 6, bytes: 4} -{name: location, type: 8, bytes: 64} -{name: groupid, type: 4, bytes: 4} -""" - -# Get data from result as list of tuple -data = result.fetch_all() -for row in data: - print(row) - -""" -output: -(datetime.datetime(2018, 10, 3, 14, 38, 16, 650000), 10.300000190734863, 218, 0.25, 'California.SanFrancisco', 3) -... -""" -# ANCHOR_END: query - -# ANCHOR: req_id -result = conn.query("SELECT * from meters", req_id=1) -# ANCHOR_END: req_id -conn.close() +except Exception as err: + print(err) +finally: + if conn: + conn.close() diff --git a/docs/examples/python/insert_rest.py b/docs/examples/python/insert_rest.py index 16b8fe669c..c43a6a6d17 100644 --- a/docs/examples/python/insert_rest.py +++ b/docs/examples/python/insert_rest.py @@ -1,48 +1,26 @@ import taosrest -conn = taosrest.connect(url="http://localhost:6041") +conn = None -db = "power" +try: + conn = taosrest.connect(url="http://localhost:6041", + user="root", + password="taosdata", + timeout=30) -conn.execute(f"DROP DATABASE IF EXISTS {db}") -conn.execute(f"CREATE DATABASE {db}") + sql = """ + INSERT INTO + power.d1001 USING power.meters (groupid, location) TAGS(2, 'California.SanFrancisco') + 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 (groupid, location) TAGS(3, 'California.SanFrancisco') + VALUES (NOW + 1a, 10.30000, 218, 0.25000) + """ + affectedRows = conn.execute(sql) + print(f"inserted into {affectedRows} rows to power.meters successfully.") -# create super table -conn.execute( - "CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)" -) - -# ANCHOR: insert -# rest insert data -sql = """ -INSERT INTO -power.d1001 USING power.meters TAGS('California.SanFrancisco', 2) - VALUES ('2018-10-03 14:38:05.000', 10.30000, 219, 0.31000) - ('2018-10-03 14:38:15.000', 12.60000, 218, 0.33000) ('2018-10-03 14:38:16.800', 12.30000, 221, 0.31000) -power.d1002 USING power.meters TAGS('California.SanFrancisco', 3) - VALUES ('2018-10-03 14:38:16.650', 10.30000, 218, 0.25000) -power.d1003 USING power.meters TAGS('California.LosAngeles', 2) - VALUES ('2018-10-03 14:38:05.500', 11.80000, 221, 0.28000) ('2018-10-03 14:38:16.600', 13.40000, 223, 0.29000) -power.d1004 USING power.meters TAGS('California.LosAngeles', 3) - VALUES ('2018-10-03 14:38:05.000', 10.80000, 223, 0.29000) ('2018-10-03 14:38:06.500', 11.50000, 221, 0.35000) -""" - -inserted = conn.execute(sql) -assert inserted == 8 -# ANCHOR_END: insert - -# ANCHOR: query -client = taosrest.RestClient("http://localhost:6041") -result = client.sql(f"SELECT * from {db}.meters") -print(result) - -""" -output: -{'code': 0, 'column_meta': [['ts', 'TIMESTAMP', 8], ['current', 'FLOAT', 4], ['voltage', 'INT', 4], ['phase', 'FLOAT', 4], ['location', 'VARCHAR', 64], ['groupid', 'INT', 4]], 'data': [[datetime.datetime(2018, 10, 3, 14, 38, 5), 10.3, 219, 0.31, 'California.SanFrancisco', 2], [datetime.datetime(2018, 10, 3, 14, 38, 15), 12.6, 218, 0.33, 'California.SanFrancisco', 2], [datetime.datetime(2018, 10, 3, 14, 38, 16, 800000), 12.3, 221, 0.31, 'California.SanFrancisco', 2], [datetime.datetime(2018, 10, 3, 14, 38, 16, 650000), 10.3, 218, 0.25, 'California.SanFrancisco', 3], [datetime.datetime(2018, 10, 3, 14, 38, 5, 500000), 11.8, 221, 0.28, 'California.LosAngeles', 2], [datetime.datetime(2018, 10, 3, 14, 38, 16, 600000), 13.4, 223, 0.29, 'California.LosAngeles', 2], [datetime.datetime(2018, 10, 3, 14, 38, 5), 10.8, 223, 0.29, 'California.LosAngeles', 3], [datetime.datetime(2018, 10, 3, 14, 38, 6, 500000), 11.5, 221, 0.35, 'California.LosAngeles', 3]], 'rows': 8} -""" -# ANCHOR_END: query - -# ANCHOR: req_id -result = client.sql(f"SELECT * from {db}.meters", req_id=1) -# ANCHOR_END: req_id -conn.close() +except Exception as err: + print(err) +finally: + if conn: + conn.close() diff --git a/docs/examples/python/insert_ws.py b/docs/examples/python/insert_ws.py index ef3ae3ea99..1d7aa7fc5d 100644 --- a/docs/examples/python/insert_ws.py +++ b/docs/examples/python/insert_ws.py @@ -1,71 +1,26 @@ import taosws -dsn = "taosws://root:taosdata@localhost:6041" -conn = taosws.connect(dsn) +conn = None -db = "power" +try: + conn = taosws.connect(user="root", + password="taosdata", + host="localhost", + port=6041) -conn.execute(f"DROP DATABASE IF EXISTS {db}") -conn.execute(f"CREATE DATABASE {db}") + sql = """ + INSERT INTO + power.d1001 USING power.meters (groupid, location) TAGS(2, 'California.SanFrancisco') + 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 (groupid, location) TAGS(3, 'California.SanFrancisco') + VALUES (NOW + 1a, 10.30000, 218, 0.25000) + """ + inserted = conn.execute(sql) + print("inserted into {affectedRows} rows to power.meters successfully.") -# change database. -conn.execute(f"USE {db}") - -# create super table -conn.execute( - "CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)" -) - -# ANCHOR: insert -# ws insert data -sql = """ -INSERT INTO -power.d1001 USING power.meters TAGS('California.SanFrancisco', 2) - VALUES ('2018-10-03 14:38:05.000', 10.30000, 219, 0.31000) - ('2018-10-03 14:38:15.000', 12.60000, 218, 0.33000) ('2018-10-03 14:38:16.800', 12.30000, 221, 0.31000) -power.d1002 USING power.meters TAGS('California.SanFrancisco', 3) - VALUES ('2018-10-03 14:38:16.650', 10.30000, 218, 0.25000) -power.d1003 USING power.meters TAGS('California.LosAngeles', 2) - VALUES ('2018-10-03 14:38:05.500', 11.80000, 221, 0.28000) ('2018-10-03 14:38:16.600', 13.40000, 223, 0.29000) -power.d1004 USING power.meters TAGS('California.LosAngeles', 3) - VALUES ('2018-10-03 14:38:05.000', 10.80000, 223, 0.29000) ('2018-10-03 14:38:06.500', 11.50000, 221, 0.35000) -""" - -inserted = conn.execute(sql) -assert inserted == 8 -# ANCHOR_END: insert - -# ANCHOR: query -# Execute a sql and get its result set. It's useful for SELECT statement -result = conn.query("SELECT * from meters") - -# Get fields from result -fields = result.fields -for field in fields: - print(field) - -""" -output: -{name: ts, type: TIMESTAMP, bytes: 8} -{name: current, type: FLOAT, bytes: 4} -{name: voltage, type: INT, bytes: 4} -{name: phase, type: FLOAT, bytes: 4} -{name: location, type: BINARY, bytes: 64} -{name: groupid, type: INT, bytes: 4} -""" - -# Get rows from result -for row in result: - print(row) - -""" -output: -('2018-10-03 14:38:05 +08:00', 10.300000190734863, 219, 0.3100000023841858, 'California.SanFrancisco', 2) -... -""" -# ANCHOR_END: query - -# ANCHOR: req_id -result = conn.query_with_req_id("SELECT * from meters", req_id=1) -# ANCHOR_END: req_id -conn.close() +except Exception as err: + print(err) +finally: + if conn: + conn.close() diff --git a/docs/zh/08-develop/01-connect/index.md b/docs/zh/08-develop/01-connect/index.md index ac2787a4cc..43b9e91b15 100644 --- a/docs/zh/08-develop/01-connect/index.md +++ b/docs/zh/08-develop/01-connect/index.md @@ -424,7 +424,7 @@ URL 和 Properties 的详细参数说明和如何使用详见 [API 说明](../.. ```python -{{#include docs/examples/python/connect_rest_examples.py:connect}} +{{#include docs/examples/python/connect_rest_example.py:connect}} ``` diff --git a/docs/zh/08-develop/02-sql.md b/docs/zh/08-develop/02-sql.md index 7b4c6e5d98..fa9285d55c 100644 --- a/docs/zh/08-develop/02-sql.md +++ b/docs/zh/08-develop/02-sql.md @@ -25,13 +25,28 @@ TDengine 对 SQL 语言提供了全面的支持,允许用户以熟悉的 SQL -- Websocket 连接 +```python title="Websocket 连接" +{{#include docs/examples/python/create_db_ws.py}} +``` + +```python title="原生连接" +{{#include docs/examples/python/create_db_native.py}} +``` + +```python title="Rest 连接" +{{#include docs/examples/python/create_db_rest.py}} +``` + +```js +{{#include docs/examples/node/websocketexample/sql_example.js:create_db_and_table}} +``` + @@ -57,11 +72,29 @@ NOW 为系统内部函数,默认为客户端所在计算机当前时间。 NOW + +```python title="Websocket 连接" +{{#include docs/examples/python/insert_ws.py}} +``` + +```python title="原生连接" +{{#include docs/examples/python/insert_native.py}} +``` + +```python title="Rest 连接" +{{#include docs/examples/python/insert_rest.py}} +``` + + +```js +{{#include docs/examples/node/websocketexample/sql_example.js:insertData}} +``` + @@ -86,11 +119,28 @@ NOW 为系统内部函数,默认为客户端所在计算机当前时间。 NOW + +```python title="Websocket 连接" +{{#include docs/examples/python/query_ws.py}} +``` + +```python title="原生连接" +{{#include docs/examples/python/query_native.py}} +``` + +```python title="Rest 连接" +{{#include docs/examples/python/query_rest.py}} +``` + +```js +{{#include docs/examples/node/websocketexample/sql_example.js:queryData}} +``` + @@ -128,6 +178,11 @@ reqId 可用于请求链路追踪,reqId 就像分布式系统中的 traceId + +```js +{{#include docs/examples/node/websocketexample/sql_example.js:sqlWithReqid}} +``` + diff --git a/docs/zh/08-develop/04-schemaless.md b/docs/zh/08-develop/04-schemaless.md index 734e9558a2..7c7cb34187 100644 --- a/docs/zh/08-develop/04-schemaless.md +++ b/docs/zh/08-develop/04-schemaless.md @@ -182,6 +182,11 @@ writer.write(lineDemo, SchemalessProtocolType.LINE, SchemalessTimestampType.NANO + +```js +{{#include docs/examples/node/websocketexample/line_example.js}} +``` + diff --git a/docs/zh/08-develop/05-stmt.md b/docs/zh/08-develop/05-stmt.md index 132a1b8850..6e6ae050b1 100644 --- a/docs/zh/08-develop/05-stmt.md +++ b/docs/zh/08-develop/05-stmt.md @@ -46,9 +46,9 @@ import TabItem from "@theme/TabItem"; - ```js - {{#include docs/examples/node/websocketexample/sql_example.js:createConnect}} - ``` +```js + {{#include docs/examples/node/websocketexample/stmt_example.js:createConnect}} +``` diff --git a/docs/zh/08-develop/07-tmq.md b/docs/zh/08-develop/07-tmq.md index 16a538757f..cb01bc28e0 100644 --- a/docs/zh/08-develop/07-tmq.md +++ b/docs/zh/08-develop/07-tmq.md @@ -106,6 +106,9 @@ Java 连接器创建消费者的参数为 Properties, 可以设置的参数列 +```js + {{#include docs/examples/node/websocketexample/tmq_example.js:create_consumer}} +``` From 870d285f2bb265a1208a3905582b84951a61d201 Mon Sep 17 00:00:00 2001 From: t_max <1172915550@qq.com> Date: Fri, 2 Aug 2024 15:28:32 +0800 Subject: [PATCH 07/15] docs: fix go example anchor --- docs/zh/08-develop/01-connect/index.md | 10 +++++----- docs/zh/08-develop/02-sql.md | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/zh/08-develop/01-connect/index.md b/docs/zh/08-develop/01-connect/index.md index 89c3dd7f69..5a0732f92b 100644 --- a/docs/zh/08-develop/01-connect/index.md +++ b/docs/zh/08-develop/01-connect/index.md @@ -540,15 +540,15 @@ DSN 的详细说明和如何使用详见 [连接功能](../../reference/connecto ``` - ```go - {{#include docs/examples/go/connect/restexample/main.go}} - ``` +```go +{{#include docs/examples/go/connect/restexample/main.go}} +``` -不支持 + 不支持 - C# 只支持 WebSocket 连接与原生连接 + 不支持 diff --git a/docs/zh/08-develop/02-sql.md b/docs/zh/08-develop/02-sql.md index 5476154158..2bc428bebf 100644 --- a/docs/zh/08-develop/02-sql.md +++ b/docs/zh/08-develop/02-sql.md @@ -38,7 +38,7 @@ REST API:通过 `curl` 命令进行数据写入和查询操作。 ```go -{{#include docs/examples/go/queryreqid/main.go:query_id}} +{{#include docs/examples/go/sqlquery/main.go:create_db_and_table}} ``` @@ -101,7 +101,7 @@ NOW 为系统内部函数,默认为客户端所在计算机当前时间。 NOW ```go -{{#include docs/examples/go/sqlquery/main.go:create_db_and_table}} +{{#include docs/examples/go/sqlquery/main.go:insert_data}} ``` @@ -157,7 +157,7 @@ curl --location -uroot:taosdata 'http://127.0.0.1:6041/rest/sql' \ ```go -{{#include docs/examples/go/sqlquery/main.go:insert_data}} +{{#include docs/examples/go/sqlquery/main.go:select_data}} ``` @@ -218,7 +218,7 @@ reqId 可用于请求链路追踪,reqId 就像分布式系统中的 traceId ```go -{{#include docs/examples/go/sqlquery/main.go:select_data}} +{{#include docs/examples/go/queryreqid/main.go:query_id}} ``` From 6693b2cc58af66fe67cf2aa9931e98d8b6754a74 Mon Sep 17 00:00:00 2001 From: menshibin Date: Fri, 2 Aug 2024 16:20:50 +0800 Subject: [PATCH 08/15] add node.js example --- .../node/websocketexample/tmq_example.js | 46 ++++---- .../node/websocketexample/tmq_seek_example.js | 104 ++++++++++++++++++ docs/examples/python/connect_rest_example.py | 20 ++++ docs/examples/python/query_native.py | 26 +++++ docs/examples/python/query_rest.py | 15 +++ docs/examples/python/query_ws.py | 22 ++++ docs/zh/08-develop/07-tmq.md | 15 +++ 7 files changed, 222 insertions(+), 26 deletions(-) create mode 100644 docs/examples/node/websocketexample/tmq_seek_example.js create mode 100644 docs/examples/python/connect_rest_example.py create mode 100644 docs/examples/python/query_native.py create mode 100644 docs/examples/python/query_rest.py create mode 100644 docs/examples/python/query_ws.py diff --git a/docs/examples/node/websocketexample/tmq_example.js b/docs/examples/node/websocketexample/tmq_example.js index b7a8d13809..12c303acf4 100644 --- a/docs/examples/node/websocketexample/tmq_example.js +++ b/docs/examples/node/websocketexample/tmq_example.js @@ -38,10 +38,9 @@ async function prepare() { await wsSql.exec(createDB); await wsSql.exec(createStable); -// ANCHOR: create_topic -let createTopic = `CREATE TOPIC IF NOT EXISTS ${topics[0]} AS SELECT * FROM ${db}.${stable}`; -await wsSql.exec(createTopic); -// ANCHOR_END: create_topic + let createTopic = `CREATE TOPIC IF NOT EXISTS ${topics[0]} AS SELECT * FROM ${db}.${stable}`; + await wsSql.exec(createTopic); + for (let i = 0; i < 10; i++) { await wsSql.exec(`INSERT INTO d1001 USING ${stable} (location, groupId) TAGS ("California.SanFrancisco", 3) VALUES (NOW, ${10 + i}, ${200 + i}, ${0.32 + i})`); @@ -49,37 +48,31 @@ await wsSql.exec(createTopic); wsSql.Close(); } -// ANCHOR: subscribe async function subscribe(consumer) { - await consumer.subscribe(topics); - for (let i = 0; i < 5; i++) { - let res = await consumer.poll(500); - for (let [key, value] of res) { - console.log(key, value); - } - if (res.size == 0) { - break; - } - await consumer.commit(); + // ANCHOR: commit + try { + await consumer.subscribe(['topic_meters']); + for (let i = 0; i < 50; i++) { + let res = await consumer.poll(100); + for (let [key, value] of res) { + console.log(key, value); + } + consumer.commit(); + } + } catch (err) { + console.error(err.code, err.message); + throw err; } + // ANCHOR_END: commit } -// ANCHOR_END: subscribe async function test() { + // ANCHOR: unsubscribe let consumer = null; try { await prepare(); let consumer = await createConsumer() - await subscribe(consumer) - // ANCHOR: assignment - let assignment = await consumer.assignment(); - console.log(assignment); - - assignment = await consumer.seekToBeginning(assignment); - for(let i in assignment) { - console.log("seek after:", assignment[i]) - } - // ANCHOR_END: assignment + await subscribe(consumer) await consumer.unsubscribe(); } catch (err) { @@ -91,6 +84,7 @@ async function test() { } taos.destroy(); } + // ANCHOR_END: unsubscribe } test() diff --git a/docs/examples/node/websocketexample/tmq_seek_example.js b/docs/examples/node/websocketexample/tmq_seek_example.js new file mode 100644 index 0000000000..17242dc870 --- /dev/null +++ b/docs/examples/node/websocketexample/tmq_seek_example.js @@ -0,0 +1,104 @@ +const taos = require("@tdengine/websocket"); + +const db = 'power'; +const stable = 'meters'; +const topics = ['power_meters_topic']; + +// ANCHOR: create_consumer +async function createConsumer() { + let configMap = new Map([ + [taos.TMQConstants.GROUP_ID, "group1"], + [taos.TMQConstants.CLIENT_ID, 'client1'], + [taos.TMQConstants.CONNECT_USER, "root"], + [taos.TMQConstants.CONNECT_PASS, "taosdata"], + [taos.TMQConstants.AUTO_OFFSET_RESET, "latest"], + [taos.TMQConstants.WS_URL, 'ws://localhost:6041'], + [taos.TMQConstants.ENABLE_AUTO_COMMIT, 'true'], + [taos.TMQConstants.AUTO_COMMIT_INTERVAL_MS, '1000'] + ]); + try { + return await taos.tmqConnect(configMap); + }catch (err) { + console.log(err); + throw err; + } + +} +// ANCHOR_END: create_consumer + +async function prepare() { + let conf = new taos.WSConfig('ws://localhost:6041'); + conf.setUser('root'); + conf.setPwd('taosdata'); + conf.setDb('power'); + const createDB = `CREATE DATABASE IF NOT EXISTS POWER ${db} KEEP 3650 DURATION 10 BUFFER 16 WAL_LEVEL 1;`; + const createStable = `CREATE STABLE IF NOT EXISTS ${db}.${stable} (ts timestamp, current float, voltage int, phase float) TAGS (location binary(64), groupId int);`; + + let wsSql = await taos.sqlConnect(conf); + await wsSql.exec(createDB); + await wsSql.exec(createStable); + + let createTopic = `CREATE TOPIC IF NOT EXISTS ${topics[0]} AS SELECT * FROM ${db}.${stable}`; + await wsSql.exec(createTopic); + + + for (let i = 0; i < 10; i++) { + await wsSql.exec(`INSERT INTO d1001 USING ${stable} (location, groupId) TAGS ("California.SanFrancisco", 3) VALUES (NOW, ${10 + i}, ${200 + i}, ${0.32 + i})`); + } + wsSql.Close(); +} + +// ANCHOR: subscribe +async function subscribe(consumer) { + try { + await consumer.subscribe(['topic_meters']); + for (let i = 0; i < 50; i++) { + let res = await consumer.poll(100); + for (let [key, value] of res) { + console.log(key, value); + } + } + }catch (err) { + console.error(err.code, err.message); + throw err; + } + +} +// ANCHOR_END: subscribe + +// ANCHOR: offset +async function test() { + let consumer = null; + try { + await prepare(); + let consumer = await createConsumer() + await consumer.subscribe(['topic_meters']); + let res = new Map(); + while (res.size == 0) { + res = await consumer.poll(100); + } + + let assignment = await consumer.assignment(); + for (let i in assignment) { + console.log("seek before:", assignment[i]); + } + + await consumer.seekToBeginning(assignment); + assignment = await consumer.assignment(); + for (let i in assignment) { + console.log("seek after:", assignment[i]); + } + await consumer.unsubscribe(); + } + catch (err) { + console.error(err.code, err.message); + } + finally { + if (consumer) { + await consumer.close(); + } + taos.destroy(); + } +} +// ANCHOR_END: offset +test() diff --git a/docs/examples/python/connect_rest_example.py b/docs/examples/python/connect_rest_example.py new file mode 100644 index 0000000000..c2b8f38431 --- /dev/null +++ b/docs/examples/python/connect_rest_example.py @@ -0,0 +1,20 @@ +# ANCHOR: connect +import taosrest + +def create_connection(): + conn = None + try: + conn = taosrest.connect(url="http://localhost:6041", + user="root", + password="taosdata", + timeout=30) + except Exception as err: + print(err) + finally: + if conn: + conn.close() +# ANCHOR_END: connect + +if __name__ == "__main__": + create_connection() + diff --git a/docs/examples/python/query_native.py b/docs/examples/python/query_native.py new file mode 100644 index 0000000000..6e361405e3 --- /dev/null +++ b/docs/examples/python/query_native.py @@ -0,0 +1,26 @@ +import taos + +conn = None +try: + conn = taos.connect(host="localhost", + port=6030, + user="root", + password="taosdata") + + result = conn.query("SELECT ts, current, location FROM power.meters limit 100") + print(result) + # Get fields from result + fields = result.fields + for field in fields: + print(field) + + # Get data from result as list of tuple + data = result.fetch_all() + for row in data: + print(row) + +except Exception as err: + print(err) +finally: + if conn: + conn.close() \ No newline at end of file diff --git a/docs/examples/python/query_rest.py b/docs/examples/python/query_rest.py new file mode 100644 index 0000000000..fc31e9db33 --- /dev/null +++ b/docs/examples/python/query_rest.py @@ -0,0 +1,15 @@ +import taosrest + +client = None + +try: + client = taosrest.RestClient(url="http://localhost:6041", + user="root", + password="taosdata", + timeout=30) + + result = client.sql(f"SELECT ts, current, location FROM power.meters limit 100") + print(result) + +except Exception as err: + print(err) diff --git a/docs/examples/python/query_ws.py b/docs/examples/python/query_ws.py new file mode 100644 index 0000000000..ee0d40167b --- /dev/null +++ b/docs/examples/python/query_ws.py @@ -0,0 +1,22 @@ +import taosws + +conn = None + +try: + conn = taosws.connect(user="root", + password="taosdata", + host="localhost", + port=6041) + + result = conn.query("SELECT ts, current, location FROM power.meters limit 100") + num_of_fields = result.field_count + print(num_of_fields) + + for row in result: + print(row) + +except Exception as err: + print(err) +finally: + if conn: + conn.close() diff --git a/docs/zh/08-develop/07-tmq.md b/docs/zh/08-develop/07-tmq.md index cf88f5fc2e..3f379b52e6 100644 --- a/docs/zh/08-develop/07-tmq.md +++ b/docs/zh/08-develop/07-tmq.md @@ -249,6 +249,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 +```js + {{#include docs/examples/node/websocketexample/tmq_seek_example.js:subscribe}} +``` @@ -346,6 +349,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 +```js + {{#include docs/examples/node/websocketexample/tmq_seek_example.js:offset}} +``` @@ -445,6 +451,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 +```js + {{#include docs/examples/node/websocketexample/tmq_example.js:commit}} +``` @@ -550,6 +559,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 +```js + {{#include docs/examples/node/websocketexample/tmq_example.js:unsubscribe}} +``` @@ -655,6 +667,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 +```js + {{#include docs/examples/node/websocketexample/tmq_example.js}} +``` From 6f259ab2983417406b109244e06556784a5cbbb0 Mon Sep 17 00:00:00 2001 From: sheyanjie-qq <249478495@qq.com> Date: Fri, 2 Aug 2024 16:32:21 +0800 Subject: [PATCH 09/15] mod rust example --- .../rust/nativeexample/examples/tmq.rs | 39 ++--- docs/examples/rust/restexample/Cargo.toml | 2 + .../restexample/examples/subscribe_demo.rs | 135 ++++++++++++++++++ .../examples/rust/restexample/examples/tmq.rs | 63 ++------ docs/zh/08-develop/07-tmq.md | 50 ++++++- 5 files changed, 217 insertions(+), 72 deletions(-) create mode 100644 docs/examples/rust/restexample/examples/subscribe_demo.rs diff --git a/docs/examples/rust/nativeexample/examples/tmq.rs b/docs/examples/rust/nativeexample/examples/tmq.rs index 04bf66b2ef..c8f2b0a19a 100644 --- a/docs/examples/rust/nativeexample/examples/tmq.rs +++ b/docs/examples/rust/nativeexample/examples/tmq.rs @@ -9,9 +9,11 @@ async fn main() -> anyhow::Result<()> { .filter_level(log::LevelFilter::Info) .init(); use taos_query::prelude::*; + // ANCHOR: create_consumer_dsn let dsn = "taos://localhost:6030".to_string(); log::info!("dsn: {}", dsn); let mut dsn = Dsn::from_str(&dsn)?; + // ANCHOR_END: create_consumer_dsn let taos = TaosBuilder::from_dsn(&dsn)?.build().await?; @@ -43,7 +45,7 @@ async fn main() -> anyhow::Result<()> { .await?; // ANCHOR_END: create_topic - // ANCHOR: create_consumer + // ANCHOR: create_consumer_ac dsn.params.insert("auto.offset.reset".to_string(), "latest".to_string()); dsn.params.insert("msg.with.table.name".to_string(), "true".to_string()); dsn.params.insert("enable.auto.commit".to_string(), "true".to_string()); @@ -53,13 +55,11 @@ async fn main() -> anyhow::Result<()> { let builder = TmqBuilder::from_dsn(&dsn)?; let mut consumer = builder.build().await?; - // ANCHOR_END: create_consumer - - // ANCHOR: subscribe - consumer.subscribe(["topic_meters"]).await?; - // ANCHOR_END: subscribe + // ANCHOR_END: create_consumer_ac // ANCHOR: consume + consumer.subscribe(["topic_meters"]).await?; + { let mut stream = consumer.stream_with_timeout(Timeout::from_secs(1)); @@ -69,7 +69,7 @@ async fn main() -> anyhow::Result<()> { let database = offset.database(); let vgroup_id = offset.vgroup_id(); log::debug!( - "topic: {}, database: {}, vgroup_id: {}", + "receive message from: topic: {}, database: {}, vgroup_id: {}", topic, database, vgroup_id @@ -84,13 +84,13 @@ async fn main() -> anyhow::Result<()> { let json = meta.as_json_meta().await?; let sql = json.to_string(); if let Err(err) = taos.exec(sql).await { - println!("maybe error: {}", err); + println!("maybe error in handling meta message: {}", err); } } MessageSet::Data(data) => { log::info!("Data"); while let Some(data) = data.fetch_raw_block().await? { - log::debug!("data: {:?}", data); + log::debug!("message data: {:?}", data); } } MessageSet::MetaData(meta, data) => { @@ -101,24 +101,24 @@ async fn main() -> anyhow::Result<()> { let json = meta.as_json_meta().await?; let sql = json.to_string(); if let Err(err) = taos.exec(sql).await { - println!("maybe error: {}", err); + println!("maybe error in handling metadata message: {}", err); } while let Some(data) = data.fetch_raw_block().await? { - log::debug!("data: {:?}", data); + log::debug!("message data: {:?}", data); } } } + // commit offset manually when handling message successfully consumer.commit(offset).await?; } } // ANCHOR_END: consume - // ANCHOR: assignments + // ANCHOR: seek_offset let assignments = consumer.assignments().await.unwrap(); - log::info!("assignments: {:?}", assignments); - // ANCHOR_END: assignments - + log::info!("start assignments: {:?}", assignments); + // seek offset for topic_vec_assignment in assignments { let topic = &topic_vec_assignment.0; @@ -136,23 +136,24 @@ async fn main() -> anyhow::Result<()> { begin, end ); - // ANCHOR: seek_offset - let res = consumer.offset_seek(topic, vgroup_id, end).await; + + // seek offset of the (topic, vgroup_id) to the begin + let res = consumer.offset_seek(topic, vgroup_id, begin).await; if res.is_err() { log::error!("seek offset error: {:?}", res); let a = consumer.assignments().await.unwrap(); log::error!("assignments: {:?}", a); } - // ANCHOR_END: seek_offset } let topic_assignment = consumer.topic_assignment(topic).await; log::debug!("topic assignment: {:?}", topic_assignment); } - + // after seek offset let assignments = consumer.assignments().await.unwrap(); log::info!("after seek offset assignments: {:?}", assignments); + // ANCHOR_END: seek_offset // ANCHOR: unsubscribe consumer.unsubscribe().await; diff --git a/docs/examples/rust/restexample/Cargo.toml b/docs/examples/rust/restexample/Cargo.toml index 5fffe215d4..7b13b48104 100644 --- a/docs/examples/rust/restexample/Cargo.toml +++ b/docs/examples/rust/restexample/Cargo.toml @@ -8,5 +8,7 @@ anyhow = "1" chrono = "0.4" serde = { version = "1", features = ["derive"] } tokio = { version = "1", features = ["rt", "macros", "rt-multi-thread"] } +log = "0.4" +pretty_env_logger = "0.5.0" taos = { version = "0.*" } diff --git a/docs/examples/rust/restexample/examples/subscribe_demo.rs b/docs/examples/rust/restexample/examples/subscribe_demo.rs new file mode 100644 index 0000000000..8486419386 --- /dev/null +++ b/docs/examples/rust/restexample/examples/subscribe_demo.rs @@ -0,0 +1,135 @@ +use std::time::Duration; + +use chrono::{DateTime, Local}; +use taos::*; + +// Query options 2, use deserialization with serde. +#[derive(Debug, serde::Deserialize)] +#[allow(dead_code)] +struct Record { + // deserialize timestamp to chrono::DateTime + ts: DateTime, + // float to f32 + current: Option, + // int to i32 + voltage: Option, + phase: Option, +} + +async fn prepare(taos: Taos) -> anyhow::Result<()> { + let inserted = taos.exec_many([ + // create child table + "CREATE TABLE `d0` USING `meters` TAGS(0, 'California.LosAngles')", + // insert into child table + "INSERT INTO `d0` values(now - 10s, 10, 116, 0.32)", + // insert with NULL values + "INSERT INTO `d0` values(now - 8s, NULL, NULL, NULL)", + // insert and automatically create table with tags if not exists + "INSERT INTO `d1` USING `meters` TAGS(1, 'California.SanFrancisco') values(now - 9s, 10.1, 119, 0.33)", + // insert many records in a single sql + "INSERT INTO `d1` values (now-8s, 10, 120, 0.33) (now - 6s, 10, 119, 0.34) (now - 4s, 11.2, 118, 0.322)", + ]).await?; + assert_eq!(inserted, 6); + Ok(()) +} + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + let dsn = "taos://localhost:6030"; + let builder = TaosBuilder::from_dsn(dsn)?; + + let taos = builder.build().await?; + let db = "tmq"; + + // prepare database + taos.exec_many([ + format!("DROP TOPIC IF EXISTS tmq_meters"), + format!("DROP DATABASE IF EXISTS `{db}`"), + format!("CREATE DATABASE `{db}` WAL_RETENTION_PERIOD 3600"), + format!("USE `{db}`"), + // create super table + format!("CREATE TABLE `meters` (`ts` TIMESTAMP, `current` FLOAT, `voltage` INT, `phase` FLOAT) TAGS (`groupid` INT, `location` BINARY(24))"), + // create topic for subscription + format!("CREATE TOPIC tmq_meters AS SELECT * FROM `meters`") + ]) + .await?; + + let task = tokio::spawn(prepare(taos)); + + tokio::time::sleep(Duration::from_secs(1)).await; + + // subscribe + let tmq = TmqBuilder::from_dsn("taos://localhost:6030/?group.id=test")?; + + let mut consumer = tmq.build().await?; + consumer.subscribe(["tmq_meters"]).await?; + + // ANCHOR: consumer_commit_manually + consumer + .stream() + .try_for_each(|(offset, message)| async { + let topic = offset.topic(); + // the vgroup id, like partition id in kafka. + let vgroup_id = offset.vgroup_id(); + println!("* in vgroup id {vgroup_id} of topic {topic}\n"); + + if let Some(data) = message.into_data() { + while let Some(block) = data.fetch_raw_block().await? { + let records: Vec = block.deserialize().try_collect()?; + println!("** read {} records: {:#?}\n", records.len(), records); + } + } + // commit offset manually when you have processed the message. + consumer.commit(offset).await?; + Ok(()) + }) + .await?; + // ANCHOR_END: consumer_commit_manually + + + // ANCHOR: assignments + let assignments = consumer.assignments().await.unwrap(); + log::info!("assignments: {:?}", assignments); + // ANCHOR_END: assignments + + // seek offset + for topic_vec_assignment in assignments { + let topic = &topic_vec_assignment.0; + let vec_assignment = topic_vec_assignment.1; + for assignment in vec_assignment { + let vgroup_id = assignment.vgroup_id(); + let current = assignment.current_offset(); + let begin = assignment.begin(); + let end = assignment.end(); + log::debug!( + "topic: {}, vgroup_id: {}, current offset: {} begin {}, end: {}", + topic, + vgroup_id, + current, + begin, + end + ); + // ANCHOR: seek_offset + let res = consumer.offset_seek(topic, vgroup_id, end).await; + if res.is_err() { + log::error!("seek offset error: {:?}", res); + let a = consumer.assignments().await.unwrap(); + log::error!("assignments: {:?}", a); + } + // ANCHOR_END: seek_offset + } + + let topic_assignment = consumer.topic_assignment(topic).await; + log::debug!("topic assignment: {:?}", topic_assignment); + } + + // after seek offset + let assignments = consumer.assignments().await.unwrap(); + log::info!("after seek offset assignments: {:?}", assignments); + + consumer.unsubscribe().await; + + task.await??; + + Ok(()) +} diff --git a/docs/examples/rust/restexample/examples/tmq.rs b/docs/examples/rust/restexample/examples/tmq.rs index 0438e47515..b931a871b6 100644 --- a/docs/examples/rust/restexample/examples/tmq.rs +++ b/docs/examples/rust/restexample/examples/tmq.rs @@ -42,7 +42,7 @@ async fn main() -> anyhow::Result<()> { .await?; // ANCHOR_END: create_topic - // ANCHOR: create_consumer + // ANCHOR: create_consumer_ac dsn.params.insert("auto.offset.reset".to_string(), "latest".to_string()); dsn.params.insert("msg.with.table.name".to_string(), "true".to_string()); dsn.params.insert("enable.auto.commit".to_string(), "true".to_string()); @@ -52,7 +52,7 @@ async fn main() -> anyhow::Result<()> { let builder = TmqBuilder::from_dsn(&dsn)?; let mut consumer = builder.build().await?; - // ANCHOR_END: create_consumer + // ANCHOR_END: create_consumer_ac // ANCHOR: subscribe consumer.subscribe(["topic_meters"]).await?; @@ -60,56 +60,23 @@ async fn main() -> anyhow::Result<()> { // ANCHOR: consume { - let mut stream = consumer.stream_with_timeout(Timeout::from_secs(1)); - - while let Some((offset, message)) = stream.try_next().await? { - - let topic: &str = offset.topic(); - let database = offset.database(); + consumer + .stream() + .try_for_each(|(offset, message)| async { + let topic = offset.topic(); + // the vgroup id, like partition id in kafka. let vgroup_id = offset.vgroup_id(); - log::debug!( - "topic: {}, database: {}, vgroup_id: {}", - topic, - database, - vgroup_id - ); + println!("* in vgroup id {vgroup_id} of topic {topic}\n"); - match message { - MessageSet::Meta(meta) => { - log::info!("Meta"); - let raw = meta.as_raw_meta().await?; - taos.write_raw_meta(&raw).await?; - - let json = meta.as_json_meta().await?; - let sql = json.to_string(); - if let Err(err) = taos.exec(sql).await { - println!("maybe error: {}", err); - } - } - MessageSet::Data(data) => { - log::info!("Data"); - while let Some(data) = data.fetch_raw_block().await? { - log::debug!("data: {:?}", data); - } - } - MessageSet::MetaData(meta, data) => { - log::info!("MetaData"); - let raw = meta.as_raw_meta().await?; - taos.write_raw_meta(&raw).await?; - - let json = meta.as_json_meta().await?; - let sql = json.to_string(); - if let Err(err) = taos.exec(sql).await { - println!("maybe error: {}", err); - } - - while let Some(data) = data.fetch_raw_block().await? { - log::debug!("data: {:?}", data); - } + if let Some(data) = message.into_data() { + while let Some(block) = data.fetch_raw_block().await? { + let records: Vec = block.deserialize().try_collect()?; + println!("** read {} records: {:#?}\n", records.len(), records); } } - consumer.commit(offset).await?; - } + Ok(()) + }) + .await?; } // ANCHOR_END: consume diff --git a/docs/zh/08-develop/07-tmq.md b/docs/zh/08-develop/07-tmq.md index 6f259cf521..36ff09d0f4 100644 --- a/docs/zh/08-develop/07-tmq.md +++ b/docs/zh/08-develop/07-tmq.md @@ -131,8 +131,11 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 ```rust {{#include docs/examples/rust/restexample/examples/tmq.rs:create_consumer_dsn}} +``` -{{#include docs/examples/rust/restexample/examples/tmq.rs:create_consumer}} + +```rust +{{#include docs/examples/rust/restexample/examples/tmq.rs:create_consumer_ac}} ``` @@ -190,6 +193,13 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 +```rust +{{#include docs/examples/rust/nativeexample/examples/tmq.rs:create_consumer_dsn}} +``` + +```rust +{{#include docs/examples/rust/nativeexample/examples/tmq.rs:create_consumer_ac}} +``` @@ -242,7 +252,12 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 +消费者可订阅一个或多个 `TOPIC`,一般建议一个消费者只订阅一个 `TOPIC`。 +TMQ 消息队列是一个 [futures::Stream](https://docs.rs/futures/latest/futures/stream/index.html) 类型,可以使用相应 API 对每个消息进行消费,并通过 `.commit` 进行已消费标记。 +```rust +{{#include docs/examples/rust/restexample/examples/tmq.rs:consume}} +``` @@ -290,7 +305,7 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +同 Websocket 示例代码 @@ -322,6 +337,10 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 ```java {{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WsConsumerLoopFull.java:consumer_seek}} ``` +1. 使用 consumer.poll 方法轮询数据,直到获取到数据为止。 +2. 对于轮询到的第一批数据,打印第一条数据的内容,并获取当前消费者的分区分配信息。 +3. 使用 consumer.seekToBeginning 方法将所有分区的偏移量重置到开始位置,并打印成功重置的消息。 +4. 再次使用 consumer.poll 方法轮询数据,并打印第一条数据的内容。 @@ -340,6 +359,16 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 +```rust +{{#include docs/examples/rust/nativeexample/examples/tmq.rs:seek_offset}} +``` + +1. 通过调用 consumer.assignments() 方法获取消费者当前的分区分配信息,并记录初始分配状态。 +2. 遍历每个分区分配信息,对于每个分区:提取主题(topic)、消费组ID(vgroup_id)、当前偏移量(current)、起始偏移量(begin)和结束偏移量(end)。 +记录这些信息。 +1. 调用 consumer.offset_seek 方法将偏移量设置到起始位置。如果操作失败,记录错误信息和当前分配状态。 +2. 在所有分区的偏移量调整完成后,再次获取并记录消费者的分区分配信息,以确认偏移量调整后的状态。 + @@ -387,7 +416,7 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +同 Websocket 代码样例。 @@ -413,6 +442,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 ## 提交 Offset 当消费者读取并处理完消息后,它可以提交 Offset,这表示消费者已经成功处理到这个 Offset 的消息。Offset 提交可以是自动的(根据配置定期提交)或手动的(应用程序控制何时提交)。 当创建消费者时,属性 `enable.auto.commit` 为 false 时,可以手动提交 offset。 + +**注意**:手工提交消费进度前确保消息正常处理完成,否则处理出错的消息不会被再次消费。自动提交是在本次 `poll` 消息时可能会提交上次消息的消费进度,因此请确保消息处理完毕再进行下一次 `poll` 或消息获取。 + ### Websocket 连接 @@ -438,7 +470,11 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 +```rust +{{#include docs/examples/rust/restexample/examples/subscribe_demo.rs:consumer_commit_manually}} +``` +可以通过 `consumer.commit` 方法来手工提交消费进度。 @@ -488,7 +524,7 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +同 Websocket 代码样例。 @@ -543,7 +579,11 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 +```rust +{{#include docs/examples/rust/restexample/examples/tmq.rs:unsubscribe}} +``` +**注意**:消费者取消订阅后无法重用,如果想订阅新的 `topic`, 请重新创建消费者。 @@ -592,7 +632,7 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +同 Websocket 代码样例。 From 8c6ff828e913e2c2eeef766a9c31b15146cd7b1b Mon Sep 17 00:00:00 2001 From: sheyanjie-qq <249478495@qq.com> Date: Fri, 2 Aug 2024 17:06:40 +0800 Subject: [PATCH 10/15] mod rust example --- .../nativeexample/examples/subscribe_demo.rs | 48 +++++++- .../restexample/examples/subscribe_demo.rs | 4 +- docs/zh/08-develop/01-connect/index.md | 82 ------------- docs/zh/08-develop/02-sql.md | 21 +--- docs/zh/08-develop/04-schemaless.md | 12 -- docs/zh/08-develop/05-stmt.md | 13 --- docs/zh/08-develop/07-tmq.md | 110 +----------------- 7 files changed, 56 insertions(+), 234 deletions(-) diff --git a/docs/examples/rust/nativeexample/examples/subscribe_demo.rs b/docs/examples/rust/nativeexample/examples/subscribe_demo.rs index d54bb60e93..8486419386 100644 --- a/docs/examples/rust/nativeexample/examples/subscribe_demo.rs +++ b/docs/examples/rust/nativeexample/examples/subscribe_demo.rs @@ -38,7 +38,7 @@ async fn main() -> anyhow::Result<()> { let dsn = "taos://localhost:6030"; let builder = TaosBuilder::from_dsn(dsn)?; - let taos = builder.build()?; + let taos = builder.build().await?; let db = "tmq"; // prepare database @@ -61,9 +61,10 @@ async fn main() -> anyhow::Result<()> { // subscribe let tmq = TmqBuilder::from_dsn("taos://localhost:6030/?group.id=test")?; - let mut consumer = tmq.build()?; + let mut consumer = tmq.build().await?; consumer.subscribe(["tmq_meters"]).await?; + // ANCHOR: consumer_commit_manually consumer .stream() .try_for_each(|(offset, message)| async { @@ -78,11 +79,54 @@ async fn main() -> anyhow::Result<()> { println!("** read {} records: {:#?}\n", records.len(), records); } } + // commit offset manually when you have processed the message. consumer.commit(offset).await?; Ok(()) }) .await?; + // ANCHOR_END: consumer_commit_manually + + // ANCHOR: assignments + let assignments = consumer.assignments().await.unwrap(); + log::info!("assignments: {:?}", assignments); + // ANCHOR_END: assignments + + // seek offset + for topic_vec_assignment in assignments { + let topic = &topic_vec_assignment.0; + let vec_assignment = topic_vec_assignment.1; + for assignment in vec_assignment { + let vgroup_id = assignment.vgroup_id(); + let current = assignment.current_offset(); + let begin = assignment.begin(); + let end = assignment.end(); + log::debug!( + "topic: {}, vgroup_id: {}, current offset: {} begin {}, end: {}", + topic, + vgroup_id, + current, + begin, + end + ); + // ANCHOR: seek_offset + let res = consumer.offset_seek(topic, vgroup_id, end).await; + if res.is_err() { + log::error!("seek offset error: {:?}", res); + let a = consumer.assignments().await.unwrap(); + log::error!("assignments: {:?}", a); + } + // ANCHOR_END: seek_offset + } + + let topic_assignment = consumer.topic_assignment(topic).await; + log::debug!("topic assignment: {:?}", topic_assignment); + } + + // after seek offset + let assignments = consumer.assignments().await.unwrap(); + log::info!("after seek offset assignments: {:?}", assignments); + consumer.unsubscribe().await; task.await??; diff --git a/docs/examples/rust/restexample/examples/subscribe_demo.rs b/docs/examples/rust/restexample/examples/subscribe_demo.rs index 8486419386..2e95fb0543 100644 --- a/docs/examples/rust/restexample/examples/subscribe_demo.rs +++ b/docs/examples/rust/restexample/examples/subscribe_demo.rs @@ -35,7 +35,7 @@ async fn prepare(taos: Taos) -> anyhow::Result<()> { #[tokio::main] async fn main() -> anyhow::Result<()> { - let dsn = "taos://localhost:6030"; + let dsn = "ws://localhost:6041"; let builder = TaosBuilder::from_dsn(dsn)?; let taos = builder.build().await?; @@ -59,7 +59,7 @@ async fn main() -> anyhow::Result<()> { tokio::time::sleep(Duration::from_secs(1)).await; // subscribe - let tmq = TmqBuilder::from_dsn("taos://localhost:6030/?group.id=test")?; + let tmq = TmqBuilder::from_dsn("ws://localhost:6041/?group.id=test")?; let mut consumer = tmq.build().await?; consumer.subscribe(["tmq_meters"]).await?; diff --git a/docs/zh/08-develop/01-connect/index.md b/docs/zh/08-develop/01-connect/index.md index 21d11df23c..0e92400d9e 100644 --- a/docs/zh/08-develop/01-connect/index.md +++ b/docs/zh/08-develop/01-connect/index.md @@ -13,8 +13,6 @@ import ConnNode from "./_connect_node.mdx"; import ConnPythonNative from "./_connect_python.mdx"; import ConnCSNative from "./_connect_cs.mdx"; import ConnC from "./_connect_c.mdx"; -import ConnR from "./_connect_r.mdx"; -import ConnPHP from "./_connect_php.mdx"; import InstallOnLinux from "../../14-reference/05-connector/_linux_install.mdx"; import InstallOnWindows from "../../14-reference/05-connector/_windows_install.mdx"; import InstallOnMacOS from "../../14-reference/05-connector/_macos_install.mdx"; @@ -249,62 +247,12 @@ dotnet add package TDengine.Connector ::: - - - -1. 下载 [taos-jdbcdriver-version-dist.jar](https://repo1.maven.org/maven2/com/taosdata/jdbc/taos-jdbcdriver/3.0.0/)。 -2. 安装 R 的依赖包`RJDBC`: - -```R -install.packages("RJDBC") -``` - 如果已经安装了 TDengine 服务端软件或 TDengine 客户端驱动 taosc, 那么已经安装了 C 连接器,无需额外操作。
-
- - -**下载代码并解压:** - -```shell -curl -L -o php-tdengine.tar.gz https://github.com/Yurunsoft/php-tdengine/archive/refs/tags/v1.0.2.tar.gz \ -&& mkdir php-tdengine \ -&& tar -xzf php-tdengine.tar.gz -C php-tdengine --strip-components=1 -``` - -> 版本 `v1.0.2` 只是示例,可替换为任意更新的版本,可在 [TDengine PHP Connector 发布历史](https://github.com/Yurunsoft/php-tdengine/releases) 中查看可用版本。 - -**非 Swoole 环境:** - -```shell -phpize && ./configure && make -j && make install -``` - -**手动指定 TDengine 目录:** - -```shell -phpize && ./configure --with-tdengine-dir=/usr/local/Cellar/tdengine/3.0.0.0 && make -j && make install -``` - -> `--with-tdengine-dir=` 后跟上 TDengine 目录。 -> 适用于默认找不到的情况,或者 macOS 系统用户。 - -**Swoole 环境:** - -```shell -phpize && ./configure --enable-swoole && make -j && make install -``` - -**启用扩展:** - -方法一:在 `php.ini` 中加入 `extension=tdengine` - -方法二:运行带参数 `php -d extension=tdengine test.php` -
@@ -404,8 +352,6 @@ DSN 的详细说明和如何使用详见 [连接功能](../../reference/connecto - `reconnectRetryCount`:重连次数,默认为 3。 - `reconnectIntervalMs`:重连间隔毫秒时间,默认为 2000。
- - 使用客户端驱动访问 TDengine 集群的基本过程为:建立连接、查询和写入、关闭连接、清除资源。 @@ -433,10 +379,6 @@ DSN 的详细说明和如何使用详见 [连接功能](../../reference/connecto ::: - - - -
@@ -475,15 +417,9 @@ DSN 的详细说明和如何使用详见 [连接功能](../../reference/connecto {{#include docs/examples/csharp/wsConnect/Program.cs:main}} ```
- - - - - - ### 原生连接 @@ -513,15 +449,9 @@ DSN 的详细说明和如何使用详见 [连接功能](../../reference/connecto {{#include docs/examples/csharp/connect/Program.cs:main}} ``` - - - - - - @@ -550,15 +480,9 @@ DSN 的详细说明和如何使用详见 [连接功能](../../reference/connecto 不支持 - - - - - - @@ -642,14 +566,8 @@ let taos = pool.get()?; 不支持 - - - - - - diff --git a/docs/zh/08-develop/02-sql.md b/docs/zh/08-develop/02-sql.md index 8871dee786..01d94cca53 100644 --- a/docs/zh/08-develop/02-sql.md +++ b/docs/zh/08-develop/02-sql.md @@ -13,9 +13,8 @@ TDengine 对 SQL 语言提供了全面的支持,允许用户以熟悉的 SQL :::note -REST 连接:各编程语言的连接器封装使用 `HTTP` 请求的连接,支持数据写入和查询操作。 - -REST API:通过 `curl` 命令进行数据写入和查询操作。 +REST 连接:各编程语言的连接器封装使用 `HTTP` 请求的连接,支持数据写入和查询操作,开发者依然使用连接器提供的接口访问 `TDengine`。 +REST API:直接调用 `taosadapter` 提供的 REST API 接口,进行数据写入和查询操作。代码示例使用 `curl` 命令来演示。 ::: @@ -68,16 +67,12 @@ REST API:通过 `curl` 命令进行数据写入和查询操作。 {{#include docs/examples/csharp/wsInsert/Program.cs:create_db_and_table}} ``` - - ```c {{#include docs/examples/c/CCreateDBDemo.c:create_db_and_table}} ``` > **注意**:如果不使用 `USE power` 指定数据库,则后续对表的操作都需要增加数据库名称作为前缀,如 power.meters。 - - 创建数据库 @@ -149,8 +144,6 @@ NOW 为系统内部函数,默认为客户端所在计算机当前时间。 NOW {{#include docs/examples/csharp/wsInsert/Program.cs:insert_data}} ``` - - ```c {{#include docs/examples/c/CInsertDataDemo.c:insert_data}} @@ -159,8 +152,6 @@ NOW 为系统内部函数,默认为客户端所在计算机当前时间。 NOW **Note** NOW 为系统内部函数,默认为客户端所在计算机当前时间。 NOW + 1s 代表客户端当前时间往后加 1 秒,数字后面代表时间单位:a(毫秒),s(秒),m(分),h(小时),d(天),w(周),n(月),y(年)。 - - 写入数据 @@ -222,15 +213,11 @@ curl --location -uroot:taosdata 'http://127.0.0.1:6041/rest/sql' \ {{#include docs/examples/csharp/wsInsert/Program.cs:select_data}} ``` - - ```c {{#include docs/examples/c/CQueryDataDemo.c:query_data}} ``` - - 查询数据 @@ -288,15 +275,11 @@ reqId 可用于请求链路追踪,reqId 就像分布式系统中的 traceId {{#include docs/examples/csharp/wsInsert/Program.cs:query_id}} ``` - - ```c {{#include docs/examples/c/CWithReqIdDemo.c:with_reqid}} ``` - - 查询数据,指定 reqId 为 3 diff --git a/docs/zh/08-develop/04-schemaless.md b/docs/zh/08-develop/04-schemaless.md index 611878960d..5d376222e7 100644 --- a/docs/zh/08-develop/04-schemaless.md +++ b/docs/zh/08-develop/04-schemaless.md @@ -200,12 +200,8 @@ writer.write(lineDemo, SchemalessProtocolType.LINE, SchemalessTimestampType.NANO {{#include docs/examples/csharp/wssml/Program.cs:main}} ``` - - - - ### 原生连接 @@ -234,12 +230,8 @@ writer.write(lineDemo, SchemalessProtocolType.LINE, SchemalessTimestampType.NANO {{#include docs/examples/csharp/nativesml/Program.cs:main}} ``` - - - - @@ -262,12 +254,8 @@ writer.write(lineDemo, SchemalessProtocolType.LINE, SchemalessTimestampType.NANO 不支持 - - - - diff --git a/docs/zh/08-develop/05-stmt.md b/docs/zh/08-develop/05-stmt.md index d3e71eed63..f60e7b1705 100644 --- a/docs/zh/08-develop/05-stmt.md +++ b/docs/zh/08-develop/05-stmt.md @@ -60,15 +60,9 @@ import TabItem from "@theme/TabItem"; ```csharp {{#include docs/examples/csharp/wsStmt/Program.cs:main}} ``` - - - - - - @@ -98,15 +92,8 @@ import TabItem from "@theme/TabItem"; ```csharp {{#include docs/examples/csharp/stmtInsert/Program.cs:main}} ``` - - - - - - - diff --git a/docs/zh/08-develop/07-tmq.md b/docs/zh/08-develop/07-tmq.md index d2b759bfd7..ff7ac5d997 100644 --- a/docs/zh/08-develop/07-tmq.md +++ b/docs/zh/08-develop/07-tmq.md @@ -90,15 +90,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 其他参数见上表。 - - - - - - @@ -153,16 +147,8 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 ``` - - - - - - - - @@ -212,17 +198,10 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 ``` - - - - - - - ## 订阅消费数据 @@ -276,16 +255,8 @@ TMQ 消息队列是一个 [futures::Stream](https://docs.rs/futures/latest/futur ``` - - - - - - - - @@ -320,17 +291,10 @@ TMQ 消息队列是一个 [futures::Stream](https://docs.rs/futures/latest/futur ``` - - - - - - - ## 指定订阅的 Offset @@ -390,17 +354,10 @@ TMQ 消息队列是一个 [futures::Stream](https://docs.rs/futures/latest/futur ``` - - - - - - - ### 原生连接 @@ -434,16 +391,8 @@ TMQ 消息队列是一个 [futures::Stream](https://docs.rs/futures/latest/futur ``` - - - - - - - - @@ -499,18 +448,9 @@ TMQ 消息队列是一个 [futures::Stream](https://docs.rs/futures/latest/futur ``` - - - - - - - - - ### 原生连接 @@ -549,18 +489,9 @@ TMQ 消息队列是一个 [futures::Stream](https://docs.rs/futures/latest/futur ``` - - - - - - - - - @@ -611,18 +542,10 @@ TMQ 消息队列是一个 [futures::Stream](https://docs.rs/futures/latest/futur ``` - - - - - - - - ### 原生连接 @@ -660,18 +583,10 @@ TMQ 消息队列是一个 [futures::Stream](https://docs.rs/futures/latest/futur ``` - - - - - - - - @@ -703,7 +618,9 @@ TMQ 消息队列是一个 [futures::Stream](https://docs.rs/futures/latest/futur - +```rust +{{#include docs/examples/rust/restexample/examples/subscribe_demo.rs}} +``` @@ -719,18 +636,10 @@ TMQ 消息队列是一个 [futures::Stream](https://docs.rs/futures/latest/futur ``` - - - - - - - - ### 原生连接 @@ -763,7 +672,9 @@ TMQ 消息队列是一个 [futures::Stream](https://docs.rs/futures/latest/futur - +```rust +{{#include docs/examples/rust/nativeexample/examples/subscribe_demo.rs}} +``` @@ -776,16 +687,7 @@ TMQ 消息队列是一个 [futures::Stream](https://docs.rs/futures/latest/futur ``` - - - - - - - - - From daf6437f53e599bf392b0d54ae989530240b81c4 Mon Sep 17 00:00:00 2001 From: t_max <1172915550@qq.com> Date: Fri, 2 Aug 2024 17:12:14 +0800 Subject: [PATCH 11/15] docs: improve go and csharp example --- docs/examples/csharp/.gitignore | 8 +- docs/examples/csharp/connect/Program.cs | 9 +- docs/examples/csharp/nativesml/Program.cs | 4 +- .../obj/nativesml.csproj.nuget.dgspec.json | 67 -------- .../obj/nativesml.csproj.nuget.g.props | 15 -- .../obj/nativesml.csproj.nuget.g.targets | 2 - .../csharp/nativesml/obj/project.assets.json | 149 ----------------- .../csharp/nativesml/obj/project.nuget.cache | 11 -- .../nativesml/obj/project.packagespec.json | 1 - .../obj/rider.project.model.nuget.info | 1 - .../nativesml/obj/rider.project.restore.info | 1 - docs/examples/csharp/optsJSON/Program.cs | 4 +- docs/examples/csharp/sqlInsert/Program.cs | 61 +++++-- docs/examples/csharp/stmtInsert/Program.cs | 4 +- docs/examples/csharp/subscribe/Program.cs | 51 ++++-- docs/examples/csharp/wsConnect/Program.cs | 12 +- docs/examples/csharp/wsInsert/Program.cs | 22 +-- docs/examples/csharp/wsStmt/Program.cs | 4 +- docs/examples/csharp/wssml/Program.cs | 4 +- .../csharp/wssml/obj/project.assets.json | 149 ----------------- .../csharp/wssml/obj/project.nuget.cache | 11 -- .../csharp/wssml/obj/project.packagespec.json | 1 - .../wssml/obj/rider.project.model.nuget.info | 1 - .../wssml/obj/rider.project.restore.info | 1 - .../wssml/obj/wssml.csproj.nuget.dgspec.json | 67 -------- .../wssml/obj/wssml.csproj.nuget.g.props | 15 -- .../wssml/obj/wssml.csproj.nuget.g.targets | 2 - docs/examples/csharp/wssubscribe/Program.cs | 51 ++++-- .../wssubscribe/obj/project.assets.json | 150 ------------------ .../wssubscribe/obj/project.nuget.cache | 11 -- .../wssubscribe/obj/project.packagespec.json | 1 - .../obj/rider.project.model.nuget.info | 1 - .../obj/rider.project.restore.info | 1 - .../obj/wssubscribe.csproj.nuget.dgspec.json | 68 -------- .../obj/wssubscribe.csproj.nuget.g.props | 18 --- .../obj/wssubscribe.csproj.nuget.g.targets | 2 - .../csharp/wssubscribe/wssubscribe.csproj | 2 +- docs/examples/go/connect/cgoexample/main.go | 3 +- docs/examples/go/connect/connpool/main.go | 1 - docs/examples/go/connect/restexample/main.go | 3 +- docs/examples/go/connect/wsexample/main.go | 3 +- docs/examples/go/queryreqid/main.go | 13 +- docs/examples/go/schemaless/native/main.go | 14 +- docs/examples/go/schemaless/ws/main.go | 15 +- docs/examples/go/sqlquery/main.go | 21 +-- docs/examples/go/stmt/native/main.go | 21 +-- docs/examples/go/stmt/ws/main.go | 27 ++-- docs/examples/go/tmq/native/main.go | 55 +++++-- docs/examples/go/tmq/ws/main.go | 55 +++++-- docs/zh/08-develop/04-schemaless.md | 7 +- tests/docs-examples-test/csharp.sh | 51 ++++-- tests/docs-examples-test/go.sh | 49 +++++- 52 files changed, 389 insertions(+), 931 deletions(-) delete mode 100644 docs/examples/csharp/nativesml/obj/nativesml.csproj.nuget.dgspec.json delete mode 100644 docs/examples/csharp/nativesml/obj/nativesml.csproj.nuget.g.props delete mode 100644 docs/examples/csharp/nativesml/obj/nativesml.csproj.nuget.g.targets delete mode 100644 docs/examples/csharp/nativesml/obj/project.assets.json delete mode 100644 docs/examples/csharp/nativesml/obj/project.nuget.cache delete mode 100644 docs/examples/csharp/nativesml/obj/project.packagespec.json delete mode 100644 docs/examples/csharp/nativesml/obj/rider.project.model.nuget.info delete mode 100644 docs/examples/csharp/nativesml/obj/rider.project.restore.info delete mode 100644 docs/examples/csharp/wssml/obj/project.assets.json delete mode 100644 docs/examples/csharp/wssml/obj/project.nuget.cache delete mode 100644 docs/examples/csharp/wssml/obj/project.packagespec.json delete mode 100644 docs/examples/csharp/wssml/obj/rider.project.model.nuget.info delete mode 100644 docs/examples/csharp/wssml/obj/rider.project.restore.info delete mode 100644 docs/examples/csharp/wssml/obj/wssml.csproj.nuget.dgspec.json delete mode 100644 docs/examples/csharp/wssml/obj/wssml.csproj.nuget.g.props delete mode 100644 docs/examples/csharp/wssml/obj/wssml.csproj.nuget.g.targets delete mode 100644 docs/examples/csharp/wssubscribe/obj/project.assets.json delete mode 100644 docs/examples/csharp/wssubscribe/obj/project.nuget.cache delete mode 100644 docs/examples/csharp/wssubscribe/obj/project.packagespec.json delete mode 100644 docs/examples/csharp/wssubscribe/obj/rider.project.model.nuget.info delete mode 100644 docs/examples/csharp/wssubscribe/obj/rider.project.restore.info delete mode 100644 docs/examples/csharp/wssubscribe/obj/wssubscribe.csproj.nuget.dgspec.json delete mode 100644 docs/examples/csharp/wssubscribe/obj/wssubscribe.csproj.nuget.g.props delete mode 100644 docs/examples/csharp/wssubscribe/obj/wssubscribe.csproj.nuget.g.targets diff --git a/docs/examples/csharp/.gitignore b/docs/examples/csharp/.gitignore index b0df020f44..da1cdfe217 100644 --- a/docs/examples/csharp/.gitignore +++ b/docs/examples/csharp/.gitignore @@ -3,6 +3,7 @@ connect/bin influxdbLine/bin optsJSON/bin +nativesml/bin optsTelnet/bin query/bin sqlInsert/bin @@ -11,9 +12,12 @@ subscribe/bin wsConnect/bin wsInsert/bin wsQuery/bin +wssml/bin wsStmt/bin +wssubscribe/bin connect/obj influxdbLine/obj +nativesml/obj optsJSON/obj optsTelnet/obj query/obj @@ -23,4 +27,6 @@ subscribe/obj wsConnect/obj wsInsert/obj wsQuery/obj -wsStmt/obj \ No newline at end of file +wssml/obj +wsStmt/obj +wssubscribe/obj \ No newline at end of file diff --git a/docs/examples/csharp/connect/Program.cs b/docs/examples/csharp/connect/Program.cs index 697871573c..7aaed2cfba 100644 --- a/docs/examples/csharp/connect/Program.cs +++ b/docs/examples/csharp/connect/Program.cs @@ -8,26 +8,27 @@ namespace TDengineExample // ANCHOR: main static void Main(String[] args) { + var connectionString = "host=127.0.0.1;port=6030;username=root;password=taosdata"; try { // Connect to TDengine server using Native - var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); + var builder = new ConnectionStringBuilder(connectionString); // Open connection with using block, it will close the connection automatically using (var client = DbDriver.Open(builder)) { - Console.WriteLine("connected"); + Console.WriteLine("Connected to " + connectionString + " successfully."); } } catch (TDengineError e) { // handle TDengine error - Console.WriteLine(e.Message); + Console.WriteLine("Failed to connect to " + connectionString + "; ErrCode:" + e.Code + "; ErrMessage: " + e.Error); throw; } catch (Exception e) { // handle other exceptions - Console.WriteLine(e.Message); + Console.WriteLine("Failed to connect to " + connectionString + "; Err:" + e.Message); throw; } } diff --git a/docs/examples/csharp/nativesml/Program.cs b/docs/examples/csharp/nativesml/Program.cs index c4925041a1..cfee07eee0 100644 --- a/docs/examples/csharp/nativesml/Program.cs +++ b/docs/examples/csharp/nativesml/Program.cs @@ -42,13 +42,13 @@ namespace TDengineExample catch (TDengineError e) { // handle TDengine error - Console.WriteLine(e.Message); + Console.WriteLine("Failed to insert data with schemaless; ErrCode:" + e.Code + "; ErrMessage: " + e.Error); throw; } catch (Exception e) { // handle other exceptions - Console.WriteLine(e.Message); + Console.WriteLine("Failed to insert data with schemaless; Err:" + e.Message); throw; } } diff --git a/docs/examples/csharp/nativesml/obj/nativesml.csproj.nuget.dgspec.json b/docs/examples/csharp/nativesml/obj/nativesml.csproj.nuget.dgspec.json deleted file mode 100644 index 74b8259305..0000000000 --- a/docs/examples/csharp/nativesml/obj/nativesml.csproj.nuget.dgspec.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "format": 1, - "restore": { - "/mnt/e/github/TDengine/docs/examples/csharp/nativesml/nativesml.csproj": {} - }, - "projects": { - "/mnt/e/github/TDengine/docs/examples/csharp/nativesml/nativesml.csproj": { - "version": "1.0.0", - "restore": { - "projectUniqueName": "/mnt/e/github/TDengine/docs/examples/csharp/nativesml/nativesml.csproj", - "projectName": "nativesml", - "projectPath": "/mnt/e/github/TDengine/docs/examples/csharp/nativesml/nativesml.csproj", - "packagesPath": "/root/.nuget/packages/", - "outputPath": "/mnt/e/github/TDengine/docs/examples/csharp/nativesml/obj/", - "projectStyle": "PackageReference", - "configFilePaths": [ - "/root/.nuget/NuGet/NuGet.Config" - ], - "originalTargetFrameworks": [ - "net6.0" - ], - "sources": { - "https://api.nuget.org/v3/index.json": {} - }, - "frameworks": { - "net6.0": { - "targetAlias": "net6.0", - "projectReferences": {} - } - }, - "warningProperties": { - "warnAsError": [ - "NU1605" - ] - } - }, - "frameworks": { - "net6.0": { - "targetAlias": "net6.0", - "dependencies": { - "TDengine.Connector": { - "target": "Package", - "version": "[3.1.*, )" - } - }, - "imports": [ - "net461", - "net462", - "net47", - "net471", - "net472", - "net48", - "net481" - ], - "assetTargetFallback": true, - "warn": true, - "frameworkReferences": { - "Microsoft.NETCore.App": { - "privateAssets": "all" - } - }, - "runtimeIdentifierGraphPath": "/root/.dotnet/sdk/8.0.100/RuntimeIdentifierGraph.json" - } - } - } - } -} \ No newline at end of file diff --git a/docs/examples/csharp/nativesml/obj/nativesml.csproj.nuget.g.props b/docs/examples/csharp/nativesml/obj/nativesml.csproj.nuget.g.props deleted file mode 100644 index a270b60d2c..0000000000 --- a/docs/examples/csharp/nativesml/obj/nativesml.csproj.nuget.g.props +++ /dev/null @@ -1,15 +0,0 @@ - - - - True - NuGet - $(MSBuildThisFileDirectory)project.assets.json - /root/.nuget/packages/ - /root/.nuget/packages/ - PackageReference - 6.8.0 - - - - - \ No newline at end of file diff --git a/docs/examples/csharp/nativesml/obj/nativesml.csproj.nuget.g.targets b/docs/examples/csharp/nativesml/obj/nativesml.csproj.nuget.g.targets deleted file mode 100644 index 35a7576c5a..0000000000 --- a/docs/examples/csharp/nativesml/obj/nativesml.csproj.nuget.g.targets +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/docs/examples/csharp/nativesml/obj/project.assets.json b/docs/examples/csharp/nativesml/obj/project.assets.json deleted file mode 100644 index 652bbd6688..0000000000 --- a/docs/examples/csharp/nativesml/obj/project.assets.json +++ /dev/null @@ -1,149 +0,0 @@ -{ - "version": 3, - "targets": { - "net6.0": { - "Newtonsoft.Json/13.0.3": { - "type": "package", - "compile": { - "lib/net6.0/Newtonsoft.Json.dll": { - "related": ".xml" - } - }, - "runtime": { - "lib/net6.0/Newtonsoft.Json.dll": { - "related": ".xml" - } - } - }, - "TDengine.Connector/3.1.3": { - "type": "package", - "dependencies": { - "Newtonsoft.Json": "13.0.3" - }, - "compile": { - "lib/net6.0/TDengine.dll": {} - }, - "runtime": { - "lib/net6.0/TDengine.dll": {} - } - } - } - }, - "libraries": { - "Newtonsoft.Json/13.0.3": { - "sha512": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==", - "type": "package", - "path": "newtonsoft.json/13.0.3", - "files": [ - ".nupkg.metadata", - ".signature.p7s", - "LICENSE.md", - "README.md", - "lib/net20/Newtonsoft.Json.dll", - "lib/net20/Newtonsoft.Json.xml", - "lib/net35/Newtonsoft.Json.dll", - "lib/net35/Newtonsoft.Json.xml", - "lib/net40/Newtonsoft.Json.dll", - "lib/net40/Newtonsoft.Json.xml", - "lib/net45/Newtonsoft.Json.dll", - "lib/net45/Newtonsoft.Json.xml", - "lib/net6.0/Newtonsoft.Json.dll", - "lib/net6.0/Newtonsoft.Json.xml", - "lib/netstandard1.0/Newtonsoft.Json.dll", - "lib/netstandard1.0/Newtonsoft.Json.xml", - "lib/netstandard1.3/Newtonsoft.Json.dll", - "lib/netstandard1.3/Newtonsoft.Json.xml", - "lib/netstandard2.0/Newtonsoft.Json.dll", - "lib/netstandard2.0/Newtonsoft.Json.xml", - "newtonsoft.json.13.0.3.nupkg.sha512", - "newtonsoft.json.nuspec", - "packageIcon.png" - ] - }, - "TDengine.Connector/3.1.3": { - "sha512": "dDX+Oex4I0X9yCalU0/YyUN0ecy+8X5xj6N8CoqeLrU6ICYDZgilSGQK9Fh3qmLobhGQvOJWwDpoO73rryHU5Q==", - "type": "package", - "path": "tdengine.connector/3.1.3", - "files": [ - ".nupkg.metadata", - "docs/README.md", - "image/logo.jpg", - "lib/net45/TDengine.dll", - "lib/net451/TDengine.dll", - "lib/net5.0/TDengine.dll", - "lib/net6.0/TDengine.dll", - "lib/netstandard2.0/TDengine.dll", - "lib/netstandard2.1/TDengine.dll", - "tdengine.connector.3.1.3.nupkg.sha512", - "tdengine.connector.nuspec" - ] - } - }, - "projectFileDependencyGroups": { - "net6.0": [ - "TDengine.Connector >= 3.1.*" - ] - }, - "packageFolders": { - "/root/.nuget/packages/": {} - }, - "project": { - "version": "1.0.0", - "restore": { - "projectUniqueName": "/mnt/e/github/TDengine/docs/examples/csharp/nativesml/nativesml.csproj", - "projectName": "nativesml", - "projectPath": "/mnt/e/github/TDengine/docs/examples/csharp/nativesml/nativesml.csproj", - "packagesPath": "/root/.nuget/packages/", - "outputPath": "/mnt/e/github/TDengine/docs/examples/csharp/nativesml/obj/", - "projectStyle": "PackageReference", - "configFilePaths": [ - "/root/.nuget/NuGet/NuGet.Config" - ], - "originalTargetFrameworks": [ - "net6.0" - ], - "sources": { - "https://api.nuget.org/v3/index.json": {} - }, - "frameworks": { - "net6.0": { - "targetAlias": "net6.0", - "projectReferences": {} - } - }, - "warningProperties": { - "warnAsError": [ - "NU1605" - ] - } - }, - "frameworks": { - "net6.0": { - "targetAlias": "net6.0", - "dependencies": { - "TDengine.Connector": { - "target": "Package", - "version": "[3.1.*, )" - } - }, - "imports": [ - "net461", - "net462", - "net47", - "net471", - "net472", - "net48", - "net481" - ], - "assetTargetFallback": true, - "warn": true, - "frameworkReferences": { - "Microsoft.NETCore.App": { - "privateAssets": "all" - } - }, - "runtimeIdentifierGraphPath": "/root/.dotnet/sdk/8.0.100/RuntimeIdentifierGraph.json" - } - } - } -} \ No newline at end of file diff --git a/docs/examples/csharp/nativesml/obj/project.nuget.cache b/docs/examples/csharp/nativesml/obj/project.nuget.cache deleted file mode 100644 index 3c34e78160..0000000000 --- a/docs/examples/csharp/nativesml/obj/project.nuget.cache +++ /dev/null @@ -1,11 +0,0 @@ -{ - "version": 2, - "dgSpecHash": "xbVzGVQru/qLTE5UBOQoTSR5C+6GFj/M4fcB1h/3W6PsWOVoFQLbV4fwAAKt5f5BKxrV1phiwzm2zGYK0fpXBQ==", - "success": true, - "projectFilePath": "/mnt/e/github/TDengine/docs/examples/csharp/nativesml/nativesml.csproj", - "expectedPackageFiles": [ - "/root/.nuget/packages/newtonsoft.json/13.0.3/newtonsoft.json.13.0.3.nupkg.sha512", - "/root/.nuget/packages/tdengine.connector/3.1.3/tdengine.connector.3.1.3.nupkg.sha512" - ], - "logs": [] -} \ No newline at end of file diff --git a/docs/examples/csharp/nativesml/obj/project.packagespec.json b/docs/examples/csharp/nativesml/obj/project.packagespec.json deleted file mode 100644 index 8c110899d3..0000000000 --- a/docs/examples/csharp/nativesml/obj/project.packagespec.json +++ /dev/null @@ -1 +0,0 @@ -"restore":{"projectUniqueName":"E:\\github\\TDengine\\docs\\examples\\csharp\\nativesml\\nativesml.csproj","projectName":"nativesml","projectPath":"E:\\github\\TDengine\\docs\\examples\\csharp\\nativesml\\nativesml.csproj","outputPath":"E:\\github\\TDengine\\docs\\examples\\csharp\\nativesml\\obj\\","projectStyle":"PackageReference","originalTargetFrameworks":["net6.0"],"sources":{"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\":{},"E:\\github\\taos-connector-dotnet\\src\\resource":{},"https://api.nuget.org/v3/index.json":{}},"frameworks":{"net6.0":{"targetAlias":"net6.0","projectReferences":{}}},"warningProperties":{"warnAsError":["NU1605"]}}"frameworks":{"net6.0":{"targetAlias":"net6.0","dependencies":{"TDengine.Connector":{"target":"Package","version":"[3.1.*, )"}},"imports":["net461","net462","net47","net471","net472","net48","net481"],"assetTargetFallback":true,"warn":true,"frameworkReferences":{"Microsoft.NETCore.App":{"privateAssets":"all"}},"runtimeIdentifierGraphPath":"C:\\Program Files\\dotnet\\sdk\\8.0.202\\RuntimeIdentifierGraph.json"}} \ No newline at end of file diff --git a/docs/examples/csharp/nativesml/obj/rider.project.model.nuget.info b/docs/examples/csharp/nativesml/obj/rider.project.model.nuget.info deleted file mode 100644 index c922ea143f..0000000000 --- a/docs/examples/csharp/nativesml/obj/rider.project.model.nuget.info +++ /dev/null @@ -1 +0,0 @@ -17225691407520754 \ No newline at end of file diff --git a/docs/examples/csharp/nativesml/obj/rider.project.restore.info b/docs/examples/csharp/nativesml/obj/rider.project.restore.info deleted file mode 100644 index 7559664705..0000000000 --- a/docs/examples/csharp/nativesml/obj/rider.project.restore.info +++ /dev/null @@ -1 +0,0 @@ -17225689181017775 \ No newline at end of file diff --git a/docs/examples/csharp/optsJSON/Program.cs b/docs/examples/csharp/optsJSON/Program.cs index 747d89c0d3..d9b936745e 100644 --- a/docs/examples/csharp/optsJSON/Program.cs +++ b/docs/examples/csharp/optsJSON/Program.cs @@ -42,13 +42,13 @@ namespace TDengineExample catch (TDengineError e) { // handle TDengine error - Console.WriteLine(e.Message); + Console.WriteLine("Failed to insert data with schemaless; ErrCode:" + e.Code + "; ErrMessage: " + e.Error); throw; } catch (Exception e) { // handle other exceptions - Console.WriteLine(e.Message); + Console.WriteLine("Failed to insert data with schemaless; Err:" + e.Message); throw; } // ANCHOR_END: main diff --git a/docs/examples/csharp/sqlInsert/Program.cs b/docs/examples/csharp/sqlInsert/Program.cs index 0ac8d55c5e..d84e4b146b 100644 --- a/docs/examples/csharp/sqlInsert/Program.cs +++ b/docs/examples/csharp/sqlInsert/Program.cs @@ -17,6 +17,7 @@ namespace TDengineExample CreateDatabaseAndTable(client); InsertData(client); QueryData(client); + QueryWithReqId(client); } } catch (TDengineError e) @@ -49,13 +50,13 @@ namespace TDengineExample catch (TDengineError e) { // handle TDengine error - Console.WriteLine(e.Message); + Console.WriteLine("Failed to create db and table; ErrCode:" + e.Code + "; ErrMessage: " + e.Error); throw; } catch (Exception e) { // handle other exceptions - Console.WriteLine(e.Message); + Console.WriteLine("Failed to create db and table; Err:" + e.Message); throw; } // ANCHOR_END: create_db_and_table @@ -76,27 +77,27 @@ namespace TDengineExample "power.d1002 USING power.meters TAGS(3, 'California.SanFrancisco') " + "VALUES " + "(NOW + 1a, 10.30000, 218, 0.25000) "; - var affectedRows = client.Exec(insertQuery); - Console.WriteLine("inserted into " + affectedRows + " rows to power.meters successfully."); + var affectedRows = client.Exec(insertQuery); + Console.WriteLine("insert " + affectedRows + " rows to power.meters successfully."); } catch (TDengineError e) { // handle TDengine error - Console.WriteLine(e.Message); + Console.WriteLine("Failed to insert data to power.meters; ErrCode:" + e.Code + "; ErrMessage: " + e.Error); throw; } catch (Exception e) { // handle other exceptions - Console.WriteLine(e.Message); + Console.WriteLine("Failed to insert data to power.meters; Err:" + e.Message); throw; } // ANCHOR_END: insert_data } - + private static void QueryData(ITDengineClient client) { - // ANCHOR: query_data + // ANCHOR: select_data try { // query data @@ -108,23 +109,59 @@ namespace TDengineExample var ts = (DateTime)rows.GetValue(0); var current = (float)rows.GetValue(1); var location = Encoding.UTF8.GetString((byte[])rows.GetValue(2)); - Console.WriteLine($"ts: {ts:yyyy-MM-dd HH:mm:ss.fff}, current: {current}, location: {location}"); + Console.WriteLine( + $"ts: {ts:yyyy-MM-dd HH:mm:ss.fff}, current: {current}, location: {location}"); } } } catch (TDengineError e) { // handle TDengine error - Console.WriteLine(e.Message); + Console.WriteLine("Failed to query data from power.meters; ErrCode:" + e.Code + "; ErrMessage: " + e.Error); throw; } catch (Exception e) { // handle other exceptions - Console.WriteLine(e.Message); + Console.WriteLine("Failed to query data from power.meters; Err:" + e.Message); throw; } - // ANCHOR_END: query_data + // ANCHOR_END: select_data + } + + private static void QueryWithReqId(ITDengineClient client) + { + // ANCHOR: query_id + try + { + // query data + var query = "SELECT ts, current, location FROM power.meters limit 1"; + // query with request id 3 + using (var rows = client.Query(query,3)) + { + while (rows.Read()) + { + var ts = (DateTime)rows.GetValue(0); + var current = (float)rows.GetValue(1); + var location = Encoding.UTF8.GetString((byte[])rows.GetValue(2)); + Console.WriteLine( + $"ts: {ts:yyyy-MM-dd HH:mm:ss.fff}, current: {current}, location: {location}"); + } + } + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine("Failed to execute sql with reqId; ErrCode:" + e.Code + "; ErrMessage: " + e.Error); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine("Failed to execute sql with reqId; Err:" + e.Message); + throw; + } + // ANCHOR_END: query_id } } } \ No newline at end of file diff --git a/docs/examples/csharp/stmtInsert/Program.cs b/docs/examples/csharp/stmtInsert/Program.cs index 5b4cf2677c..161682b19e 100644 --- a/docs/examples/csharp/stmtInsert/Program.cs +++ b/docs/examples/csharp/stmtInsert/Program.cs @@ -61,13 +61,13 @@ namespace TDengineExample catch (TDengineError e) { // handle TDengine error - Console.WriteLine(e.Message); + Console.WriteLine("Failed to insert to table meters using stmt; ErrCode:" + e.Code + "; ErrMessage: " + e.Error); throw; } catch (Exception e) { // handle other exceptions - Console.WriteLine(e.Message); + Console.WriteLine("Failed to insert to table meters using stmt; Err:" + e.Message); throw; } } diff --git a/docs/examples/csharp/subscribe/Program.cs b/docs/examples/csharp/subscribe/Program.cs index 80e25f1acf..4798877440 100644 --- a/docs/examples/csharp/subscribe/Program.cs +++ b/docs/examples/csharp/subscribe/Program.cs @@ -71,8 +71,8 @@ namespace TMQExample { "msg.with.table.name", "true" }, { "enable.auto.commit", "true" }, { "auto.commit.interval.ms", "1000" }, - { "group.id", "group2" }, - { "client.id", "1" }, + { "group.id", "group1" }, + { "client.id", "client1" }, { "td.connect.ip", "127.0.0.1" }, { "td.connect.user", "root" }, { "td.connect.pass", "taosdata" }, @@ -86,13 +86,13 @@ namespace TMQExample catch (TDengineError e) { // handle TDengine error - Console.WriteLine(e.Message); + Console.WriteLine("Failed to create consumer; ErrCode:" + e.Code + "; ErrMessage: " + e.Error); throw; } catch (Exception e) { // handle other exceptions - Console.WriteLine(e.Message); + Console.WriteLine("Failed to create consumer; Err:" + e.Message); throw; } @@ -117,7 +117,7 @@ namespace TMQExample { // handle message Console.WriteLine( - $"message {{{((DateTime)message.Value["ts"]).ToString("yyyy-MM-dd HH:mm:ss.fff")}, " + + $"data {{{((DateTime)message.Value["ts"]).ToString("yyyy-MM-dd HH:mm:ss.fff")}, " + $"{message.Value["current"]}, {message.Value["voltage"]}, {message.Value["phase"]}}}"); } } @@ -126,13 +126,13 @@ namespace TMQExample catch (TDengineError e) { // handle TDengine error - Console.WriteLine(e.Message); + Console.WriteLine("Failed to poll data; ErrCode:" + e.Code + "; ErrMessage: " + e.Error); throw; } catch (Exception e) { // handle other exceptions - Console.WriteLine(e.Message); + Console.WriteLine("Failed to poll data; Err:" + e.Message); throw; } // ANCHOR_END: subscribe @@ -150,17 +150,35 @@ namespace TMQExample { consumer.Seek(new TopicPartitionOffset(topicPartition.Topic, topicPartition.Partition, 0)); } + Console.WriteLine("assignment seek to beginning successfully"); + // poll data again + for (int i = 0; i < 50; i++) + { + // consume message with using block to ensure the result is disposed + using (var cr = consumer.Consume(100)) + { + if (cr == null) continue; + foreach (var message in cr.Message) + { + // handle message + Console.WriteLine( + $"second data polled: {{{((DateTime)message.Value["ts"]).ToString("yyyy-MM-dd HH:mm:ss.fff")}, " + + $"{message.Value["current"]}, {message.Value["voltage"]}, {message.Value["phase"]}}}"); + } + break; + } + } } catch (TDengineError e) { // handle TDengine error - Console.WriteLine(e.Message); + Console.WriteLine("Failed to seek; ErrCode:" + e.Code + "; ErrMessage: " + e.Error); throw; } catch (Exception e) { // handle other exceptions - Console.WriteLine(e.Message); + Console.WriteLine("Failed to seek; Err:" + e.Message); throw; } // ANCHOR_END: seek @@ -187,13 +205,13 @@ namespace TMQExample catch (TDengineError e) { // handle TDengine error - Console.WriteLine(e.Message); + Console.WriteLine("Failed to commit offset; ErrCode:" + e.Code + "; ErrMessage: " + e.Error); throw; } catch (Exception e) { // handle other exceptions - Console.WriteLine(e.Message); + Console.WriteLine("Failed to commit offset; Err:" + e.Message); throw; } } @@ -207,21 +225,24 @@ namespace TMQExample { // unsubscribe consumer.Unsubscribe(); - // close consumer - consumer.Close(); } catch (TDengineError e) { // handle TDengine error - Console.WriteLine(e.Message); + Console.WriteLine("Failed to unsubscribe consumer; ErrCode:" + e.Code + "; ErrMessage: " + e.Error); throw; } catch (Exception e) { // handle other exceptions - Console.WriteLine(e.Message); + Console.WriteLine("Failed to unsubscribe consumer; Err:" + e.Message); throw; } + finally + { + // close consumer + consumer.Close(); + } // ANCHOR_END: close } } diff --git a/docs/examples/csharp/wsConnect/Program.cs b/docs/examples/csharp/wsConnect/Program.cs index c7423969d8..67e763e119 100644 --- a/docs/examples/csharp/wsConnect/Program.cs +++ b/docs/examples/csharp/wsConnect/Program.cs @@ -9,27 +9,29 @@ namespace Examples // ANCHOR: main static void Main(string[] args) { + var connectionString = + "protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata"; try { // Connect to TDengine server using WebSocket - var builder = new ConnectionStringBuilder( - "protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata"); + var builder = new ConnectionStringBuilder(connectionString); // Open connection with using block, it will close the connection automatically using (var client = DbDriver.Open(builder)) { - Console.WriteLine("connected"); + Console.WriteLine("Connected to " + connectionString + " successfully."); } } catch (TDengineError e) { // handle TDengine error - Console.WriteLine(e.Message); + Console.WriteLine("Failed to connect to " + connectionString + "; ErrCode:" + e.Code + + "; ErrMessage: " + e.Error); throw; } catch (Exception e) { // handle other exceptions - Console.WriteLine(e.Message); + Console.WriteLine("Failed to connect to " + connectionString + "; Err:" + e.Message); throw; } } diff --git a/docs/examples/csharp/wsInsert/Program.cs b/docs/examples/csharp/wsInsert/Program.cs index d393b775ba..06e3dbe5e8 100644 --- a/docs/examples/csharp/wsInsert/Program.cs +++ b/docs/examples/csharp/wsInsert/Program.cs @@ -50,13 +50,13 @@ namespace Examples catch (TDengineError e) { // handle TDengine error - Console.WriteLine(e.Message); + Console.WriteLine("Failed to create db and table; ErrCode:" + e.Code + "; ErrMessage: " + e.Error); throw; } catch (Exception e) { // handle other exceptions - Console.WriteLine(e.Message); + Console.WriteLine("Failed to create db and table; Err:" + e.Message); throw; } // ANCHOR_END: create_db_and_table @@ -78,18 +78,18 @@ namespace Examples "VALUES " + "(NOW + 1a, 10.30000, 218, 0.25000) "; var affectedRows = client.Exec(insertQuery); - Console.WriteLine("inserted " + affectedRows + " rows to power.meters successfully."); + Console.WriteLine("insert " + affectedRows + " rows to power.meters successfully."); } catch (TDengineError e) { // handle TDengine error - Console.WriteLine(e.Message); + Console.WriteLine("Failed to insert data to power.meters; ErrCode:" + e.Code + "; ErrMessage: " + e.Error); throw; } catch (Exception e) { // handle other exceptions - Console.WriteLine(e.Message); + Console.WriteLine("Failed to insert data to power.meters; Err:" + e.Message); throw; } // ANCHOR_END: insert_data @@ -117,13 +117,13 @@ namespace Examples catch (TDengineError e) { // handle TDengine error - Console.WriteLine(e.Message); + Console.WriteLine("Failed to query data from power.meters; ErrCode:" + e.Code + "; ErrMessage: " + e.Error); throw; } catch (Exception e) { // handle other exceptions - Console.WriteLine(e.Message); + Console.WriteLine("Failed to query data from power.meters; Err:" + e.Message); throw; } // ANCHOR_END: select_data @@ -136,8 +136,8 @@ namespace Examples { // query data var query = "SELECT ts, current, location FROM power.meters limit 1"; - // query with request id 1 - using (var rows = client.Query(query,1)) + // query with request id 3 + using (var rows = client.Query(query,3)) { while (rows.Read()) { @@ -152,13 +152,13 @@ namespace Examples catch (TDengineError e) { // handle TDengine error - Console.WriteLine(e.Message); + Console.WriteLine("Failed to execute sql with reqId; ErrCode:" + e.Code + "; ErrMessage: " + e.Error); throw; } catch (Exception e) { // handle other exceptions - Console.WriteLine(e.Message); + Console.WriteLine("Failed to execute sql with reqId; Err:" + e.Message); throw; } // ANCHOR_END: query_id diff --git a/docs/examples/csharp/wsStmt/Program.cs b/docs/examples/csharp/wsStmt/Program.cs index dfc98d17d6..139a423388 100644 --- a/docs/examples/csharp/wsStmt/Program.cs +++ b/docs/examples/csharp/wsStmt/Program.cs @@ -62,13 +62,13 @@ namespace Examples catch (TDengineError e) { // handle TDengine error - Console.WriteLine(e.Message); + Console.WriteLine("Failed to insert to table meters using stmt; ErrCode:" + e.Code + "; ErrMessage: " + e.Error); throw; } catch (Exception e) { // handle other exceptions - Console.WriteLine(e.Message); + Console.WriteLine("Failed to insert to table meters using stmt; Err:" + e.Message); throw; } } diff --git a/docs/examples/csharp/wssml/Program.cs b/docs/examples/csharp/wssml/Program.cs index 5c47c6651b..1eac06ed08 100644 --- a/docs/examples/csharp/wssml/Program.cs +++ b/docs/examples/csharp/wssml/Program.cs @@ -42,13 +42,13 @@ namespace TDengineExample catch (TDengineError e) { // handle TDengine error - Console.WriteLine(e.Message); + Console.WriteLine("Failed to insert data with schemaless; ErrCode:" + e.Code + "; ErrMessage: " + e.Error); throw; } catch (Exception e) { // handle other exceptions - Console.WriteLine(e.Message); + Console.WriteLine("Failed to insert data with schemaless; Err:" + e.Message); throw; } } diff --git a/docs/examples/csharp/wssml/obj/project.assets.json b/docs/examples/csharp/wssml/obj/project.assets.json deleted file mode 100644 index a3062a28a9..0000000000 --- a/docs/examples/csharp/wssml/obj/project.assets.json +++ /dev/null @@ -1,149 +0,0 @@ -{ - "version": 3, - "targets": { - "net6.0": { - "Newtonsoft.Json/13.0.3": { - "type": "package", - "compile": { - "lib/net6.0/Newtonsoft.Json.dll": { - "related": ".xml" - } - }, - "runtime": { - "lib/net6.0/Newtonsoft.Json.dll": { - "related": ".xml" - } - } - }, - "TDengine.Connector/3.1.3": { - "type": "package", - "dependencies": { - "Newtonsoft.Json": "13.0.3" - }, - "compile": { - "lib/net6.0/TDengine.dll": {} - }, - "runtime": { - "lib/net6.0/TDengine.dll": {} - } - } - } - }, - "libraries": { - "Newtonsoft.Json/13.0.3": { - "sha512": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==", - "type": "package", - "path": "newtonsoft.json/13.0.3", - "files": [ - ".nupkg.metadata", - ".signature.p7s", - "LICENSE.md", - "README.md", - "lib/net20/Newtonsoft.Json.dll", - "lib/net20/Newtonsoft.Json.xml", - "lib/net35/Newtonsoft.Json.dll", - "lib/net35/Newtonsoft.Json.xml", - "lib/net40/Newtonsoft.Json.dll", - "lib/net40/Newtonsoft.Json.xml", - "lib/net45/Newtonsoft.Json.dll", - "lib/net45/Newtonsoft.Json.xml", - "lib/net6.0/Newtonsoft.Json.dll", - "lib/net6.0/Newtonsoft.Json.xml", - "lib/netstandard1.0/Newtonsoft.Json.dll", - "lib/netstandard1.0/Newtonsoft.Json.xml", - "lib/netstandard1.3/Newtonsoft.Json.dll", - "lib/netstandard1.3/Newtonsoft.Json.xml", - "lib/netstandard2.0/Newtonsoft.Json.dll", - "lib/netstandard2.0/Newtonsoft.Json.xml", - "newtonsoft.json.13.0.3.nupkg.sha512", - "newtonsoft.json.nuspec", - "packageIcon.png" - ] - }, - "TDengine.Connector/3.1.3": { - "sha512": "dDX+Oex4I0X9yCalU0/YyUN0ecy+8X5xj6N8CoqeLrU6ICYDZgilSGQK9Fh3qmLobhGQvOJWwDpoO73rryHU5Q==", - "type": "package", - "path": "tdengine.connector/3.1.3", - "files": [ - ".nupkg.metadata", - "docs/README.md", - "image/logo.jpg", - "lib/net45/TDengine.dll", - "lib/net451/TDengine.dll", - "lib/net5.0/TDengine.dll", - "lib/net6.0/TDengine.dll", - "lib/netstandard2.0/TDengine.dll", - "lib/netstandard2.1/TDengine.dll", - "tdengine.connector.3.1.3.nupkg.sha512", - "tdengine.connector.nuspec" - ] - } - }, - "projectFileDependencyGroups": { - "net6.0": [ - "TDengine.Connector >= 3.1.*" - ] - }, - "packageFolders": { - "/root/.nuget/packages/": {} - }, - "project": { - "version": "1.0.0", - "restore": { - "projectUniqueName": "/mnt/e/github/TDengine/docs/examples/csharp/wssml/wssml.csproj", - "projectName": "wssml", - "projectPath": "/mnt/e/github/TDengine/docs/examples/csharp/wssml/wssml.csproj", - "packagesPath": "/root/.nuget/packages/", - "outputPath": "/mnt/e/github/TDengine/docs/examples/csharp/wssml/obj/", - "projectStyle": "PackageReference", - "configFilePaths": [ - "/root/.nuget/NuGet/NuGet.Config" - ], - "originalTargetFrameworks": [ - "net6.0" - ], - "sources": { - "https://api.nuget.org/v3/index.json": {} - }, - "frameworks": { - "net6.0": { - "targetAlias": "net6.0", - "projectReferences": {} - } - }, - "warningProperties": { - "warnAsError": [ - "NU1605" - ] - } - }, - "frameworks": { - "net6.0": { - "targetAlias": "net6.0", - "dependencies": { - "TDengine.Connector": { - "target": "Package", - "version": "[3.1.*, )" - } - }, - "imports": [ - "net461", - "net462", - "net47", - "net471", - "net472", - "net48", - "net481" - ], - "assetTargetFallback": true, - "warn": true, - "frameworkReferences": { - "Microsoft.NETCore.App": { - "privateAssets": "all" - } - }, - "runtimeIdentifierGraphPath": "/root/.dotnet/sdk/8.0.100/RuntimeIdentifierGraph.json" - } - } - } -} \ No newline at end of file diff --git a/docs/examples/csharp/wssml/obj/project.nuget.cache b/docs/examples/csharp/wssml/obj/project.nuget.cache deleted file mode 100644 index 140c7e62da..0000000000 --- a/docs/examples/csharp/wssml/obj/project.nuget.cache +++ /dev/null @@ -1,11 +0,0 @@ -{ - "version": 2, - "dgSpecHash": "f/iAhsDLFU7jI95wf6NFa1XHue7HQsgzzqr1jqfMTnrejkprbps/2toSr4j9kUyRUVdJNr7/TtdHhEsxEhKo+A==", - "success": true, - "projectFilePath": "/mnt/e/github/TDengine/docs/examples/csharp/wssml/wssml.csproj", - "expectedPackageFiles": [ - "/root/.nuget/packages/newtonsoft.json/13.0.3/newtonsoft.json.13.0.3.nupkg.sha512", - "/root/.nuget/packages/tdengine.connector/3.1.3/tdengine.connector.3.1.3.nupkg.sha512" - ], - "logs": [] -} \ No newline at end of file diff --git a/docs/examples/csharp/wssml/obj/project.packagespec.json b/docs/examples/csharp/wssml/obj/project.packagespec.json deleted file mode 100644 index 587dbcda23..0000000000 --- a/docs/examples/csharp/wssml/obj/project.packagespec.json +++ /dev/null @@ -1 +0,0 @@ -"restore":{"projectUniqueName":"E:\\github\\TDengine\\docs\\examples\\csharp\\wssml\\wssml.csproj","projectName":"wssml","projectPath":"E:\\github\\TDengine\\docs\\examples\\csharp\\wssml\\wssml.csproj","outputPath":"E:\\github\\TDengine\\docs\\examples\\csharp\\wssml\\obj\\","projectStyle":"PackageReference","originalTargetFrameworks":["net6.0"],"sources":{"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\":{},"E:\\github\\taos-connector-dotnet\\src\\resource":{},"https://api.nuget.org/v3/index.json":{}},"frameworks":{"net6.0":{"targetAlias":"net6.0","projectReferences":{}}},"warningProperties":{"warnAsError":["NU1605"]}}"frameworks":{"net6.0":{"targetAlias":"net6.0","dependencies":{"TDengine.Connector":{"target":"Package","version":"[3.1.*, )"}},"imports":["net461","net462","net47","net471","net472","net48","net481"],"assetTargetFallback":true,"warn":true,"frameworkReferences":{"Microsoft.NETCore.App":{"privateAssets":"all"}},"runtimeIdentifierGraphPath":"C:\\Program Files\\dotnet\\sdk\\8.0.202\\RuntimeIdentifierGraph.json"}} \ No newline at end of file diff --git a/docs/examples/csharp/wssml/obj/rider.project.model.nuget.info b/docs/examples/csharp/wssml/obj/rider.project.model.nuget.info deleted file mode 100644 index 8c12f7e019..0000000000 --- a/docs/examples/csharp/wssml/obj/rider.project.model.nuget.info +++ /dev/null @@ -1 +0,0 @@ -17225691310239873 \ No newline at end of file diff --git a/docs/examples/csharp/wssml/obj/rider.project.restore.info b/docs/examples/csharp/wssml/obj/rider.project.restore.info deleted file mode 100644 index b11c9dec26..0000000000 --- a/docs/examples/csharp/wssml/obj/rider.project.restore.info +++ /dev/null @@ -1 +0,0 @@ -17225689180359712 \ No newline at end of file diff --git a/docs/examples/csharp/wssml/obj/wssml.csproj.nuget.dgspec.json b/docs/examples/csharp/wssml/obj/wssml.csproj.nuget.dgspec.json deleted file mode 100644 index 314b2831c6..0000000000 --- a/docs/examples/csharp/wssml/obj/wssml.csproj.nuget.dgspec.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "format": 1, - "restore": { - "/mnt/e/github/TDengine/docs/examples/csharp/wssml/wssml.csproj": {} - }, - "projects": { - "/mnt/e/github/TDengine/docs/examples/csharp/wssml/wssml.csproj": { - "version": "1.0.0", - "restore": { - "projectUniqueName": "/mnt/e/github/TDengine/docs/examples/csharp/wssml/wssml.csproj", - "projectName": "wssml", - "projectPath": "/mnt/e/github/TDengine/docs/examples/csharp/wssml/wssml.csproj", - "packagesPath": "/root/.nuget/packages/", - "outputPath": "/mnt/e/github/TDengine/docs/examples/csharp/wssml/obj/", - "projectStyle": "PackageReference", - "configFilePaths": [ - "/root/.nuget/NuGet/NuGet.Config" - ], - "originalTargetFrameworks": [ - "net6.0" - ], - "sources": { - "https://api.nuget.org/v3/index.json": {} - }, - "frameworks": { - "net6.0": { - "targetAlias": "net6.0", - "projectReferences": {} - } - }, - "warningProperties": { - "warnAsError": [ - "NU1605" - ] - } - }, - "frameworks": { - "net6.0": { - "targetAlias": "net6.0", - "dependencies": { - "TDengine.Connector": { - "target": "Package", - "version": "[3.1.*, )" - } - }, - "imports": [ - "net461", - "net462", - "net47", - "net471", - "net472", - "net48", - "net481" - ], - "assetTargetFallback": true, - "warn": true, - "frameworkReferences": { - "Microsoft.NETCore.App": { - "privateAssets": "all" - } - }, - "runtimeIdentifierGraphPath": "/root/.dotnet/sdk/8.0.100/RuntimeIdentifierGraph.json" - } - } - } - } -} \ No newline at end of file diff --git a/docs/examples/csharp/wssml/obj/wssml.csproj.nuget.g.props b/docs/examples/csharp/wssml/obj/wssml.csproj.nuget.g.props deleted file mode 100644 index a270b60d2c..0000000000 --- a/docs/examples/csharp/wssml/obj/wssml.csproj.nuget.g.props +++ /dev/null @@ -1,15 +0,0 @@ - - - - True - NuGet - $(MSBuildThisFileDirectory)project.assets.json - /root/.nuget/packages/ - /root/.nuget/packages/ - PackageReference - 6.8.0 - - - - - \ No newline at end of file diff --git a/docs/examples/csharp/wssml/obj/wssml.csproj.nuget.g.targets b/docs/examples/csharp/wssml/obj/wssml.csproj.nuget.g.targets deleted file mode 100644 index 35a7576c5a..0000000000 --- a/docs/examples/csharp/wssml/obj/wssml.csproj.nuget.g.targets +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/docs/examples/csharp/wssubscribe/Program.cs b/docs/examples/csharp/wssubscribe/Program.cs index 269fc4c732..4f242e12e2 100644 --- a/docs/examples/csharp/wssubscribe/Program.cs +++ b/docs/examples/csharp/wssubscribe/Program.cs @@ -72,8 +72,8 @@ namespace TMQExample { "msg.with.table.name", "true" }, { "enable.auto.commit", "true" }, { "auto.commit.interval.ms", "1000" }, - { "group.id", "group2" }, - { "client.id", "1" }, + { "group.id", "group1" }, + { "client.id", "client1" }, { "td.connect.ip", "127.0.0.1" }, { "td.connect.user", "root" }, { "td.connect.pass", "taosdata" }, @@ -87,13 +87,13 @@ namespace TMQExample catch (TDengineError e) { // handle TDengine error - Console.WriteLine(e.Message); + Console.WriteLine("Failed to create consumer; ErrCode:" + e.Code + "; ErrMessage: " + e.Error); throw; } catch (Exception e) { // handle other exceptions - Console.WriteLine(e.Message); + Console.WriteLine("Failed to create consumer; Err:" + e.Message); throw; } @@ -118,7 +118,7 @@ namespace TMQExample { // handle message Console.WriteLine( - $"message {{{((DateTime)message.Value["ts"]).ToString("yyyy-MM-dd HH:mm:ss.fff")}, " + + $"data {{{((DateTime)message.Value["ts"]).ToString("yyyy-MM-dd HH:mm:ss.fff")}, " + $"{message.Value["current"]}, {message.Value["voltage"]}, {message.Value["phase"]}}}"); } } @@ -127,13 +127,13 @@ namespace TMQExample catch (TDengineError e) { // handle TDengine error - Console.WriteLine(e.Message); + Console.WriteLine("Failed to poll data; ErrCode:" + e.Code + "; ErrMessage: " + e.Error); throw; } catch (Exception e) { // handle other exceptions - Console.WriteLine(e.Message); + Console.WriteLine("Failed to poll data; Err:" + e.Message); throw; } // ANCHOR_END: subscribe @@ -151,17 +151,35 @@ namespace TMQExample { consumer.Seek(new TopicPartitionOffset(topicPartition.Topic, topicPartition.Partition, 0)); } + Console.WriteLine("assignment seek to beginning successfully"); + // poll data again + for (int i = 0; i < 50; i++) + { + // consume message with using block to ensure the result is disposed + using (var cr = consumer.Consume(100)) + { + if (cr == null) continue; + foreach (var message in cr.Message) + { + // handle message + Console.WriteLine( + $"second data polled: {{{((DateTime)message.Value["ts"]).ToString("yyyy-MM-dd HH:mm:ss.fff")}, " + + $"{message.Value["current"]}, {message.Value["voltage"]}, {message.Value["phase"]}}}"); + } + break; + } + } } catch (TDengineError e) { // handle TDengine error - Console.WriteLine(e.Message); + Console.WriteLine("Failed to seek; ErrCode:" + e.Code + "; ErrMessage: " + e.Error); throw; } catch (Exception e) { // handle other exceptions - Console.WriteLine(e.Message); + Console.WriteLine("Failed to seek; Err:" + e.Message); throw; } // ANCHOR_END: seek @@ -188,13 +206,13 @@ namespace TMQExample catch (TDengineError e) { // handle TDengine error - Console.WriteLine(e.Message); + Console.WriteLine("Failed to commit offset; ErrCode:" + e.Code + "; ErrMessage: " + e.Error); throw; } catch (Exception e) { // handle other exceptions - Console.WriteLine(e.Message); + Console.WriteLine("Failed to commit offset; Err:" + e.Message); throw; } } @@ -208,21 +226,24 @@ namespace TMQExample { // unsubscribe consumer.Unsubscribe(); - // close consumer - consumer.Close(); } catch (TDengineError e) { // handle TDengine error - Console.WriteLine(e.Message); + Console.WriteLine("Failed to unsubscribe consumer; ErrCode:" + e.Code + "; ErrMessage: " + e.Error); throw; } catch (Exception e) { // handle other exceptions - Console.WriteLine(e.Message); + Console.WriteLine("Failed to unsubscribe consumer; Err:" + e.Message); throw; } + finally + { + // close consumer + consumer.Close(); + } // ANCHOR_END: close } } diff --git a/docs/examples/csharp/wssubscribe/obj/project.assets.json b/docs/examples/csharp/wssubscribe/obj/project.assets.json deleted file mode 100644 index 8335d20e65..0000000000 --- a/docs/examples/csharp/wssubscribe/obj/project.assets.json +++ /dev/null @@ -1,150 +0,0 @@ -{ - "version": 3, - "targets": { - "net6.0": { - "Newtonsoft.Json/13.0.3": { - "type": "package", - "compile": { - "lib/net6.0/Newtonsoft.Json.dll": { - "related": ".xml" - } - }, - "runtime": { - "lib/net6.0/Newtonsoft.Json.dll": { - "related": ".xml" - } - } - }, - "TDengine.Connector/3.1.3": { - "type": "package", - "dependencies": { - "Newtonsoft.Json": "13.0.3" - }, - "compile": { - "lib/net6.0/TDengine.dll": {} - }, - "runtime": { - "lib/net6.0/TDengine.dll": {} - } - } - } - }, - "libraries": { - "Newtonsoft.Json/13.0.3": { - "sha512": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==", - "type": "package", - "path": "newtonsoft.json/13.0.3", - "files": [ - ".nupkg.metadata", - ".signature.p7s", - "LICENSE.md", - "README.md", - "lib/net20/Newtonsoft.Json.dll", - "lib/net20/Newtonsoft.Json.xml", - "lib/net35/Newtonsoft.Json.dll", - "lib/net35/Newtonsoft.Json.xml", - "lib/net40/Newtonsoft.Json.dll", - "lib/net40/Newtonsoft.Json.xml", - "lib/net45/Newtonsoft.Json.dll", - "lib/net45/Newtonsoft.Json.xml", - "lib/net6.0/Newtonsoft.Json.dll", - "lib/net6.0/Newtonsoft.Json.xml", - "lib/netstandard1.0/Newtonsoft.Json.dll", - "lib/netstandard1.0/Newtonsoft.Json.xml", - "lib/netstandard1.3/Newtonsoft.Json.dll", - "lib/netstandard1.3/Newtonsoft.Json.xml", - "lib/netstandard2.0/Newtonsoft.Json.dll", - "lib/netstandard2.0/Newtonsoft.Json.xml", - "newtonsoft.json.13.0.3.nupkg.sha512", - "newtonsoft.json.nuspec", - "packageIcon.png" - ] - }, - "TDengine.Connector/3.1.3": { - "sha512": "dDX+Oex4I0X9yCalU0/YyUN0ecy+8X5xj6N8CoqeLrU6ICYDZgilSGQK9Fh3qmLobhGQvOJWwDpoO73rryHU5Q==", - "type": "package", - "path": "tdengine.connector/3.1.3", - "files": [ - ".nupkg.metadata", - "docs/README.md", - "image/logo.jpg", - "lib/net45/TDengine.dll", - "lib/net451/TDengine.dll", - "lib/net5.0/TDengine.dll", - "lib/net6.0/TDengine.dll", - "lib/netstandard2.0/TDengine.dll", - "lib/netstandard2.1/TDengine.dll", - "tdengine.connector.3.1.3.nupkg.sha512", - "tdengine.connector.nuspec" - ] - } - }, - "projectFileDependencyGroups": { - "net6.0": [ - "TDengine.Connector >= 3.1.*" - ] - }, - "packageFolders": { - "/root/.nuget/packages/": {} - }, - "project": { - "version": "1.0.0", - "restore": { - "projectUniqueName": "/mnt/e/github/TDengine/docs/examples/csharp/wssubscribe/wssubscribe.csproj", - "projectName": "wssubscribe", - "projectPath": "/mnt/e/github/TDengine/docs/examples/csharp/wssubscribe/wssubscribe.csproj", - "packagesPath": "/root/.nuget/packages/", - "outputPath": "/mnt/e/github/TDengine/docs/examples/csharp/wssubscribe/obj/", - "projectStyle": "PackageReference", - "configFilePaths": [ - "/root/.nuget/NuGet/NuGet.Config" - ], - "originalTargetFrameworks": [ - "net6.0" - ], - "sources": { - "https://api.nuget.org/v3/index.json": {} - }, - "frameworks": { - "net6.0": { - "targetAlias": "net6.0", - "projectReferences": {} - } - }, - "warningProperties": { - "warnAsError": [ - "NU1605" - ] - } - }, - "frameworks": { - "net6.0": { - "targetAlias": "net6.0", - "dependencies": { - "TDengine.Connector": { - "target": "Package", - "version": "[3.1.*, )", - "generatePathProperty": true - } - }, - "imports": [ - "net461", - "net462", - "net47", - "net471", - "net472", - "net48", - "net481" - ], - "assetTargetFallback": true, - "warn": true, - "frameworkReferences": { - "Microsoft.NETCore.App": { - "privateAssets": "all" - } - }, - "runtimeIdentifierGraphPath": "/root/.dotnet/sdk/8.0.100/RuntimeIdentifierGraph.json" - } - } - } -} \ No newline at end of file diff --git a/docs/examples/csharp/wssubscribe/obj/project.nuget.cache b/docs/examples/csharp/wssubscribe/obj/project.nuget.cache deleted file mode 100644 index 07a2d75f6b..0000000000 --- a/docs/examples/csharp/wssubscribe/obj/project.nuget.cache +++ /dev/null @@ -1,11 +0,0 @@ -{ - "version": 2, - "dgSpecHash": "iYS3B811DdocWqUXN2aMJdEwvfDVCixB5mK4XYN+98yFFNdPOU8hN4wQCxaOSFM7xKpvlmJvQPwkMetGBbFO8g==", - "success": true, - "projectFilePath": "/mnt/e/github/TDengine/docs/examples/csharp/wssubscribe/wssubscribe.csproj", - "expectedPackageFiles": [ - "/root/.nuget/packages/newtonsoft.json/13.0.3/newtonsoft.json.13.0.3.nupkg.sha512", - "/root/.nuget/packages/tdengine.connector/3.1.3/tdengine.connector.3.1.3.nupkg.sha512" - ], - "logs": [] -} \ No newline at end of file diff --git a/docs/examples/csharp/wssubscribe/obj/project.packagespec.json b/docs/examples/csharp/wssubscribe/obj/project.packagespec.json deleted file mode 100644 index 319dd58c7f..0000000000 --- a/docs/examples/csharp/wssubscribe/obj/project.packagespec.json +++ /dev/null @@ -1 +0,0 @@ -"restore":{"projectUniqueName":"E:\\github\\TDengine\\docs\\examples\\csharp\\wssubscribe\\wssubscribe.csproj","projectName":"wssubscribe","projectPath":"E:\\github\\TDengine\\docs\\examples\\csharp\\wssubscribe\\wssubscribe.csproj","outputPath":"E:\\github\\TDengine\\docs\\examples\\csharp\\wssubscribe\\obj\\","projectStyle":"PackageReference","originalTargetFrameworks":["net6.0"],"sources":{"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\":{},"E:\\github\\taos-connector-dotnet\\src\\resource":{},"https://api.nuget.org/v3/index.json":{}},"frameworks":{"net6.0":{"targetAlias":"net6.0","projectReferences":{}}},"warningProperties":{"warnAsError":["NU1605"]}}"frameworks":{"net6.0":{"targetAlias":"net6.0","dependencies":{"TDengine.Connector":{"target":"Package","version":"[3.1.*, )","generatePathProperty":true}},"imports":["net461","net462","net47","net471","net472","net48","net481"],"assetTargetFallback":true,"warn":true,"frameworkReferences":{"Microsoft.NETCore.App":{"privateAssets":"all"}},"runtimeIdentifierGraphPath":"C:\\Program Files\\dotnet\\sdk\\8.0.202\\RuntimeIdentifierGraph.json"}} \ No newline at end of file diff --git a/docs/examples/csharp/wssubscribe/obj/rider.project.model.nuget.info b/docs/examples/csharp/wssubscribe/obj/rider.project.model.nuget.info deleted file mode 100644 index 4a9bcd784b..0000000000 --- a/docs/examples/csharp/wssubscribe/obj/rider.project.model.nuget.info +++ /dev/null @@ -1 +0,0 @@ -17225691490262111 \ No newline at end of file diff --git a/docs/examples/csharp/wssubscribe/obj/rider.project.restore.info b/docs/examples/csharp/wssubscribe/obj/rider.project.restore.info deleted file mode 100644 index b8e44bdfbe..0000000000 --- a/docs/examples/csharp/wssubscribe/obj/rider.project.restore.info +++ /dev/null @@ -1 +0,0 @@ -17225689180408669 \ No newline at end of file diff --git a/docs/examples/csharp/wssubscribe/obj/wssubscribe.csproj.nuget.dgspec.json b/docs/examples/csharp/wssubscribe/obj/wssubscribe.csproj.nuget.dgspec.json deleted file mode 100644 index 0825170a7d..0000000000 --- a/docs/examples/csharp/wssubscribe/obj/wssubscribe.csproj.nuget.dgspec.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "format": 1, - "restore": { - "/mnt/e/github/TDengine/docs/examples/csharp/wssubscribe/wssubscribe.csproj": {} - }, - "projects": { - "/mnt/e/github/TDengine/docs/examples/csharp/wssubscribe/wssubscribe.csproj": { - "version": "1.0.0", - "restore": { - "projectUniqueName": "/mnt/e/github/TDengine/docs/examples/csharp/wssubscribe/wssubscribe.csproj", - "projectName": "wssubscribe", - "projectPath": "/mnt/e/github/TDengine/docs/examples/csharp/wssubscribe/wssubscribe.csproj", - "packagesPath": "/root/.nuget/packages/", - "outputPath": "/mnt/e/github/TDengine/docs/examples/csharp/wssubscribe/obj/", - "projectStyle": "PackageReference", - "configFilePaths": [ - "/root/.nuget/NuGet/NuGet.Config" - ], - "originalTargetFrameworks": [ - "net6.0" - ], - "sources": { - "https://api.nuget.org/v3/index.json": {} - }, - "frameworks": { - "net6.0": { - "targetAlias": "net6.0", - "projectReferences": {} - } - }, - "warningProperties": { - "warnAsError": [ - "NU1605" - ] - } - }, - "frameworks": { - "net6.0": { - "targetAlias": "net6.0", - "dependencies": { - "TDengine.Connector": { - "target": "Package", - "version": "[3.1.*, )", - "generatePathProperty": true - } - }, - "imports": [ - "net461", - "net462", - "net47", - "net471", - "net472", - "net48", - "net481" - ], - "assetTargetFallback": true, - "warn": true, - "frameworkReferences": { - "Microsoft.NETCore.App": { - "privateAssets": "all" - } - }, - "runtimeIdentifierGraphPath": "/root/.dotnet/sdk/8.0.100/RuntimeIdentifierGraph.json" - } - } - } - } -} \ No newline at end of file diff --git a/docs/examples/csharp/wssubscribe/obj/wssubscribe.csproj.nuget.g.props b/docs/examples/csharp/wssubscribe/obj/wssubscribe.csproj.nuget.g.props deleted file mode 100644 index 939669445d..0000000000 --- a/docs/examples/csharp/wssubscribe/obj/wssubscribe.csproj.nuget.g.props +++ /dev/null @@ -1,18 +0,0 @@ - - - - True - NuGet - $(MSBuildThisFileDirectory)project.assets.json - /root/.nuget/packages/ - /root/.nuget/packages/ - PackageReference - 6.8.0 - - - - - - /root/.nuget/packages/tdengine.connector/3.1.3 - - \ No newline at end of file diff --git a/docs/examples/csharp/wssubscribe/obj/wssubscribe.csproj.nuget.g.targets b/docs/examples/csharp/wssubscribe/obj/wssubscribe.csproj.nuget.g.targets deleted file mode 100644 index 35a7576c5a..0000000000 --- a/docs/examples/csharp/wssubscribe/obj/wssubscribe.csproj.nuget.g.targets +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/docs/examples/csharp/wssubscribe/wssubscribe.csproj b/docs/examples/csharp/wssubscribe/wssubscribe.csproj index 3a2796a3af..4e27ed1b2d 100644 --- a/docs/examples/csharp/wssubscribe/wssubscribe.csproj +++ b/docs/examples/csharp/wssubscribe/wssubscribe.csproj @@ -7,6 +7,6 @@ enable - + diff --git a/docs/examples/go/connect/cgoexample/main.go b/docs/examples/go/connect/cgoexample/main.go index 9c9b414b47..02dbb6ab85 100644 --- a/docs/examples/go/connect/cgoexample/main.go +++ b/docs/examples/go/connect/cgoexample/main.go @@ -16,8 +16,7 @@ func main() { taos, err := sql.Open("taosSql", taosDSN) if err != nil { log.Fatalln("failed to connect TDengine, err:", err) - return } - fmt.Println("Connected") + fmt.Println("Connected to " + taosDSN + " successfully.") defer taos.Close() } diff --git a/docs/examples/go/connect/connpool/main.go b/docs/examples/go/connect/connpool/main.go index e3058fca3f..e52523a655 100644 --- a/docs/examples/go/connect/connpool/main.go +++ b/docs/examples/go/connect/connpool/main.go @@ -16,7 +16,6 @@ func main() { taos, err := sql.Open("taosSql", taosDSN) if err != nil { log.Fatalln("failed to connect TDengine, err:", err) - return } fmt.Println("Connected") defer taos.Close() diff --git a/docs/examples/go/connect/restexample/main.go b/docs/examples/go/connect/restexample/main.go index ecc5110c60..a76091a4a3 100644 --- a/docs/examples/go/connect/restexample/main.go +++ b/docs/examples/go/connect/restexample/main.go @@ -16,8 +16,7 @@ func main() { taos, err := sql.Open("taosRestful", taosDSN) if err != nil { log.Fatalln("failed to connect TDengine, err:", err) - return } - fmt.Println("Connected") + fmt.Println("Connected to " + taosDSN + " successfully.") defer taos.Close() } diff --git a/docs/examples/go/connect/wsexample/main.go b/docs/examples/go/connect/wsexample/main.go index c815f0aec5..5c5abf0796 100644 --- a/docs/examples/go/connect/wsexample/main.go +++ b/docs/examples/go/connect/wsexample/main.go @@ -16,8 +16,7 @@ func main() { taos, err := sql.Open("taosWS", taosDSN) if err != nil { log.Fatalln("failed to connect TDengine, err:", err) - return } - fmt.Println("Connected") + fmt.Println("Connected to " + taosDSN + " successfully.") defer taos.Close() } diff --git a/docs/examples/go/queryreqid/main.go b/docs/examples/go/queryreqid/main.go index c7dd3d9215..f43a5b5c44 100644 --- a/docs/examples/go/queryreqid/main.go +++ b/docs/examples/go/queryreqid/main.go @@ -4,6 +4,7 @@ import ( "context" "database/sql" "fmt" + "log" "time" _ "github.com/taosdata/driver-go/v3/taosSql" @@ -12,7 +13,7 @@ import ( func main() { db, err := sql.Open("taosSql", "root:taosdata@tcp(localhost:6030)/") if err != nil { - panic(err) + log.Fatal("Open database error: ", err) } defer db.Close() initEnv(db) @@ -22,7 +23,7 @@ func main() { // execute query with context rows, err := db.QueryContext(ctx, "SELECT ts, current, location FROM power.meters limit 1") if err != nil { - panic(err) + log.Fatal("Query error: ", err) } for rows.Next() { var ( @@ -32,7 +33,7 @@ func main() { ) err = rows.Scan(&ts, ¤t, &location) if err != nil { - panic(err) + log.Fatal("Scan error: ", err) } fmt.Printf("ts: %s, current: %f, location: %s\n", ts, current, location) } @@ -42,14 +43,14 @@ func main() { func initEnv(conn *sql.DB) { _, err := conn.Exec("CREATE DATABASE IF NOT EXISTS power") if err != nil { - panic(err) + log.Fatal("Create database error: ", err) } _, err = conn.Exec("CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))") if err != nil { - panic(err) + log.Fatal("Create table error: ", err) } _, err = conn.Exec("INSERT INTO power.d1001 USING power.meters TAGS (2, 'California.SanFrancisco') VALUES (NOW , 10.2, 219, 0.32)") if err != nil { - panic(err) + log.Fatal("Insert data error: ", err) } } diff --git a/docs/examples/go/schemaless/native/main.go b/docs/examples/go/schemaless/native/main.go index b9cd70ef14..acb5b95c89 100644 --- a/docs/examples/go/schemaless/native/main.go +++ b/docs/examples/go/schemaless/native/main.go @@ -1,6 +1,8 @@ package main import ( + "log" + "github.com/taosdata/driver-go/v3/af" ) @@ -12,30 +14,30 @@ func main() { conn, err := af.Open(host, "root", "taosdata", "", 0) if err != nil { - panic(err) + log.Fatal("failed to connect TDengine, err:", err) } defer conn.Close() _, err = conn.Exec("CREATE DATABASE IF NOT EXISTS power") if err != nil { - panic(err) + log.Fatal("failed to create database, err:", err) } _, err = conn.Exec("USE power") if err != nil { - panic(err) + log.Fatal("failed to use database, err:", err) } // insert influxdb line protocol err = conn.InfluxDBInsertLines([]string{lineDemo}, "ms") if err != nil { - panic(err) + log.Fatal("failed to insert influxdb line protocol, err:", err) } // insert opentsdb telnet protocol err = conn.OpenTSDBInsertTelnetLines([]string{telnetDemo}) if err != nil { - panic(err) + log.Fatal("failed to insert opentsdb telnet line protocol, err:", err) } // insert opentsdb json protocol err = conn.OpenTSDBInsertJsonPayload(jsonDemo) if err != nil { - panic(err) + log.Fatal("failed to insert opentsdb json format protocol, err:", err) } } diff --git a/docs/examples/go/schemaless/ws/main.go b/docs/examples/go/schemaless/ws/main.go index c6807f213c..84280fc0fa 100644 --- a/docs/examples/go/schemaless/ws/main.go +++ b/docs/examples/go/schemaless/ws/main.go @@ -19,12 +19,12 @@ func main() { db, err := sql.Open("taosWS", fmt.Sprintf("root:taosdata@ws(%s:6041)/", host)) if err != nil { - log.Fatal(err) + log.Fatal("failed to connect TDengine, err:", err) } defer db.Close() _, err = db.Exec("CREATE DATABASE IF NOT EXISTS power") if err != nil { - log.Fatal(err) + log.Fatal("failed to create database, err:", err) } s, err := schemaless.NewSchemaless(schemaless.NewConfig("ws://localhost:6041", 1, schemaless.SetDb("power"), @@ -32,26 +32,23 @@ func main() { schemaless.SetWriteTimeout(10*time.Second), schemaless.SetUser("root"), schemaless.SetPassword("taosdata"), - schemaless.SetErrorHandler(func(err error) { - log.Fatal(err) - }), )) if err != nil { - panic(err) + log.Fatal("failed to create schemaless connection, err:", err) } // insert influxdb line protocol err = s.Insert(lineDemo, schemaless.InfluxDBLineProtocol, "ms", 0, common.GetReqID()) if err != nil { - panic(err) + log.Fatal("failed to insert influxdb line protocol, err:", err) } // insert opentsdb telnet line protocol err = s.Insert(telnetDemo, schemaless.OpenTSDBTelnetLineProtocol, "ms", 0, common.GetReqID()) if err != nil { - panic(err) + log.Fatal("failed to insert opentsdb telnet line protocol, err:", err) } // insert opentsdb json format protocol err = s.Insert(jsonDemo, schemaless.OpenTSDBJsonFormatProtocol, "s", 0, common.GetReqID()) if err != nil { - panic(err) + log.Fatal("failed to insert opentsdb json format protocol, err:", err) } } diff --git a/docs/examples/go/sqlquery/main.go b/docs/examples/go/sqlquery/main.go index 12e1732b31..19d0029bfa 100644 --- a/docs/examples/go/sqlquery/main.go +++ b/docs/examples/go/sqlquery/main.go @@ -3,6 +3,7 @@ package main import ( "database/sql" "fmt" + "log" "time" _ "github.com/taosdata/driver-go/v3/taosSql" @@ -11,35 +12,35 @@ import ( func main() { db, err := sql.Open("taosSql", "root:taosdata@tcp(localhost:6030)/") if err != nil { - panic(err) + log.Fatal("open database failed:", err) } defer db.Close() // ANCHOR: create_db_and_table // create database res, err := db.Exec("CREATE DATABASE IF NOT EXISTS power") if err != nil { - panic(err) + log.Fatal("create database failed:", err) } affected, err := res.RowsAffected() if err != nil { - panic(err) + log.Fatal("get affected rows failed:", err) } fmt.Println("create database affected:", affected) // use database res, err = db.Exec("USE power") if err != nil { - panic(err) + log.Fatal("use database failed:", err) } affected, err = res.RowsAffected() if err != nil { - panic(err) + log.Fatal("get affected rows failed:", err) } fmt.Println("use database affected:", affected) // create table res, err = db.Exec("CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))") affected, err = res.RowsAffected() if err != nil { - panic(err) + log.Fatal("create table failed:", err) } fmt.Println("create table affected:", affected) // ANCHOR_END: create_db_and_table @@ -56,11 +57,11 @@ func main() { "(NOW + 1a, 10.30000, 218, 0.25000) " res, err = db.Exec(insertQuery) if err != nil { - panic(err) + log.Fatal("insert data failed:", err) } affected, err = res.RowsAffected() if err != nil { - panic(err) + log.Fatal("get affected rows failed:", err) } // you can check affectedRows here fmt.Println("insert data affected:", affected) @@ -69,7 +70,7 @@ func main() { // query data, make sure the database and table are created before rows, err := db.Query("SELECT ts, current, location FROM power.meters limit 100") if err != nil { - panic(err) + log.Fatal("query data failed:", err) } for rows.Next() { var ( @@ -79,7 +80,7 @@ func main() { ) err = rows.Scan(&ts, ¤t, &location) if err != nil { - panic(err) + log.Fatal("scan data failed:", err) } // you can check data here fmt.Printf("ts: %s, current: %f, location: %s\n", ts, current, location) diff --git a/docs/examples/go/stmt/native/main.go b/docs/examples/go/stmt/native/main.go index 63986912da..6fec28969b 100644 --- a/docs/examples/go/stmt/native/main.go +++ b/docs/examples/go/stmt/native/main.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "log" "math/rand" "time" @@ -16,28 +17,28 @@ func main() { numOfRow := 10 db, err := af.Open(host, "root", "taosdata", "", 0) if err != nil { - panic(err) + log.Fatal("failed to connect TDengine, err:", err) } defer db.Close() // prepare database and table _, err = db.Exec("CREATE DATABASE IF NOT EXISTS power") if err != nil { - panic(err) + log.Fatal("failed to create database, err:", err) } _, err = db.Exec("USE power") if err != nil { - panic(err) + log.Fatal("failed to use database, err:", err) } _, err = db.Exec("CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))") if err != nil { - panic(err) + log.Fatal("failed to create table, err:", err) } // prepare statement sql := "INSERT INTO ? USING meters TAGS(?,?) VALUES (?,?,?,?)" stmt := db.Stmt() err = stmt.Prepare(sql) if err != nil { - panic(err) + log.Fatal("failed to prepare statement, err:", err) } for i := 1; i <= numOfSubTable; i++ { tableName := fmt.Sprintf("d_bind_%d", i) @@ -45,7 +46,7 @@ func main() { // set tableName and tags err = stmt.SetTableNameWithTags(tableName, tags) if err != nil { - panic(err) + log.Fatal("failed to set table name and tags, err:", err) } // bind column data current := time.Now() @@ -57,18 +58,18 @@ func main() { AddFloat(rand.Float32()) err = stmt.BindRow(row) if err != nil { - panic(err) + log.Fatal("failed to bind row, err:", err) } } // add batch err = stmt.AddBatch() if err != nil { - panic(err) + log.Fatal("failed to add batch, err:", err) } // execute batch err = stmt.Execute() if err != nil { - panic(err) + log.Fatal("failed to execute batch, err:", err) } // get affected rows affected := stmt.GetAffectedRows() @@ -77,6 +78,6 @@ func main() { } err = stmt.Close() if err != nil { - panic(err) + log.Fatal("failed to close statement, err:", err) } } diff --git a/docs/examples/go/stmt/ws/main.go b/docs/examples/go/stmt/ws/main.go index ddb1d6e2a7..4873e7df91 100644 --- a/docs/examples/go/stmt/ws/main.go +++ b/docs/examples/go/stmt/ws/main.go @@ -3,6 +3,7 @@ package main import ( "database/sql" "fmt" + "log" "math/rand" "time" @@ -18,17 +19,17 @@ func main() { numOfRow := 10 db, err := sql.Open("taosRestful", fmt.Sprintf("root:taosdata@http(%s:6041)/", host)) if err != nil { - panic(err) + log.Fatal("failed to connect TDengine, err:", err) } defer db.Close() // prepare database and table _, err = db.Exec("CREATE DATABASE IF NOT EXISTS power") if err != nil { - panic(err) + log.Fatal("failed to create database, err:", err) } _, err = db.Exec("CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))") if err != nil { - panic(err) + log.Fatal("failed to create table, err:", err) } config := stmt.NewConfig(fmt.Sprintf("ws://%s:6041", host), 0) @@ -40,17 +41,17 @@ func main() { connector, err := stmt.NewConnector(config) if err != nil { - panic(err) + log.Fatal("failed to create stmt connector, err:", err) } - // // prepare statement + // prepare statement sql := "INSERT INTO ? USING meters TAGS(?,?) VALUES (?,?,?,?)" stmt, err := connector.Init() if err != nil { - panic(err) + log.Fatal("failed to init stmt, err:", err) } err = stmt.Prepare(sql) if err != nil { - panic(err) + log.Fatal("failed to prepare stmt, err:", err) } for i := 1; i <= numOfSubTable; i++ { tableName := fmt.Sprintf("d_bind_%d", i) @@ -60,12 +61,12 @@ func main() { // set tableName err = stmt.SetTableName(tableName) if err != nil { - panic(err) + log.Fatal("failed to set table name, err:", err) } // set tags err = stmt.SetTags(tags, tagsType) if err != nil { - panic(err) + log.Fatal("failed to set tags, err:", err) } // bind column data current := time.Now() @@ -77,18 +78,18 @@ func main() { columnData[3] = param.NewParam(1).AddFloat(rand.Float32()) err = stmt.BindParam(columnData, columnType) if err != nil { - panic(err) + log.Fatal("failed to bind param, err:", err) } } // add batch err = stmt.AddBatch() if err != nil { - panic(err) + log.Fatal("failed to add batch, err:", err) } // execute batch err = stmt.Exec() if err != nil { - panic(err) + log.Fatal("failed to exec stmt, err:", err) } // get affected rows affected := stmt.GetAffectedRows() @@ -97,6 +98,6 @@ func main() { } err = stmt.Close() if err != nil { - panic(err) + log.Fatal("failed to close stmt, err:", err) } } diff --git a/docs/examples/go/tmq/native/main.go b/docs/examples/go/tmq/native/main.go index 668898239e..299d5ada07 100644 --- a/docs/examples/go/tmq/native/main.go +++ b/docs/examples/go/tmq/native/main.go @@ -3,6 +3,7 @@ package main import ( "database/sql" "fmt" + "log" "time" "github.com/taosdata/driver-go/v3/af/tmq" @@ -16,7 +17,7 @@ func main() { // init env conn, err := sql.Open("taosSql", "root:taosdata@tcp(127.0.0.1:6030)/") if err != nil { - panic(err) + log.Fatal("failed to connect TDengine, err:", err) } defer func() { conn.Close() @@ -31,17 +32,17 @@ func main() { "msg.with.table.name": "true", "enable.auto.commit": "true", "auto.commit.interval.ms": "1000", - "group.id": "group2", - "client.id": "1", + "group.id": "group1", + "client.id": "client1", }) if err != nil { - panic(err) + log.Fatal("failed to create consumer, err:", err) } // ANCHOR_END: create_consumer // ANCHOR: subscribe err = consumer.Subscribe("topic_meters", nil) if err != nil { - panic(err) + log.Fatal("failed to subscribe, err:", err) } for i := 0; i < 50; i++ { ev := consumer.Poll(100) @@ -49,23 +50,23 @@ func main() { switch e := ev.(type) { case *tmqcommon.DataMessage: // process your data here - fmt.Printf("get message:%v\n", e) + fmt.Printf("data:%v\n", e) // ANCHOR: commit_offset // commit offset topicPartition, err := consumer.CommitOffsets([]tmqcommon.TopicPartition{e.TopicPartition}) if err != nil { - panic(err) + log.Fatal("failed to commit offset, err:", err) } fmt.Println(topicPartition) // ANCHOR_END: commit_offset case tmqcommon.Error: fmt.Printf("%% Error: %v: %v\n", e.Code(), e) - panic(e) + log.Fatal("failed to get message, err:", e) } // commit all offsets topicPartition, err := consumer.Commit() if err != nil { - panic(err) + log.Fatal("failed to commit, err:", err) } fmt.Println(topicPartition) @@ -76,7 +77,7 @@ func main() { // get assignment partitions, err := consumer.Assignment() if err != nil { - panic(err) + log.Fatal("failed to get assignment, err:", err) } for i := 0; i < len(partitions); i++ { fmt.Println(partitions[i]) @@ -87,7 +88,27 @@ func main() { Offset: 0, }, 0) if err != nil { - panic(err) + log.Fatal("failed to seek, err:", err) + } + } + fmt.Println("assignment seek to beginning successfully") + // poll data again + gotData := false + for i := 0; i < 50; i++ { + if gotData { + break + } + ev := consumer.Poll(100) + if ev != nil { + switch e := ev.(type) { + case *tmqcommon.DataMessage: + // process your data here + fmt.Printf("second data polled:%v\n", e) + gotData = true + case tmqcommon.Error: + fmt.Printf("%% Error: %v: %v\n", e.Code(), e) + log.Fatal("failed to get message, err:", e) + } } } // ANCHOR_END: seek @@ -95,12 +116,12 @@ func main() { // unsubscribe err = consumer.Unsubscribe() if err != nil { - panic(err) + log.Fatal("failed to unsubscribe, err:", err) } // close consumer err = consumer.Close() if err != nil { - panic(err) + log.Fatal("failed to close consumer, err:", err) } // ANCHOR_END: close <-done @@ -109,22 +130,22 @@ func main() { func initEnv(conn *sql.DB) { _, err := conn.Exec("CREATE DATABASE IF NOT EXISTS power") if err != nil { - panic(err) + log.Fatal("failed to create database, err:", err) } _, err = conn.Exec("CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))") if err != nil { - panic(err) + log.Fatal("failed to create stable, err:", err) } _, err = conn.Exec("CREATE TOPIC IF NOT EXISTS topic_meters AS SELECT ts, current, voltage, phase, groupid, location FROM power.meters") if err != nil { - panic(err) + log.Fatal("failed to create topic, err:", err) } go func() { for i := 0; i < 10; i++ { time.Sleep(time.Second) _, err = conn.Exec("INSERT INTO power.d1001 USING power.meters TAGS (2, 'California.SanFrancisco') VALUES (NOW , 10.2, 219, 0.32)") if err != nil { - panic(err) + log.Fatal("failed to insert data, err:", err) } } done <- struct{}{} diff --git a/docs/examples/go/tmq/ws/main.go b/docs/examples/go/tmq/ws/main.go index 48e6714957..e05f863fb5 100644 --- a/docs/examples/go/tmq/ws/main.go +++ b/docs/examples/go/tmq/ws/main.go @@ -3,6 +3,7 @@ package main import ( "database/sql" "fmt" + "log" "time" "github.com/taosdata/driver-go/v3/common" @@ -17,7 +18,7 @@ func main() { // init env conn, err := sql.Open("taosWS", "root:taosdata@ws(127.0.0.1:6041)/") if err != nil { - panic(err) + log.Fatal("failed to connect TDengine, err:", err) } defer func() { conn.Close() @@ -36,17 +37,17 @@ func main() { "msg.with.table.name": "true", "enable.auto.commit": "true", "auto.commit.interval.ms": "1000", - "group.id": "group2", - "client.id": "1", + "group.id": "group1", + "client.id": "client1", }) if err != nil { - panic(err) + log.Fatal("failed to create consumer, err:", err) } // ANCHOR_END: create_consumer // ANCHOR: subscribe err = consumer.Subscribe("topic_meters", nil) if err != nil { - panic(err) + log.Fatal("failed to subscribe, err:", err) } for i := 0; i < 50; i++ { ev := consumer.Poll(100) @@ -54,23 +55,23 @@ func main() { switch e := ev.(type) { case *tmqcommon.DataMessage: // process your data here - fmt.Printf("get message:%v\n", e) + fmt.Printf("data:%v\n", e) // ANCHOR: commit_offset // commit offset topicPartition, err := consumer.CommitOffsets([]tmqcommon.TopicPartition{e.TopicPartition}) if err != nil { - panic(err) + log.Fatal("failed to commit offset, err:", err) } fmt.Println(topicPartition) // ANCHOR_END: commit_offset case tmqcommon.Error: fmt.Printf("%% Error: %v: %v\n", e.Code(), e) - panic(e) + log.Fatal("failed to get message, err:", e) } // commit all offsets topicPartition, err := consumer.Commit() if err != nil { - panic(err) + log.Fatal("failed to commit, err:", err) } fmt.Println(topicPartition) @@ -81,7 +82,7 @@ func main() { // get assignment partitions, err := consumer.Assignment() if err != nil { - panic(err) + log.Fatal("failed to get assignment, err:", err) } for i := 0; i < len(partitions); i++ { fmt.Println(partitions[i]) @@ -92,7 +93,27 @@ func main() { Offset: 0, }, 0) if err != nil { - panic(err) + log.Fatal("failed to seek, err:", err) + } + } + fmt.Println("assignment seek to beginning successfully") + // poll data again + gotData := false + for i := 0; i < 50; i++ { + if gotData { + break + } + ev := consumer.Poll(100) + if ev != nil { + switch e := ev.(type) { + case *tmqcommon.DataMessage: + // process your data here + fmt.Printf("second data polled:%v\n", e) + gotData = true + case tmqcommon.Error: + fmt.Printf("%% Error: %v: %v\n", e.Code(), e) + log.Fatal("failed to get message, err:", e) + } } } // ANCHOR_END: seek @@ -100,12 +121,12 @@ func main() { // unsubscribe err = consumer.Unsubscribe() if err != nil { - panic(err) + log.Fatal("failed to unsubscribe, err:", err) } // close consumer err = consumer.Close() if err != nil { - panic(err) + log.Fatal("failed to close consumer, err:", err) } // ANCHOR_END: close <-done @@ -114,22 +135,22 @@ func main() { func initEnv(conn *sql.DB) { _, err := conn.Exec("CREATE DATABASE IF NOT EXISTS power") if err != nil { - panic(err) + log.Fatal("failed to create database, err:", err) } _, err = conn.Exec("CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))") if err != nil { - panic(err) + log.Fatal("failed to create stable, err:", err) } _, err = conn.Exec("CREATE TOPIC IF NOT EXISTS topic_meters AS SELECT ts, current, voltage, phase, groupid, location FROM power.meters") if err != nil { - panic(err) + log.Fatal("failed to create topic, err:", err) } go func() { for i := 0; i < 10; i++ { time.Sleep(time.Second) _, err = conn.Exec("INSERT INTO power.d1001 USING power.meters TAGS (2, 'California.SanFrancisco') VALUES (NOW , 10.2, 219, 0.32)") if err != nil { - panic(err) + log.Fatal("failed to insert data, err:", err) } } done <- struct{}{} diff --git a/docs/zh/08-develop/04-schemaless.md b/docs/zh/08-develop/04-schemaless.md index 611878960d..a36fce6e45 100644 --- a/docs/zh/08-develop/04-schemaless.md +++ b/docs/zh/08-develop/04-schemaless.md @@ -225,6 +225,9 @@ writer.write(lineDemo, SchemalessProtocolType.LINE, SchemalessTimestampType.NANO +```go +{{#include docs/examples/go/schemaless/native/main.go}} +``` 除 DSN 不同,其余同 Websocket 代码示例。 @@ -252,9 +255,7 @@ writer.write(lineDemo, SchemalessProtocolType.LINE, SchemalessTimestampType.NANO - ```go - {{#include docs/examples/go/schemaless/native/main.go}} - ``` + 不支持 不支持 diff --git a/tests/docs-examples-test/csharp.sh b/tests/docs-examples-test/csharp.sh index 9d7867d829..0805b425b4 100644 --- a/tests/docs-examples-test/csharp.sh +++ b/tests/docs-examples-test/csharp.sh @@ -7,32 +7,59 @@ pgrep taosadapter || taosadapter >> /dev/null 2>&1 & cd ../../docs/examples/csharp dotnet run --project connect/connect.csproj - -taos -s "drop database if exists power" -dotnet run --project sqlInsert/sqlinsert.csproj -dotnet run --project query/query.csproj -#dotnet run --project subscribe/subscribe.csproj - -#taos -s "drop topic if exists topic_example" -taos -s "drop database if exists power" -dotnet run --project stmtInsert/stmtinsert.csproj +dotnet run --project wsConnect/wsConnect.csproj taos -s "drop database if exists test" +sleep 1 dotnet run --project influxdbLine/influxdbline.csproj taos -s "drop database if exists test" +sleep 1 dotnet run --project optsTelnet/optstelnet.csproj taos -s "drop database if exists test" +sleep 1 dotnet run --project optsJSON/optsJSON.csproj -taos -s "create database if not exists test" +# query taos -s "drop database if exists power" -dotnet run --project wsConnect/wsConnect.csproj +sleep 1 dotnet run --project wsInsert/wsInsert.csproj dotnet run --project wsQuery/wsQuery.csproj + taos -s "drop database if exists power" +sleep 1 +dotnet run --project sqlInsert/sqlinsert.csproj +dotnet run --project query/query.csproj + + +# stmt +taos -s "drop database if exists power" +sleep 1 dotnet run --project wsStmt/wsStmt.csproj -taos -s "drop database if exists test" taos -s "drop database if exists power" +sleep 1 +dotnet run --project stmtInsert/stmtinsert.csproj + +# schemaless +taos -s "drop database if exists power" +sleep 1 +dotnet run --project wssml/wssml.csproj + +taos -s "drop database if exists power" +sleep 1 +dotnet run --project nativesml/nativesml.csproj + +# subscribe +taos -s "drop topic if exists topic_meters" +sleep 1 +taos -s "drop database if exists power" +sleep 1 +dotnet run --project wssubscribe/wssubscribe.csproj + +taos -s "drop topic if exists topic_meters" +sleep 1 +taos -s "drop database if exists power" +sleep 1 +dotnet run --project subscribe/subscribe.csproj diff --git a/tests/docs-examples-test/go.sh b/tests/docs-examples-test/go.sh index 8248b4fe0d..f8716b6bd7 100644 --- a/tests/docs-examples-test/go.sh +++ b/tests/docs-examples-test/go.sh @@ -4,7 +4,7 @@ set -e taosd >>/dev/null 2>&1 & taosadapter >>/dev/null 2>&1 & -sleep 10 +sleep 1 cd ../../docs/examples/go go mod tidy @@ -12,20 +12,67 @@ go mod tidy go run ./connect/afconn/main.go go run ./connect/cgoexample/main.go go run ./connect/restexample/main.go +go run ./connect/connpool/main.go +go run ./connect/wsexample/main.go + +taos -s "drop database if exists power" +go run ./sqlquery/main.go + +taos -s "drop database if exists power" +sleep 1 +go run ./queryreqid/main.go + +taos -s "drop database if exists power" +sleep 1 +go run ./stmt/native/main.go + +taos -s "drop database if exists power" +sleep 1 +go run ./stmt/ws/main.go + +taos -s "drop database if exists power" +sleep 1 +go run ./schemaless/native/main.go + +taos -s "drop database if exists power" +sleep 1 +go run ./schemaless/ws/main.go + +taos -s "drop topic if exists topic_meters" +sleep 1 +taos -s "drop database if exists power" +sleep 1 +go run ./tmq/native/main.go + +taos -s "drop topic if exists topic_meters" +sleep 1 +taos -s "drop database if exists power" +sleep 1 +go run ./tmq/ws/main.go + taos -s "drop database if exists test" +sleep 1 go run ./insert/json/main.go taos -s "drop database if exists test" +sleep 1 go run ./insert/line/main.go +taos -s "drop topic if exists topic_meters" +sleep 1 taos -s "drop database if exists power" +sleep 1 go run ./insert/sql/main.go taos -s "drop database if exists power" +sleep 1 go run ./insert/stmt/main.go taos -s "drop database if exists test" +sleep 1 go run ./insert/telnet/main.go go run ./query/sync/main.go taos -s "drop topic if exists example_tmq_topic" +sleep 1 taos -s "drop database if exists example_tmq" +sleep 1 go run ./sub/main.go From 098cc72fc23537357233896c7999bb24b4c74e16 Mon Sep 17 00:00:00 2001 From: sheyanjie-qq <249478495@qq.com> Date: Fri, 2 Aug 2024 17:15:20 +0800 Subject: [PATCH 12/15] mod rust doc --- docs/zh/14-reference/05-connector/26-rust.mdx | 517 +----------------- 1 file changed, 1 insertion(+), 516 deletions(-) diff --git a/docs/zh/14-reference/05-connector/26-rust.mdx b/docs/zh/14-reference/05-connector/26-rust.mdx index e33d3f0a0f..ae16af4f2d 100644 --- a/docs/zh/14-reference/05-connector/26-rust.mdx +++ b/docs/zh/14-reference/05-connector/26-rust.mdx @@ -82,360 +82,7 @@ TDengine 目前支持时间戳、数字、字符、布尔类型,与 Rust 对 **注意**:JSON 类型仅在 tag 中支持。 -## 安装步骤 - -### 安装前准备 - -* 安装 Rust 开发工具链 -* 如果使用原生连接,请安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../#安装客户端驱动) - -### 安装连接器 - -根据选择的连接方式,按照如下说明在 [Rust](https://rust-lang.org) 项目中添加 [taos][taos] 依赖: - - - - -在 `Cargo.toml` 文件中添加 [taos][taos]: - -```toml -[dependencies] -# use default feature -taos = "*" -``` - - - - - -在 `Cargo.toml` 文件中添加 [taos][taos],并启用 `ws` 特性。 - -```toml -[dependencies] -taos = { version = "*", default-features = false, features = ["ws"] } -``` - -当仅启用 `ws` 特性时,可同时指定 `r2d2` 使得在同步(blocking/sync)模式下使用 [r2d2] 作为连接池: - -```toml -[dependencies] -taos = { version = "*", default-features = false, features = ["r2d2", "ws"] } -``` - - - - - -在 `Cargo.toml` 文件中添加 [taos][taos],并启用 `native` 特性: - -```toml -[dependencies] -taos = { version = "*", default-features = false, features = ["native"] } -``` - - - - -## 建立连接 - -[TaosBuilder] 通过 DSN 连接描述字符串创建一个连接构造器。 - -```rust -let builder = TaosBuilder::from_dsn("taos://")?; -``` - -现在您可以使用该对象创建连接: - -```rust -let conn = builder.build()?; -``` - -连接对象可以创建多个: - -```rust -let conn1 = builder.build()?; -let conn2 = builder.build()?; -``` - -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 描述字符串示例如下: - -```text -taos+ws://localhost:6041/test -``` - -表示使用 Websocket(`ws`)方式通过 `6041` 端口连接服务器 `localhost`,并指定默认数据库为 `test`。 - -这使得用户可以通过 DSN 指定连接方式: - -```rust -use taos::*; - -// use native protocol. -let builder = TaosBuilder::from_dsn("taos://localhost:6030")?; -let conn1 = builder.build(); - -// use websocket protocol. -let builder2 = TaosBuilder::from_dsn("taos+ws://localhost:6041")?; -let conn2 = builder2.build(); -``` - -建立连接后,您可以进行相关数据库操作: - -```rust -async fn demo(taos: &Taos, db: &str) -> Result<(), Error> { - // prepare database - taos.exec_many([ - format!("DROP DATABASE IF EXISTS `{db}`"), - format!("CREATE DATABASE `{db}`"), - format!("USE `{db}`"), - ]) - .await?; - - let inserted = taos.exec_many([ - // create super table - "CREATE TABLE `meters` (`ts` TIMESTAMP, `current` FLOAT, `voltage` INT, `phase` FLOAT) \ - TAGS (`groupid` INT, `location` BINARY(24))", - // create child table - "CREATE TABLE `d0` USING `meters` TAGS(0, 'California.LosAngles')", - // insert into child table - "INSERT INTO `d0` values(now - 10s, 10, 116, 0.32)", - // insert with NULL values - "INSERT INTO `d0` values(now - 8s, NULL, NULL, NULL)", - // insert and automatically create table with tags if not exists - "INSERT INTO `d1` USING `meters` TAGS(1, 'California.SanFrancisco') values(now - 9s, 10.1, 119, 0.33)", - // insert many records in a single sql - "INSERT INTO `d1` values (now-8s, 10, 120, 0.33) (now - 6s, 10, 119, 0.34) (now - 4s, 11.2, 118, 0.322)", - ]).await?; - - assert_eq!(inserted, 6); - let mut result = taos.query("select * from `meters`").await?; - - for field in result.fields() { - println!("got field: {}", field.name()); - } - - let values = result. -} -``` - -查询数据可以通过两种方式:使用内建类型或 [serde](https://serde.rs) 序列化框架。 - -```rust - // Query option 1, use rows stream. - let mut rows = result.rows(); - while let Some(row) = rows.try_next().await? { - for (name, value) in row { - println!("got value of {}: {}", name, value); - } - } - - // Query options 2, use deserialization with serde. - #[derive(Debug, serde::Deserialize)] - #[allow(dead_code)] - struct Record { - // deserialize timestamp to chrono::DateTime - ts: DateTime, - // float to f32 - current: Option, - // int to i32 - voltage: Option, - phase: Option, - groupid: i32, - // binary/varchar to String - location: String, - } - - let records: Vec = taos - .query("select * from `meters`") - .await? - .deserialize() - .try_collect() - .await?; - - dbg!(records); - Ok(()) -``` - -## 使用示例 - -### 创建数据库和表 - -```rust -{{#include docs/examples/rust/nativeexample/examples/query.rs:create_db_and_table}} -``` - -> **注意**:如果不使用 `use db` 指定数据库,则后续对表的操作都需要增加数据库名称作为前缀,如 db.tb。 - -### 插入数据 - -```rust -{{#include docs/examples/rust/nativeexample/examples/query.rs:insert_data}} -``` - -### 查询数据 - -```rust -{{#include docs/examples/rust/nativeexample/examples/query.rs:query_data}} -``` - -### 执行带有 req_id 的 SQL - - - -```rust -{{#include docs/examples/rust/nativeexample/examples/query.rs:query_with_req_id}} -``` - -### 通过参数绑定写入数据 - -TDengine 的 Rust 连接器实现了参数绑定方式对数据写入(INSERT)场景的支持。采用这种方式写入数据时,能避免 SQL 语法解析的资源消耗,从而在很多情况下显著提升写入性能。 - -参数绑定接口详见[API参考](#stmt-api) - -```rust -{{#include docs/examples/rust/nativeexample/examples/stmt.rs}} -``` - -### 无模式写入 - -TDengine 支持无模式写入功能。无模式写入兼容 InfluxDB 的 行协议(Line Protocol)、OpenTSDB 的 telnet 行协议和 OpenTSDB 的 JSON 格式协议。详情请参见[无模式写入](../../reference/schemaless/)。 - -```rust -{{#include docs/examples/rust/nativeexample/examples/schemaless.rs}} -``` - -### 执行带有 req_id 的无模式写入 - -此 req_id 可用于请求链路追踪。 - -```rust -let sml_data = SmlDataBuilder::default() - .protocol(SchemalessProtocol::Line) - .data(data) - .req_id(100u64) - .build()?; - -client.put(&sml_data)? -``` - -### 数据订阅 - -TDengine 通过消息队列 [TMQ](../../taos-sql/tmq/) 启动一个订阅。 - -#### 创建 Topic - -```rust -{{#include docs/examples/rust/nativeexample/examples/tmq.rs:create_topic}} -``` - -#### 创建 Consumer - -创建消费者: - -```rust -{{#include docs/examples/rust/nativeexample/examples/tmq.rs:create_consumer}} -``` - -#### 订阅消费数据 - -消费者可订阅一个或多个 `TOPIC`。 - -```rust -{{#include docs/examples/rust/nativeexample/examples/tmq.rs:subscribe}} -``` - -TMQ 消息队列是一个 [futures::Stream](https://docs.rs/futures/latest/futures/stream/index.html) 类型,可以使用相应 API 对每个消息进行消费,并通过 `.commit` 进行已消费标记。 - -```rust -{{#include docs/examples/rust/nativeexample/examples/tmq.rs:consume}} -``` - -获取消费进度: - -版本要求 connector-rust >= v0.8.8, TDengine >= 3.0.5.0 - -```rust -{{#include docs/examples/rust/nativeexample/examples/tmq.rs:assignments}} -``` - -#### 指定订阅 Offset - -按照指定的进度消费: - -版本要求 connector-rust >= v0.8.8, TDengine >= 3.0.5.0 - -```rust -{{#include docs/examples/rust/nativeexample/examples/tmq.rs:seek_offset}} -``` - -#### 关闭订阅 - -```rust -{{#include docs/examples/rust/nativeexample/examples/tmq.rs:unsubscribe}} -``` - -对于 TMQ DSN, 有以下配置项可以进行设置,需要注意的是,`group.id` 是必须的。 - -- `group.id`: 同一个消费者组,将以至少消费一次的方式进行消息负载均衡。 -- `client.id`: 可选的订阅客户端识别项。 -- `auto.offset.reset`: 可选初始化订阅起点, *earliest* 为从头开始订阅, *latest* 为仅从最新数据开始订阅,默认值根据 TDengine 版本有所不同,详细参见 [数据订阅](https://docs.taosdata.com/develop/tmq/)。注意,此选项在同一个 `group.id` 中仅生效一次。 -- `enable.auto.commit`: 当设置为 `true` 时,将启用自动标记模式,当对数据一致性不敏感时,可以启用此方式。 -- `auto.commit.interval.ms`: 自动标记的时间间隔。 - -#### 完整示例 - -完整订阅示例参见 [GitHub 示例文件](https://github.com/taosdata/TDengine/blob/3.0/docs/examples/rust/nativeexample/examples/tmq.rs). - -### 与连接池使用 - -在复杂应用中,建议启用连接池。[taos] 的连接池默认(异步模式)使用 [deadpool] 实现。 - -如下,可以生成一个默认参数的连接池。 - -```rust -let pool: Pool = TaosBuilder::from_dsn("taos:///") - .unwrap() - .pool() - .unwrap(); -``` - -同样可以使用连接池的构造器,对连接池参数进行设置: - -```rust -let pool: Pool = Pool::builder(Manager::from_dsn(self.dsn.clone()).unwrap().0) - .max_size(88) // 最大连接数 - .build() - .unwrap(); -``` - -在应用代码中,使用 `pool.get()?` 来获取一个连接对象 [Taos]。 - -```rust -let taos = pool.get()?; -``` - -### 更多示例程序 +## 示例程序汇总 示例程序源码位于 `TDengine/examples/rust` 下: @@ -445,168 +92,6 @@ let taos = pool.get()?; 请参考 [FAQ](../../train-faq/faq) -## API 参考 - -[Taos][struct.Taos] 对象提供了多个数据库操作的 API: - -1. `exec`: 执行某个非查询类 SQL 语句,例如 `CREATE`,`ALTER`,`INSERT` 等。 - - ```rust - let affected_rows = taos.exec("INSERT INTO tb1 VALUES(now, NULL)").await?; - ``` - -2. `exec_many`: 同时(顺序)执行多个 SQL 语句。 - - ```rust - taos.exec_many([ - "CREATE DATABASE test", - "USE test", - "CREATE TABLE `tb1` (`ts` TIMESTAMP, `val` INT)", - ]).await?; - ``` - -3. `query`:执行查询语句,返回 [ResultSet] 对象。 - - ```rust - let mut q = taos.query("select * from log.logs").await?; - ``` - - [ResultSet] 对象存储了查询结果数据和返回的列的基本信息(列名,类型,长度): - - 列信息使用 [.fields()] 方法获取: - - ```rust - let cols = q.fields(); - for col in cols { - println!("name: {}, type: {:?} , bytes: {}", col.name(), col.ty(), col.bytes()); - } - ``` - - 逐行获取数据: - - ```rust - let mut rows = result.rows(); - let mut nrows = 0; - while let Some(row) = rows.try_next().await? { - for (col, (name, value)) in row.enumerate() { - println!( - "[{}] got value in col {} (named `{:>8}`): {}", - nrows, col, name, value - ); - } - nrows += 1; - } - ``` - - 或使用 [serde](https://serde.rs) 序列化框架。 - - ```rust - #[derive(Debug, Deserialize)] - struct Record { - // deserialize timestamp to chrono::DateTime - ts: DateTime, - // float to f32 - current: Option, - // int to i32 - voltage: Option, - phase: Option, - groupid: i32, - // binary/varchar to String - location: String, - } - - let records: Vec = taos - .query("select * from `meters`") - .await? - .deserialize() - .try_collect() - .await?; - ``` - -需要注意的是,需要使用 Rust 异步函数和异步运行时。 - -[Taos][struct.Taos] 提供部分 SQL 的 Rust 方法化以减少 `format!` 代码块的频率: - -- `.describe(table: &str)`: 执行 `DESCRIBE` 并返回一个 Rust 数据结构。 -- `.create_database(database: &str)`: 执行 `CREATE DATABASE` 语句。 -- `.use_database(database: &str)`: 执行 `USE` 语句。 - -除此之外,该结构也是参数绑定和行协议接口的入口,使用方法请参考具体的 API 说明。 - -

- -参数绑定接口 - -

- -与 C 接口类似,Rust 提供参数绑定接口。首先,通过 [Taos][struct.Taos] 对象创建一个 SQL 语句的参数绑定对象 [Stmt]: - -```rust -let mut stmt = Stmt::init(&taos).await?; -stmt.prepare("INSERT INTO ? USING meters TAGS(?, ?) VALUES(?, ?, ?, ?)")?; -``` - -参数绑定对象提供了一组接口用于实现参数绑定: - -`.set_tbname(name)` - -用于绑定表名。 - -```rust -let mut stmt = taos.stmt("insert into ? values(? ,?)")?; -stmt.set_tbname("d0")?; -``` - -`.set_tags(&[tag])` - -当 SQL 语句使用超级表时,用于绑定子表表名和标签值: - -```rust -let mut stmt = taos.stmt("insert into ? using stb0 tags(?) values(? ,?)")?; -stmt.set_tbname("d0")?; -stmt.set_tags(&[Value::VarChar("涛思".to_string())])?; -``` - -`.bind(&[column])` - -用于绑定值类型。使用 [ColumnView] 结构体构建需要的类型并绑定: - -```rust -let params = vec![ - ColumnView::from_millis_timestamp(vec![164000000000]), - ColumnView::from_bools(vec![true]), - ColumnView::from_tiny_ints(vec![i8::MAX]), - ColumnView::from_small_ints(vec![i16::MAX]), - ColumnView::from_ints(vec![i32::MAX]), - ColumnView::from_big_ints(vec![i64::MAX]), - ColumnView::from_unsigned_tiny_ints(vec![u8::MAX]), - ColumnView::from_unsigned_small_ints(vec![u16::MAX]), - ColumnView::from_unsigned_ints(vec![u32::MAX]), - ColumnView::from_unsigned_big_ints(vec![u64::MAX]), - ColumnView::from_floats(vec![f32::MAX]), - ColumnView::from_doubles(vec![f64::MAX]), - ColumnView::from_varchar(vec!["ABC"]), - ColumnView::from_nchar(vec!["涛思数据"]), -]; -let rows = stmt.bind(¶ms)?.add_batch()?.execute()?; -``` - -`.execute()` - -执行 SQL。[Stmt] 对象可以复用,在执行后可以重新绑定并执行。执行前请确保所有数据已通过 `.add_batch` 加入到执行队列中。 - -```rust -stmt.execute()?; - -// next bind cycle. -//stmt.set_tbname()?; -//stmt.bind()?; -//stmt.execute()?; -``` - -一个可运行的示例请见 [GitHub 上的示例](https://github.com/taosdata/taos-connector-rust/blob/main/examples/bind.rs)。 - - ## API 参考 Rust 连接器的接口分为同步接口和异步接口,一般同步接口是由异步接口实现,方法签名除 async 关键字外基本相同。对于同步接口和异步接口功能一样的接口,本文档只提供同步接口的说明。 From e0c2a3865bb30597b58c1244ca508d6d0a16338a Mon Sep 17 00:00:00 2001 From: sheyanjie-qq <249478495@qq.com> Date: Fri, 2 Aug 2024 17:17:19 +0800 Subject: [PATCH 13/15] fix typo --- .../taosdata/example/ConsumerLoopFull.java | 2 +- .../taosdata/example/WsConsumerLoopFull.java | 93 +++++++++++-------- 2 files changed, 57 insertions(+), 38 deletions(-) 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 index c78a875ab6..69d53e1117 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ConsumerLoopFull.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ConsumerLoopFull.java @@ -120,7 +120,7 @@ public class ConsumerLoopFull { break; } - // poll data agagin + // poll data again records = consumer.poll(Duration.ofMillis(100)); for (ConsumerRecord record : records) { // process the data here 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 index 6caa42b1c1..3ed0015359 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WsConsumerLoopFull.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WsConsumerLoopFull.java @@ -20,7 +20,7 @@ public class WsConsumerLoopFull { static private Statement statement; public static TaosConsumer getConsumer() throws SQLException { -// ANCHOR: create_consumer + // ANCHOR: create_consumer Properties config = new Properties(); config.setProperty("td.connect.type", "ws"); config.setProperty("bootstrap.servers", "localhost:6041"); @@ -38,14 +38,16 @@ public class WsConsumerLoopFull { 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()); + // 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 + // ANCHOR_END: create_consumer } public static void pollDataExample() throws SQLException { @@ -68,14 +70,16 @@ public class WsConsumerLoopFull { 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()); + // 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 + // ANCHOR: poll_data_code_piece try (TaosConsumer consumer = getConsumer()) { List topics = Collections.singletonList("topic_meters"); @@ -93,15 +97,17 @@ public class WsConsumerLoopFull { } } 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()); + // 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 + // ANCHOR_END: poll_data_code_piece } public static void seekExample() throws SQLException { -// ANCHOR: consumer_seek + // ANCHOR: consumer_seek try (TaosConsumer consumer = getConsumer()) { List topics = Collections.singletonList("topic_meters"); @@ -123,7 +129,7 @@ public class WsConsumerLoopFull { break; } - // poll data agagin + // poll data again records = consumer.poll(Duration.ofMillis(100)); for (ConsumerRecord record : records) { // process the data here @@ -131,16 +137,17 @@ public class WsConsumerLoopFull { 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()); + // 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 + // ANCHOR_END: consumer_seek } - public static void commitExample() throws SQLException { -// ANCHOR: commit_code_piece + // ANCHOR: commit_code_piece try (TaosConsumer consumer = getConsumer()) { List topics = Collections.singletonList("topic_meters"); @@ -158,28 +165,32 @@ public class WsConsumerLoopFull { } } } 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()); + // 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 + // 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 + // 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()); + // 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 + // ANCHOR_END: unsubscribe_data_code_piece } public static class ResultDeserializer extends ReferenceDeserializer { @@ -256,7 +267,8 @@ public class WsConsumerLoopFull { 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()); + 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); } } @@ -265,10 +277,13 @@ public class WsConsumerLoopFull { 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"); + 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()); + 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); } } @@ -282,13 +297,15 @@ public class WsConsumerLoopFull { try { connection = DriverManager.getConnection(url, properties); } catch (SQLException ex) { - System.out.println("Failed to create connection, url:" + url + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + 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()); + 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."); @@ -300,7 +317,8 @@ public class WsConsumerLoopFull { statement.close(); } } catch (SQLException ex) { - System.out.println("Failed to close statement, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + System.out.println( + "Failed to close statement, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); throw new SQLException("Failed to close statement", ex); } @@ -309,13 +327,13 @@ public class WsConsumerLoopFull { connection.close(); } } catch (SQLException ex) { - System.out.println("Failed to close connection, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + 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(); @@ -328,12 +346,13 @@ public class WsConsumerLoopFull { try { // please use one example at a time pollDataExample(); -// seekExample(); -// pollExample(); -// commitExample(); + // 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("Failed to poll data from topic_meters, ErrCode:" + ex.getErrorCode() + + "; ErrMessage: " + ex.getMessage()); } System.out.println("pollDataExample executed successfully"); }); From b45c4aec1a62471eab69a972e86536e37c6a4667 Mon Sep 17 00:00:00 2001 From: sheyanjie-qq <249478495@qq.com> Date: Fri, 2 Aug 2024 18:39:19 +0800 Subject: [PATCH 14/15] mod java exception --- .../com/taos/example/JNIConnectExample.java | 4 + .../com/taos/example/RESTConnectExample.java | 4 + .../com/taos/example/WSConnectExample.java | 4 + .../taosdata/example/ConsumerLoopFull.java | 104 +++++----- .../com/taosdata/example/JdbcCreatDBDemo.java | 4 + .../taosdata/example/JdbcInsertDataDemo.java | 5 +- .../com/taosdata/example/JdbcQueryDemo.java | 4 + .../com/taosdata/example/JdbcReqIdDemo.java | 5 +- .../example/ParameterBindingBasicDemo.java | 4 + .../example/ParameterBindingFullDemo.java | 29 ++- .../taosdata/example/SchemalessJniTest.java | 4 + .../taosdata/example/SchemalessWsTest.java | 4 + .../example/WSParameterBindingBasicDemo.java | 4 + .../example/WSParameterBindingFullDemo.java | 7 +- .../taosdata/example/WsConsumerLoopFull.java | 196 +++++++++--------- 15 files changed, 216 insertions(+), 166 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 8b9f27c5ab..42ac7bde85 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 @@ -27,6 +27,10 @@ public static void main(String[] args) throws SQLException { } catch (SQLException ex) { // handle any errors, please refer to the JDBC specifications for detailed exceptions info System.out.println("Failed to connect to " + jdbcUrl + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + throw ex; + } catch (Exception ex){ + System.out.println("Failed to connect to " + jdbcUrl + "; ErrMessage: " + ex.getMessage()); + throw ex; } } // 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 22bf1d61f4..b1ec31ee86 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 @@ -16,6 +16,10 @@ public static void main(String[] args) throws SQLException { } catch (SQLException ex) { // handle any errors, please refer to the JDBC specifications for detailed exceptions info System.out.println("Failed to connect to " + jdbcUrl + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + throw ex; + } catch (Exception ex){ + System.out.println("Failed to connect to " + jdbcUrl + "; ErrMessage: " + ex.getMessage()); + throw ex; } } // 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 b355a28f6f..d683cc64a6 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 @@ -28,6 +28,10 @@ public static void main(String[] args) throws SQLException { } catch (SQLException ex) { // handle any errors, please refer to the JDBC specifications for detailed exceptions info System.out.println("Failed to connect to " + jdbcUrl + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + throw ex; + } catch (Exception ex){ + System.out.println("Failed to connect to " + jdbcUrl + "; ErrMessage: " + ex.getMessage()); + throw ex; } } // ANCHOR_END: main 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 index 69d53e1117..7e3bc05d6a 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ConsumerLoopFull.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ConsumerLoopFull.java @@ -16,6 +16,8 @@ public class ConsumerLoopFull { static private Connection connection; static private Statement statement; + static private volatile boolean stopFlag = false; + public static TaosConsumer getConsumer() throws SQLException { // ANCHOR: create_consumer Properties config = new Properties(); @@ -38,15 +40,16 @@ public class ConsumerLoopFull { // 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); + } catch (Exception ex) { + System.out.println("Failed to create jni consumer, host : " + config.getProperty("bootstrap.servers") + + "; ErrMessage: " + ex.getMessage()); + throw new SQLException("Failed to create consumer", ex); } // ANCHOR_END: create_consumer } - public static void pollDataExample() throws SQLException { - try (TaosConsumer consumer = getConsumer()) { + public static void pollDataExample(TaosConsumer consumer) throws SQLException { + try{ // subscribe to the topics List topics = Collections.singletonList("topic_meters"); @@ -68,12 +71,15 @@ public class ConsumerLoopFull { // 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); + } catch (Exception ex) { + System.out.println("Failed to poll data from topic_meters; ErrMessage: " + ex.getMessage()); + throw new SQLException("Failed to poll data from topic_meters", ex); } } - public static void pollExample() throws SQLException { + public static void pollExample(TaosConsumer consumer) throws SQLException { // ANCHOR: poll_data_code_piece - try (TaosConsumer consumer = getConsumer()) { + try { List topics = Collections.singletonList("topic_meters"); // subscribe to the topics @@ -93,54 +99,48 @@ public class ConsumerLoopFull { // 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); + } catch (Exception ex) { + System.out.println("Failed to poll data; ErrMessage: " + ex.getMessage()); + throw new SQLException("Failed to poll data", ex); } // ANCHOR_END: poll_data_code_piece } - public static void seekExample() throws SQLException { + public static void seekExample(TaosConsumer consumer) throws SQLException { // ANCHOR: consumer_seek - try (TaosConsumer consumer = getConsumer()) { + try { List topics = Collections.singletonList("topic_meters"); // subscribe to the topics consumer.subscribe(topics); System.out.println("subscribe topics successfully"); + Set assignment = consumer.assignment(); + System.out.println("now assignment: " + JSON.toJSONString(assignment)); + 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 again - 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; - } - - + consumer.seekToBeginning(assignment); + System.out.println("assignment seek to beginning successfully"); + System.out.println("beginning assignment: " + JSON.toJSONString(assignment)); } 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); + } catch (Exception ex) { + System.out.println("seek example failed; ErrMessage: " + ex.getMessage()); + throw new SQLException("seek example failed", ex); } // ANCHOR_END: consumer_seek } - public static void commitExample() throws SQLException { + public static void commitExample(TaosConsumer consumer) throws SQLException { // ANCHOR: commit_code_piece - try (TaosConsumer consumer = getConsumer()) { + try { List topics = Collections.singletonList("topic_meters"); consumer.subscribe(topics); @@ -160,12 +160,14 @@ public class ConsumerLoopFull { // 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); + } catch (Exception ex) { + System.out.println("Failed to execute consumer functions. 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(); + public static void unsubscribeExample(TaosConsumer consumer) throws SQLException { List topics = Collections.singletonList("topic_meters"); consumer.subscribe(topics); // ANCHOR: unsubscribe_data_code_piece @@ -175,7 +177,11 @@ public class ConsumerLoopFull { // 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 { + } catch (Exception ex) { + System.out.println("Failed to unsubscribe consumer. ErrMessage: " + ex.getMessage()); + throw new SQLException("Failed to unsubscribe consumer", ex); + } + finally { consumer.close(); } // ANCHOR_END: unsubscribe_data_code_piece @@ -243,17 +249,16 @@ public class ConsumerLoopFull { } } - 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) "); - } + public static void prepareData() throws SQLException, InterruptedException { try { - int affectedRows = statement.executeUpdate(insertQuery.toString()); - assert affectedRows == 10000; + int i = 0; + while (!stopFlag) { + i++; + String insertQuery = "INSERT INTO power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') VALUES (NOW + " + i + "a, 10.30000, 219, 0.31000) "; + int affectedRows = statement.executeUpdate(insertQuery); + assert affectedRows == 1; + Thread.sleep(1); + } } 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); @@ -315,7 +320,7 @@ public class ConsumerLoopFull { } - public static void main(String[] args) throws SQLException { + public static void main(String[] args) throws SQLException, InterruptedException { initConnection(); prepareMeta(); @@ -326,11 +331,14 @@ public class ConsumerLoopFull { executor.submit(() -> { try { // please use one example at a time - pollDataExample(); -// seekExample(); -// pollExample(); -// commitExample(); - unsubscribeExample(); + TaosConsumer consumer = getConsumer(); + + pollDataExample(consumer); + seekExample(consumer); + pollExample(consumer); + commitExample(consumer); + unsubscribeExample(consumer); + stopFlag = true; } catch (SQLException ex) { System.out.println("Failed to poll data from topic_meters, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + 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 f5f5b1c62c..93531bd80f 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 @@ -45,6 +45,10 @@ public class JdbcCreatDBDemo { } catch (SQLException ex) { // handle any errors, please refer to the JDBC specifications for detailed exceptions info System.out.println("Failed to create db and table, url:" + jdbcUrl + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + throw ex; + } catch (Exception ex){ + System.out.println("Failed to create db and table, url:" + jdbcUrl + "; ErrMessage: " + ex.getMessage()); + throw ex; } // 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 f8e11a8f41..cb8755788d 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 @@ -43,7 +43,10 @@ public class JdbcInsertDataDemo { } catch (SQLException ex) { // handle any errors, please refer to the JDBC specifications for detailed exceptions info System.out.println("Failed to insert data to power.meters, url:" + jdbcUrl + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); - + throw ex; + } catch (Exception ex){ + System.out.println("Failed to insert data to power.meters, url:" + jdbcUrl + "; ErrMessage: " + ex.getMessage()); + throw ex; } // 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 a4749afed5..ea6d8346c6 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 @@ -44,6 +44,10 @@ public class JdbcQueryDemo { } catch (SQLException ex) { // handle any errors, please refer to the JDBC specifications for detailed exceptions info System.out.println("Failed to query data from power.meters, url:" + jdbcUrl + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + throw ex; + } catch (Exception ex){ + System.out.println("Failed to query data from power.meters, url:" + jdbcUrl + "; ErrMessage: " + ex.getMessage()); + throw ex; } // 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 3705e0aac2..0f2e522ce0 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 @@ -38,7 +38,10 @@ public class JdbcReqIdDemo { } catch (SQLException ex) { // handle any errors, please refer to the JDBC specifications for detailed exceptions info System.out.println("Failed to execute sql with reqId, url:" + jdbcUrl + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); - + throw ex; + } catch (Exception ex){ + System.out.println("Failed to execute sql with reqId, url:" + jdbcUrl + "; ErrMessage: " + ex.getMessage()); + throw ex; } // 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 fa2efab2ee..6a9fc5e44f 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,6 +69,10 @@ public class ParameterBindingBasicDemo { } 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()); + throw ex; + } catch (Exception ex){ + System.out.println("Failed to insert to table meters using stmt, url: " + jdbcUrl + "; ErrMessage: " + ex.getMessage()); + throw ex; } } diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ParameterBindingFullDemo.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ParameterBindingFullDemo.java index e1aabcd008..bee619c2f7 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ParameterBindingFullDemo.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ParameterBindingFullDemo.java @@ -31,20 +31,27 @@ public class ParameterBindingFullDemo { public static void main(String[] args) throws SQLException { String jdbcUrl = "jdbc:TAOS://" + host + ":6030/"; - Connection conn = DriverManager.getConnection(jdbcUrl, "root", "taosdata"); + try (Connection conn = DriverManager.getConnection(jdbcUrl, "root", "taosdata")) { - init(conn); + init(conn); - bindInteger(conn); - bindFloat(conn); - bindBoolean(conn); - bindBytes(conn); - bindString(conn); - bindVarbinary(conn); - bindGeometry(conn); + bindInteger(conn); + bindFloat(conn); + bindBoolean(conn); + bindBytes(conn); + bindString(conn); + bindVarbinary(conn); + bindGeometry(conn); - clean(conn); - conn.close(); + clean(conn); + } 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()); + throw ex; + } catch (Exception ex){ + System.out.println("Failed to insert to table meters using stmt, url: " + jdbcUrl + "; ErrMessage: " + ex.getMessage()); + throw ex; + } } private static void init(Connection conn) throws SQLException { 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 8f5fe0e7cf..0a1a674761 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 @@ -28,6 +28,10 @@ public class SchemalessJniTest { } catch (SQLException ex) { // handle any errors, please refer to the JDBC specifications for detailed exceptions info System.out.println("Failed to insert data with schemaless, host:" + host + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + throw ex; + } catch (Exception ex){ + System.out.println("Failed to insert data with schemaless, host:" + host + "; ErrMessage: " + ex.getMessage()); + throw ex; } } 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 922781af56..6d06d4e17c 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 @@ -28,6 +28,10 @@ public class SchemalessWsTest { } catch (SQLException ex) { // handle any errors, please refer to the JDBC specifications for detailed exceptions info System.out.println("Failed to insert data with schemaless, host:" + host + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + throw ex; + } catch (Exception ex){ + System.out.println("Failed to insert data with schemaless, host:" + host + "; ErrMessage: " + ex.getMessage()); + throw ex; } } 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 9eca3c973a..2f58b3798a 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 @@ -50,6 +50,10 @@ public class WSParameterBindingBasicDemo { } 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()); + throw ex; + } catch (Exception ex){ + System.out.println("Failed to insert to table meters using stmt, url: " + jdbcUrl + "; ErrMessage: " + ex.getMessage()); + throw ex; } } 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 5d63ce8bf3..ad5ba5faf0 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 @@ -39,8 +39,11 @@ public class WSParameterBindingFullDemo { } 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()); + throw ex; + } catch (Exception ex){ + System.out.println("Failed to insert to table meters using stmt, url: " + jdbcUrl + "; ErrMessage: " + ex.getMessage()); + throw ex; } } 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 index 3ed0015359..726c795b7b 100644 --- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WsConsumerLoopFull.java +++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WsConsumerLoopFull.java @@ -6,10 +6,7 @@ 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.*; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; @@ -20,7 +17,7 @@ public class WsConsumerLoopFull { static private Statement statement; public static TaosConsumer getConsumer() throws SQLException { - // ANCHOR: create_consumer +// ANCHOR: create_consumer Properties config = new Properties(); config.setProperty("td.connect.type", "ws"); config.setProperty("bootstrap.servers", "localhost:6041"); @@ -29,7 +26,7 @@ public class WsConsumerLoopFull { 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("client.id", "1"); config.setProperty("td.connect.user", "root"); config.setProperty("td.connect.pass", "taosdata"); config.setProperty("value.deserializer", "com.taosdata.example.WsConsumerLoopFull$ResultDeserializer"); @@ -38,20 +35,19 @@ public class WsConsumerLoopFull { 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()); + // 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 ex) { + System.out.println("Failed to create websocket consumer, host : " + config.getProperty("bootstrap.servers") + + "; 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 +// ANCHOR_END: create_consumer } - public static void pollDataExample() throws SQLException { - try (TaosConsumer consumer = getConsumer()) { + public static void pollDataExample(TaosConsumer consumer) throws SQLException { + try{ // subscribe to the topics List topics = Collections.singletonList("topic_meters"); @@ -70,17 +66,18 @@ public class WsConsumerLoopFull { 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()); + // 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); + } catch (Exception ex) { + System.out.println("Failed to poll data from topic_meters; 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()) { + public static void pollExample(TaosConsumer consumer) throws SQLException { +// ANCHOR: poll_data_code_piece + try { List topics = Collections.singletonList("topic_meters"); // subscribe to the topics @@ -97,58 +94,51 @@ public class WsConsumerLoopFull { } } 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()); + // 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); + } catch (Exception ex) { + System.out.println("Failed to poll data; ErrMessage: " + ex.getMessage()); throw new SQLException("Failed to poll data", ex); } - // ANCHOR_END: poll_data_code_piece +// ANCHOR_END: poll_data_code_piece } - public static void seekExample() throws SQLException { - // ANCHOR: consumer_seek - try (TaosConsumer consumer = getConsumer()) { + public static void seekExample(TaosConsumer consumer) throws SQLException { +// ANCHOR: consumer_seek + try { List topics = Collections.singletonList("topic_meters"); // subscribe to the topics consumer.subscribe(topics); System.out.println("subscribe topics successfully"); + Set assignment = consumer.assignment(); + System.out.println("now assignment: " + JSON.toJSONString(assignment)); + 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 again - 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; - } + consumer.seekToBeginning(assignment); + System.out.println("assignment seek to beginning successfully"); + System.out.println("beginning assignment: " + JSON.toJSONString(assignment)); } 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()); + // 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); + } catch (Exception ex) { + System.out.println("seek example failed; ErrMessage: " + ex.getMessage()); throw new SQLException("seek example failed", ex); } - // ANCHOR_END: consumer_seek +// ANCHOR_END: consumer_seek } - public static void commitExample() throws SQLException { - // ANCHOR: commit_code_piece - try (TaosConsumer consumer = getConsumer()) { + + public static void commitExample(TaosConsumer consumer) throws SQLException { +// ANCHOR: commit_code_piece + try { List topics = Collections.singletonList("topic_meters"); consumer.subscribe(topics); @@ -165,32 +155,34 @@ public class WsConsumerLoopFull { } } } 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()); + // 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); + } catch (Exception ex) { + System.out.println("Failed to execute consumer functions. ErrMessage: " + ex.getMessage()); throw new SQLException("Failed to execute consumer functions", ex); } - // ANCHOR_END: commit_code_piece +// ANCHOR_END: commit_code_piece } - public static void unsubscribeExample() throws SQLException { - TaosConsumer consumer = getConsumer(); + public static void unsubscribeExample(TaosConsumer consumer) throws SQLException { List topics = Collections.singletonList("topic_meters"); consumer.subscribe(topics); - // ANCHOR: unsubscribe_data_code_piece +// 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()); + // 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 { + } catch (Exception ex) { + System.out.println("Failed to unsubscribe consumer. ErrMessage: " + ex.getMessage()); + throw new SQLException("Failed to unsubscribe consumer", ex); + } + finally { consumer.close(); } - // ANCHOR_END: unsubscribe_data_code_piece +// ANCHOR_END: unsubscribe_data_code_piece } public static class ResultDeserializer extends ReferenceDeserializer { @@ -255,20 +247,16 @@ public class WsConsumerLoopFull { } } - 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) "); - } + public static void prepareData() throws SQLException, InterruptedException { try { - int affectedRows = statement.executeUpdate(insertQuery.toString()); - assert affectedRows == 10000; + for (int i = 0; i < 3000; i++) { + String insertQuery = "INSERT INTO power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') VALUES (NOW + " + i + "a, 10.30000, 219, 0.31000) "; + int affectedRows = statement.executeUpdate(insertQuery); + assert affectedRows == 1; + Thread.sleep(1); + } } catch (SQLException ex) { - System.out.println("Failed to insert data to power.meters, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " - + ex.getMessage()); + 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); } } @@ -277,13 +265,10 @@ public class WsConsumerLoopFull { 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"); + 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()); + 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); } } @@ -297,15 +282,13 @@ public class WsConsumerLoopFull { try { connection = DriverManager.getConnection(url, properties); } catch (SQLException ex) { - System.out.println("Failed to create connection, url:" + url + "; ErrCode:" + ex.getErrorCode() - + "; ErrMessage: " + ex.getMessage()); + 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()); + 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."); @@ -317,8 +300,7 @@ public class WsConsumerLoopFull { statement.close(); } } catch (SQLException ex) { - System.out.println( - "Failed to close statement, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + System.out.println("Failed to close statement, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); throw new SQLException("Failed to close statement", ex); } @@ -327,14 +309,14 @@ public class WsConsumerLoopFull { connection.close(); } } catch (SQLException ex) { - System.out.println( - "Failed to close connection, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + 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 { + + public static void main(String[] args) throws SQLException, InterruptedException { initConnection(); prepareMeta(); @@ -345,14 +327,22 @@ public class WsConsumerLoopFull { executor.submit(() -> { try { // please use one example at a time - pollDataExample(); - // seekExample(); - // pollExample(); - // commitExample(); - unsubscribeExample(); + TaosConsumer consumer = getConsumer(); + + pollDataExample(consumer); + seekExample(consumer); + consumer.unsubscribe(); + pollExample(consumer); + consumer.unsubscribe(); + commitExample(consumer); + consumer.unsubscribe(); + unsubscribeExample(consumer); } catch (SQLException ex) { - System.out.println("Failed to poll data from topic_meters, ErrCode:" + ex.getErrorCode() - + "; ErrMessage: " + ex.getMessage()); + System.out.println("Failed to poll data from topic_meters, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage()); + return; + } catch (Exception ex) { + System.out.println("Failed to poll data from topic_meters, ErrMessage: " + ex.getMessage()); + return; } System.out.println("pollDataExample executed successfully"); }); From 45ca0f3256b2f23a78a9deec1a73025a893efc29 Mon Sep 17 00:00:00 2001 From: t_max <1172915550@qq.com> Date: Fri, 2 Aug 2024 19:07:58 +0800 Subject: [PATCH 15/15] docs: add C schemaless and stmt example --- docs/examples/c/CSmlInsertDemo.c | 122 ++++++++++++ docs/examples/c/CStmtInsertDemo.c | 175 ++++++++++++++++++ docs/zh/08-develop/04-schemaless.md | 3 + docs/zh/08-develop/05-stmt.md | 3 + docs/zh/14-reference/05-connector/20-go.mdx | 2 +- .../14-reference/05-connector/40-csharp.mdx | 2 +- 6 files changed, 305 insertions(+), 2 deletions(-) create mode 100644 docs/examples/c/CSmlInsertDemo.c create mode 100644 docs/examples/c/CStmtInsertDemo.c diff --git a/docs/examples/c/CSmlInsertDemo.c b/docs/examples/c/CSmlInsertDemo.c new file mode 100644 index 0000000000..96c76ac887 --- /dev/null +++ b/docs/examples/c/CSmlInsertDemo.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +// TAOS standard API example. The same syntax as MySQL, but only a subset +// to compile: gcc -o CSmlInsertDemo CSmlInsertDemo.c -ltaos + +#include +#include +#include +#include "taos.h" + + +static int DemoSmlInsert() { +// ANCHOR: schemaless +const char *ip = "localhost"; +const char *user = "root"; +const char *password = "taosdata"; + +// connect +TAOS *taos = taos_connect(ip, user, password, NULL, 0); +if (taos == NULL) { + printf("failed to connect to server, reason: %s\n", taos_errstr(NULL)); + taos_cleanup(); + return -1; +} + +// create database +TAOS_RES *result = taos_query(taos, "CREATE DATABASE IF NOT EXISTS power"); +int code = taos_errno(result); +if (code != 0) { + printf("failed to create database, reason: %s\n", taos_errstr(result)); + taos_close(taos); + taos_cleanup(); + return -1; +} +taos_free_result(result); +printf("success to create database\n"); + +// use database +result = taos_query(taos, "USE power"); +taos_free_result(result); + +// schemaless demo data +char * line_demo = "meters,groupid=2,location=California.SanFrancisco current=10.3000002f64,voltage=219i32,phase=0.31f64 1626006833639"; +char * telnet_demo = "metric_telnet 1707095283260 4 host=host0 interface=eth0"; +char * json_demo = "{\"metric\": \"metric_json\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}"; + +// influxdb line protocol +char *lines[] = {line_demo}; +result = taos_schemaless_insert(taos, lines, 1, TSDB_SML_LINE_PROTOCOL, TSDB_SML_TIMESTAMP_MILLI_SECONDS); +if (taos_errno(result) != 0) { + printf("failed to insert schemaless line data, reason: %s\n", taos_errstr(result)); + taos_close(taos); + taos_cleanup(); + return -1; +} + +int rows = taos_affected_rows(result); +printf("success to insert %d rows of schemaless line data\n", rows); +taos_free_result(result); + +// opentsdb telnet protocol +char *telnets[] = {telnet_demo}; +result = taos_schemaless_insert(taos, telnets, 1, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_MILLI_SECONDS); +if (taos_errno(result) != 0) { + printf("failed to insert schemaless telnet data, reason: %s\n", taos_errstr(result)); + taos_close(taos); + taos_cleanup(); + return -1; +} + +rows = taos_affected_rows(result); +printf("success to insert %d rows of schemaless telnet data\n", rows); +taos_free_result(result); + +// opentsdb json protocol +char *jsons[1] = {0}; +// allocate memory for json data. can not use static memory. +jsons[0] = malloc(1024); +if (jsons[0] == NULL) { + printf("failed to allocate memory\n"); + taos_close(taos); + taos_cleanup(); + return -1; +} +(void)strncpy(jsons[0], json_demo, 1023); +result = taos_schemaless_insert(taos, jsons, 1, TSDB_SML_JSON_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED); +if (taos_errno(result) != 0) { + free(jsons[0]); + printf("failed to insert schemaless json data, reason: %s\n", taos_errstr(result)); + taos_close(taos); + taos_cleanup(); + return -1; +} +free(jsons[0]); + +rows = taos_affected_rows(result); +printf("success to insert %d rows of schemaless json data\n", rows); +taos_free_result(result); + +// close & clean +taos_close(taos); +taos_cleanup(); +return 0; +// ANCHOR_END: schemaless +} + +int main(int argc, char *argv[]) { + return DemoSmlInsert(); +} diff --git a/docs/examples/c/CStmtInsertDemo.c b/docs/examples/c/CStmtInsertDemo.c new file mode 100644 index 0000000000..79c2485af2 --- /dev/null +++ b/docs/examples/c/CStmtInsertDemo.c @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +// TAOS standard API example. The same syntax as MySQL, but only a subset +// to compile: gcc -o CStmtInsertDemo CStmtInsertDemo.c -ltaos + +#include +#include +#include +#include +#include "taos.h" + +/** + * @brief execute sql only. + * + * @param taos + * @param sql + */ +void executeSQL(TAOS *taos, const char *sql) { + TAOS_RES *res = taos_query(taos, sql); + int code = taos_errno(res); + if (code != 0) { + printf("%s\n", taos_errstr(res)); + taos_free_result(res); + taos_close(taos); + exit(EXIT_FAILURE); + } + taos_free_result(res); +} + +/** + * @brief check return status and exit program when error occur. + * + * @param stmt + * @param code + * @param msg + */ +void checkErrorCode(TAOS_STMT *stmt, int code, const char *msg) { + if (code != 0) { + printf("%s. code: %d, error: %s\n", msg,code,taos_stmt_errstr(stmt)); + taos_stmt_close(stmt); + exit(EXIT_FAILURE); + } +} + +typedef struct { + int64_t ts; + float current; + int voltage; + float phase; +} Row; + +int num_of_sub_table = 10; +int num_of_row = 10; +/** + * @brief insert data using stmt API + * + * @param taos + */ +void insertData(TAOS *taos) { + // init + TAOS_STMT *stmt = taos_stmt_init(taos); + // prepare + const char *sql = "INSERT INTO ? USING meters TAGS(?,?) VALUES (?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + checkErrorCode(stmt, code, "failed to execute taos_stmt_prepare"); + for (int i = 1; i <= num_of_sub_table; i++) { + char table_name[20]; + sprintf(table_name, "d_bind_%d", i); + char location[20]; + sprintf(location, "location_%d", i); + + // set table name and tags + TAOS_MULTI_BIND tags[2]; + // groupId + tags[0].buffer_type = TSDB_DATA_TYPE_INT; + tags[0].buffer_length = sizeof(int); + tags[0].length = (int32_t *)&tags[0].buffer_length; + tags[0].buffer = &i; + tags[0].is_null = NULL; + tags[0].num = 1; + // location + tags[1].buffer_type = TSDB_DATA_TYPE_BINARY; + tags[1].buffer_length = strlen(location); + tags[1].length =(int32_t *) &tags[1].buffer_length; + tags[1].buffer = location; + tags[1].is_null = NULL; + tags[1].num = 1; + code = taos_stmt_set_tbname_tags(stmt, table_name, tags); + checkErrorCode(stmt, code, "failed to set table name and tags\n"); + + // insert rows + TAOS_MULTI_BIND params[4]; + // ts + params[0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[0].buffer_length = sizeof(int64_t); + params[0].length = (int32_t *)¶ms[0].buffer_length; + params[0].is_null = NULL; + params[0].num = 1; + // current + params[1].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[1].buffer_length = sizeof(float); + params[1].length = (int32_t *)¶ms[1].buffer_length; + params[1].is_null = NULL; + params[1].num = 1; + // voltage + params[2].buffer_type = TSDB_DATA_TYPE_INT; + params[2].buffer_length = sizeof(int); + params[2].length = (int32_t *)¶ms[2].buffer_length; + params[2].is_null = NULL; + params[2].num = 1; + // phase + params[3].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[3].buffer_length = sizeof(float); + params[3].length = (int32_t *)¶ms[3].buffer_length; + params[3].is_null = NULL; + params[3].num = 1; + + for (int j = 0; j < num_of_row; j++) { + struct timeval tv; + gettimeofday(&tv, NULL); + long long milliseconds = tv.tv_sec * 1000LL + tv.tv_usec / 1000; // current timestamp in milliseconds + int64_t ts = milliseconds + j; + float current = (float)rand() / RAND_MAX * 30; + int voltage = rand() % 300; + float phase = (float)rand() / RAND_MAX; + params[0].buffer = &ts; + params[1].buffer = ¤t; + params[2].buffer = &voltage; + params[3].buffer = &phase; + // bind param + code = taos_stmt_bind_param(stmt, params); + checkErrorCode(stmt, code, "failed to bind param"); + } + // add batch + code = taos_stmt_add_batch(stmt); + checkErrorCode(stmt, code, "failed to add batch"); + // execute batch + code = taos_stmt_execute(stmt); + checkErrorCode(stmt, code, "failed to exec stmt"); + // get affected rows + int affected = taos_stmt_affected_rows_once(stmt); + printf("table %s insert %d rows.\n", table_name, affected); + } + taos_stmt_close(stmt); +} + +int main() { + TAOS *taos = taos_connect("localhost", "root", "taosdata", NULL, 6030); + if (taos == NULL) { + printf("failed to connect to server\n"); + exit(EXIT_FAILURE); + } + // create database and table + executeSQL(taos, "CREATE DATABASE IF NOT EXISTS power"); + executeSQL(taos, "USE power"); + executeSQL(taos, + "CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS " + "(groupId INT, location BINARY(24))"); + insertData(taos); + taos_close(taos); + taos_cleanup(); +} \ No newline at end of file diff --git a/docs/zh/08-develop/04-schemaless.md b/docs/zh/08-develop/04-schemaless.md index 78456bb4a3..08c2ce70fb 100644 --- a/docs/zh/08-develop/04-schemaless.md +++ b/docs/zh/08-develop/04-schemaless.md @@ -234,6 +234,9 @@ writer.write(lineDemo, SchemalessProtocolType.LINE, SchemalessTimestampType.NANO ```
+```c +{{#include docs/examples/c/CSmlInsertDemo.c:schemaless}} +``` diff --git a/docs/zh/08-develop/05-stmt.md b/docs/zh/08-develop/05-stmt.md index f60e7b1705..c13fb96446 100644 --- a/docs/zh/08-develop/05-stmt.md +++ b/docs/zh/08-develop/05-stmt.md @@ -94,6 +94,9 @@ import TabItem from "@theme/TabItem"; ```
+```c +{{#include docs/examples/c/CStmtInsertDemo.c}} +``` diff --git a/docs/zh/14-reference/05-connector/20-go.mdx b/docs/zh/14-reference/05-connector/20-go.mdx index ff10a31124..a06c16c212 100644 --- a/docs/zh/14-reference/05-connector/20-go.mdx +++ b/docs/zh/14-reference/05-connector/20-go.mdx @@ -42,7 +42,7 @@ REST 连接支持所有能运行 Go 的平台。 } ``` -## TDengine DataType 和 Go DataType +## 数据类型映射 | TDengine DataType | Go Type | |-------------------|-----------| diff --git a/docs/zh/14-reference/05-connector/40-csharp.mdx b/docs/zh/14-reference/05-connector/40-csharp.mdx index 9ac4369c57..4ee2c748f7 100644 --- a/docs/zh/14-reference/05-connector/40-csharp.mdx +++ b/docs/zh/14-reference/05-connector/40-csharp.mdx @@ -44,7 +44,7 @@ TDengine 不再支持 32 位 Windows 平台。 `TDengine.Connector` 会抛出异常,应用程序需要处理异常。taosc 异常类型 `TDengineError`,包含错误码和错误信息,应用程序可以根据错误码和错误信息进行处理。 -## TDengine DataType 和 C# DataType +## 数据类型映射 | TDengine DataType | C# Type | |-------------------|------------------|