From 5aa94ea90c844b6724f7bd5b2ce93298fdf47d8d Mon Sep 17 00:00:00 2001
From: sheyanjie-qq <249478495@qq.com>
Date: Fri, 2 Aug 2024 14:02:22 +0800
Subject: [PATCH] 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 42da8b8352..48af1f7a63 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/#连接功能)
+
@@ -387,7 +397,9 @@ URL 和 Properties 的详细参数说明和如何使用详见 [API 说明](../..
-
+```rust
+{{#include docs/examples/rust/restexample/examples/connect.rs}}
+```
```js
@@ -424,7 +436,10 @@ URL 和 Properties 的详细参数说明和如何使用详见 [API 说明](../..
-
+```rust
+{{#include docs/examples/rust/nativeexample/examples/connect.rs}}
+```
+
@@ -459,7 +474,7 @@ URL 和 Properties 的详细参数说明和如何使用详见 [API 说明](../..
-
+不支持
@@ -519,7 +534,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 787a3378ad..f24a35eb75 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}}
+```
+
@@ -45,6 +49,7 @@ TDengine 对 SQL 语言提供了全面的支持,允许用户以熟悉的 SQL
+> **注意**:如果不使用 `USE power` 指定数据库,则后续对表的操作都需要增加数据库名称作为前缀,如 `power.meters`。
## 插入数据
下面以智能电表为例,展示如何使用连接器执行 SQL 来插入数据到 `power` 数据库的 `meters` 超级表。样例使用 TDengine 自动建表 SQL 语法,写入 d1001 子表中 3 条数据,写入 d1002 子表中 1 条数据,然后打印出实际插入数据条数。
@@ -65,6 +70,11 @@ NOW 为系统内部函数,默认为客户端所在计算机当前时间。 NOW
+
+```rust
+{{#include docs/examples/rust/nativeexample/examples/query.rs:insert_data}}
+```
+
@@ -100,6 +110,11 @@ NOW 为系统内部函数,默认为客户端所在计算机当前时间。 NOW
+
+```rust
+{{#include docs/examples/rust/nativeexample/examples/query.rs:query_data}}
+```
+
@@ -140,6 +155,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