homework-jianmu/docs/zh/14-reference/05-connector/26-rust.mdx

1042 lines
38 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
toc_max_heading_level: 4
sidebar_label: Rust
title: TDengine Rust Connector
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import Preparation from "./_preparation.mdx"
import RequestId from "./_request_id.mdx";
[![Crates.io](https://img.shields.io/crates/v/taos)](https://crates.io/crates/taos) ![Crates.io](https://img.shields.io/crates/d/taos) [![docs.rs](https://img.shields.io/docsrs/taos)](https://docs.rs/taos)
`taos` 是 TDengine 的官方 Rust 语言连接器。Rust 开发人员可以通过它开发存取 TDengine 数据库的应用软件。
该 Rust 连接器的源码托管在 [GitHub](https://github.com/taosdata/taos-connector-rust)。
## 连接方式
`taos` 提供两种建立连接的方式。一般我们推荐使用 **Websocket 连接**。
- **原生连接**,它通过 TDengine 客户端驱动程序taosc连接 TDengine 运行实例。
- **Websocket 连接**,它通过 taosAdapter 的 Websocket 接口连接 TDengine 运行实例。
你可以通过不同的 “特性(即 Cargo 关键字 `features`)” 来指定使用哪种连接器(默认同时支持)。
连接方式的详细介绍请参考:[连接器建立连接的方式](../../develop/connect/#连接器建立连接的方式)
## 支持的平台
原生连接支持的平台和 TDengine 客户端驱动支持的平台一致。
Websocket 连接支持所有能运行 Rust 的平台。
## 版本历史
| Rust 连接器版本 | TDengine 版本 | 主要功能 |
| :----------------: | :--------------: | :--------------------------------------------------: |
| v0.12.0 | 3.2.3.0 or later | WS 支持压缩。 |
| v0.11.0 | 3.2.0.0 | TMQ 功能优化。 |
| v0.10.0 | 3.1.0.0 | WS endpoint 变更。 |
| v0.9.2 | 3.0.7.0 | STMTws 下获取 tag_fields、col_fields。 |
| v0.8.12 | 3.0.5.0 | 消息订阅:获取消费进度及按照指定进度开始消费。 |
| v0.8.0 | 3.0.4.0 | 支持无模式写入。 |
| v0.7.6 | 3.0.3.0 | 支持在请求中使用 req_id。 |
| v0.6.0 | 3.0.0.0 | 基础功能。 |
Rust 连接器仍然在快速开发中1.0 之前无法保证其向后兼容。建议使用 3.0 版本以上的 TDengine以避免已知问题。
## 处理错误
在报错后,可以获取到错误的具体信息:
```rust
match conn.exec(sql) {
Ok(_) => {
Ok(())
}
Err(e) => {
eprintln!("ERROR: {:?}", e);
Err(e)
}
}
```
## TDengine DataType 和 Rust DataType
TDengine 目前支持时间戳、数字、字符、布尔类型,与 Rust 对应类型转换如下:
| TDengine DataType | Rust DataType |
| ----------------- | ----------------- |
| TIMESTAMP | Timestamp |
| INT | i32 |
| BIGINT | i64 |
| FLOAT | f32 |
| DOUBLE | f64 |
| SMALLINT | i16 |
| TINYINT | i8 |
| BOOL | bool |
| BINARY | Vec\<u8> |
| NCHAR | String |
| JSON | serde_json::Value |
**注意**JSON 类型仅在 tag 中支持。
## 安装步骤
### 安装前准备
* 安装 Rust 开发工具链
* 如果使用原生连接,请安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../#安装客户端驱动)
### 安装连接器
根据选择的连接方式,按照如下说明在 [Rust](https://rust-lang.org) 项目中添加 [taos][taos] 依赖:
<Tabs defaultValue="default">
<TabItem value="default" label="同时支持">
在 `Cargo.toml` 文件中添加 [taos][taos]
```toml
[dependencies]
# use default feature
taos = "*"
```
</TabItem>
<TabItem value="rest" label="仅 Websocket">
在 `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"] }
```
</TabItem>
<TabItem value="native" label="仅原生连接">
在 `Cargo.toml` 文件中添加 [taos][taos],并启用 `native` 特性:
```toml
[dependencies]
taos = { version = "*", default-features = false, features = ["native"] }
```
</TabItem>
</Tabs>
## 建立连接
[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>][?<p1>=<v1>[&<p2>=<v2>]]
|------|------------|---|-----------|-----------|------|------|------------|-----------------------|
|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<Local>
ts: DateTime<Local>,
// float to f32
current: Option<f32>,
// int to i32
voltage: Option<i32>,
phase: Option<f32>,
groupid: i32,
// binary/varchar to String
location: String,
}
let records: Vec<Record> = 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
<RequestId />
```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> = TaosBuilder::from_dsn("taos:///")
.unwrap()
.pool()
.unwrap();
```
同样可以使用连接池的构造器,对连接池参数进行设置:
```rust
let pool: Pool<TaosBuilder> = 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` 下:
请参考:[rust example](https://github.com/taosdata/TDengine/tree/3.0/examples/rust)
## 常见问题
请参考 [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<Local>
ts: DateTime<Local>,
// float to f32
current: Option<f32>,
// int to i32
voltage: Option<i32>,
phase: Option<f32>,
groupid: i32,
// binary/varchar to String
location: String,
}
let records: Vec<Record> = 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 说明。
<p>
<a id="stmt-api" style={{color:'#141414'}}>
参数绑定接口
</a>
</p>
与 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(&params)?.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 关键字外基本相同。对于同步接口和异步接口功能一样的接口,本文档只提供同步接口的说明。
对于 WebSocket 连接和原生连接两种方式,除了建立连接的 DSN 不同,其余接口调用没有区别。
### 连接功能
#### DSN
TaosBuilder 通过 DSN 连接描述字符串创建一个连接构造器。
DSN 描述字符串基本结构如下:
```text
<driver>[+<protocol>]://[[<username>:<password>@]<host>:<port>][/<database>][?<p1>=<v1>[&<p2>=<v2>]]
|------|------------|---|-----------|-----------|------|------|------------|-----------------------|
|driver| protocol | | username | password | host | port | database | params |
```
各部分意义见下表:
- **driver**: 必须指定驱动名以便连接器选择何种方式创建连接,支持如下驱动名:
- **taos**: 表名使用 TDengine 连接器驱动。
- **tmq**: 使用 TMQ 订阅数据。
- **http/ws**: 使用 Websocket 创建连接。
- **https/wss**: 在 Websocket 连接方式下显示启用 SSL/TLS 连接。
- **protocol**: 显示指定以何种方式建立连接,例如:`taos+ws://localhost:6041` 指定以 Websocket 方式建立连接。
- **username/password**: 用于创建连接的用户名及密码。
- **host/port**: 指定创建连接的服务器及端口,当不指定服务器地址及端口时(`taos://`),原生连接默认为 `localhost:6030`Websocket 连接默认为 `localhost:6041` 。
- **database**: 指定默认连接的数据库名,可选参数。
- **params**:其他可选参数。
一个完整的 DSN 描述字符串示例如下:`taos+ws://localhost:6041/test` 表示使用 Websocket`ws`)方式通过 `6041` 端口连接服务器 `localhost`,并指定默认数据库为 `test`。
#### TaosBuilder
TaosBuilder 结构体主要提供了根据 DSN 构建 Taos 对象的方法,还提供了检查连接,以及获取客户端版本号等功能。
- `fn available_params() -> &'static [&'static str]`
- **接口说明**:获取 DSN 中可用的参数列表。
- **返回值**:返回静态字符串切片的引用,包含可用的参数名称。
- `fn from_dsn<D: IntoDsn>(dsn: D) -> RawResult<Self>`
- **接口说明**:使用 DSN 字符串创建连接,不检查连接。
- **参数说明**
- `dsn`DSN 字符串或可转换为 DSN 的类型。
- **返回值**:成功时返回自身类型的 `RawResult`,失败时返回错误。
- `fn client_version() -> &'static str`
- **接口说明**:获取客户端版本。
- **返回值**:返回客户端版本的静态字符串。
- `fn ping(&self, _: &mut Self::Target) -> RawResult<()>`
- **接口说明**:检查连接是否仍然存活。
- **参数说明**
- `_`:目标连接的可变引用。
- **返回值**:成功时返回空的 `RawResult`,失败时返回错误。
- `fn ready(&self) -> bool`
- **接口说明**:检查是否准备好连接。
- **返回值**:大多数情况下返回 `true`,表示地址准备好连接。
- `fn build(&self) -> RawResult<Self::Target>`
- **接口说明**:从此结构创建新的 Taos 对象。
- **返回值**:成功时返回目标连接类型的 `RawResult`,失败时返回错误。
### 执行 SQL
执行 SQL 主要使用 Taos 结构体,获取结果集以及元数据需要使用下节介绍的 ResultSet 结构体 和列信息 Field 结构体。
#### Taos
Taos 结构体提供了多个数据库操作的 API包括执行 SQL无模式写入以及一些常用数据库查询的封装如创建数据库获取
- `pub fn is_native(&self) -> bool`
- **接口说明**:判断连接是否使用本地协议。
- **返回值**:如果使用本地协议,则返回 `true`,否则返回 `false`。
- `pub fn is_ws(&self) -> bool`
- **接口说明**判断连接是否使用websocket协议。
- **返回值**如果使用websocket协议则返回 `true`,否则返回 `false`。
- `fn query<T: AsRef<str>>(&self, sql: T) -> RawResult<Self::ResultSet>`
- **接口说明**:执行 SQL 查询。
- **参数说明**
- `sql`:要执行的 SQL 语句。
- **返回值**:成功时返回结果集 `ResultSet` 的 `RawResult`,失败时返回错误。
- `fn query_with_req_id<T: AsRef<str>>(&self, sql: T, req_id: u64) -> RawResult<Self::ResultSet>`
- **接口说明**:带请求 ID 执行 SQL 查询。
- **参数说明**
- `sql`:要执行的 SQL 语句。
- `req_id`:请求 ID。
- **返回值**:成功时返回结果集 `ResultSet` 的 `RawResult`,失败时返回错误。
- `fn exec<T: AsRef<str>>(&self, sql: T) -> RawResult<usize>`
- **接口说明**:执行 SQL 语句。
- **参数说明**
- `sql`:要执行的 SQL 语句。
- **返回值**:成功时返回受影响的行数,失败时返回错误。
- `fn exec_many<T: AsRef<str>, I: IntoIterator<Item = T>>(&self, input: I) -> RawResult<usize>`
- **接口说明**:批量执行 SQL 语句。
- **参数说明**
- `input`:要执行的 SQL 语句集合。
- **返回值**:成功时返回总共受影响的行数,失败时返回错误。
- `fn query_one<T: AsRef<str>, O: DeserializeOwned>(&self, sql: T) -> RawResult<Option<O>>`
- **接口说明**:执行 SQL 查询并返回单个结果。
- **参数说明**
- `sql`:要执行的 SQL 语句。
- **返回值**:成功时返回可选的结果对象,失败时返回错误。
- `fn server_version(&self) -> RawResult<Cow<str>>`
- **接口说明**:获取服务器版本。
- **返回值**:成功时返回服务器版本字符串的 `RawResult`,失败时返回错误。
- `fn create_topic(&self, name: impl AsRef<str>, sql: impl AsRef<str>) -> RawResult<()>`
- **接口说明**:创建主题。
- **参数说明**
- `name`:主题名称。
- `sql`:关联的 SQ L语句。
- **返回值**:成功时返回空的 `RawResult`,失败时返回错误。
- `fn databases(&self) -> RawResult<Vec<ShowDatabase>>`
- **接口说明**:获取数据库列表。
- **返回值**:成功时返回数据库列表的 `RawResult`,失败时返回错误。
- `fn topics(&self) -> RawResult<Vec<Topic>>`
- **接口说明**:获取主题信息。
- **返回值**:成功时返回主题列表的 `RawResult`,失败时返回错误。
- `fn describe(&self, table: &str) -> RawResult<Describe>`
- **接口说明**:描述表结构。
- **参数说明**
- `table`:表名称。
- **返回值**:成功时返回表结构描述的 `RawResult`,失败时返回错误。
- `fn database_exists(&self, name: &str) -> RawResult<bool>`
- **接口说明**:检查数据库是否存在。
- **参数说明**
- `name`:数据库名称。
- **返回值**:成功时返回布尔值的 `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<String>`
- **接口说明**:获取数据列表。
- **返回值**:数据列表的引用。
- `pub fn ttl(&self) -> Option<i32>`
- **接口说明**:获取数据存活时间。
- **返回值**:数据存活时间(可选),单位为秒。
- `pub fn req_id(&self) -> Option<u64>`
- **接口说明**:获取请求 ID。
- **返回值**:请求 ID可选
### 结果获取
#### ResultSet
ResultSet 结构体提供了结果集的一些方法,可以用来获取结果集的数据和元数据。
- `fn affected_rows(&self) -> i32`
- **接口说明**:获取受影响的行数。
- **返回值**:受影响的行数,类型为 `i32`。
- `fn precision(&self) -> Precision`
- **接口说明**:获取精度信息。
- **返回值**:精度信息,类型为 `Precision`。
- `fn fields(&self) -> &[Field]`
- **接口说明**:获取字段信息。见下文 Feild 结构体描述。
- **返回值**:字段信息数组的引用。
- `fn summary(&self) -> (usize, usize)`
- **接口说明**:获取摘要信息。
- **返回值**:包含两个 `usize` 类型的元组,分别表示某些统计信息。
- `fn num_of_fields(&self) -> usize`
- **接口说明**:获取字段数量。
- **返回值**:字段数量,类型为 `usize`。
- `fn blocks(&mut self) -> IBlockIter<'_, Self>`
- **接口说明**:获取原始数据块的迭代器。
- **返回值**:原始数据块的迭代器,类型为 `IBlockIter<'_, Self>`。
- `fn rows(&mut self) -> IRowsIter<'_, Self>`
- **接口说明**:获取按行查询的迭代器。
- **返回值**:按行查询的迭代器,类型为 `IRowsIter<'_, Self>`。
- `fn deserialize<T>(&mut self) -> Map<IRowsIter<'_, Self>, fn(_: Result<RowView<'_>, Error>) -> Result<T, Error>>`
- **接口说明**:反序列化行数据。
- **泛型参数**
- `T`:目标类型,需实现 `DeserializeOwned`。
- **返回值**:反序列化结果的映射,类型为 `Map<IRowsIter<'_, Self>, fn(_: Result<RowView<'_>, Error>) -> Result<T, Error>>`。
- `fn to_rows_vec(&mut self) -> Result<Vec<Vec<Value>>, Error>`
- **接口说明**:将结果集转换为值的二维向量。
- **返回值**:成功时返回值的二维向量,失败时返回错误,类型为 `Result<Vec<Vec<Value>>, Error>`。
#### Feild
Feild 结构体提供了字段信息的一些方法。
- `pub const fn empty() -> Field`
- **接口说明**:创建一个空的 `Field` 实例。
- **返回值**:返回一个空的 `Field` 实例。
- `pub fn new(name: impl Into<String>, ty: Ty, bytes: u32) -> Field`
- **接口说明**:创建一个新的 `Field` 实例。
- **参数说明**
- `name`:字段名称。
- `ty`:字段类型。
- `bytes`:字段数据长度。
- **返回值**:返回一个新的 `Field` 实例。
- `pub fn name(&self) -> &str`
- **接口说明**:获取字段名称。
- **返回值**:返回字段的名称。
- `pub fn escaped_name(&self) -> String`
- **接口说明**:获取转义后的字段名称。
- **返回值**:返回转义后的字段名称。
- `pub const fn ty(&self) -> Ty`
- **接口说明**:获取字段类型。
- **返回值**:返回字段的类型。
- `pub const fn bytes(&self) -> u32`
- **接口说明**:获取字段的预设长度。
- **返回值**:对于变长数据类型,返回其预设长度;对于其他类型,返回其字节宽度。
- `pub fn to_c_field(&self) -> c_field_t`
- **接口说明**:将 `Field` 实例转换为 C 语言结构体。
- **返回值**:返回 C 语言结构体表示的字段。
- `pub fn sql_repr(&self) -> String`
- **接口说明**:表示字段在 SQL 中的数据类型。
- **返回值**:例如:"INT", "VARCHAR(100)" 等 SQL 数据类型表示。
### 参数绑定
参数绑定功能主要由 Stmt 结构体支持。
#### Stmt
Stmt 结构体提供了参数绑定相关功能,用于实现高效写入。
- `fn init(taos: &Q) -> RawResult<Self>`
- **接口说明**:初始化参数绑定实例。
- **参数说明**
- `taos`:数据库连接实例。
- **返回值**:成功时返回初始化的实例,失败时返回错误。
- `fn init_with_req_id(taos: &Q, req_id: u64) -> RawResult<Self>`
- **接口说明**:使用请求 ID 初始化参数绑定实例。
- **参数说明**
- `taos`:数据库连接实例。
- `req_id`:请求 ID。
- **返回值**:成功时返回初始化的实例,失败时返回错误。
- `fn prepare<S: AsRef<str>>(&mut self, sql: S) -> RawResult<&mut Self>`
- **接口说明**:准备要绑定的 SQL 语句。
- **参数说明**
- `sql`:要准备的 SQL 语句。
- **返回值**:成功时返回自身的可变引用,失败时返回错误。
- `fn set_tbname<S: AsRef<str>>(&mut self, name: S) -> RawResult<&mut Self>`
- **接口说明**:设置表名称。
- **参数说明**
- `name`:表名称。
- **返回值**:成功时返回自身的可变引用,失败时返回错误。
- `fn set_tags(&mut self, tags: &[Value]) -> RawResult<&mut Self>`
- **接口说明**:设置标签。
- **参数说明**
- `tags`:标签数组。
- **返回值**:成功时返回自身的可变引用,失败时返回错误。
- `fn set_tbname_tags<S: AsRef<str>>(&mut self, name: S, tags: &[Value]) -> RawResult<&mut Self>`
- **接口说明**:设置表名称和标签。
- **参数说明**
- `name`:表名称。
- `tags`:标签数组。
- **返回值**:成功时返回自身的可变引用,失败时返回错误。
- `fn bind(&mut self, params: &[ColumnView]) -> RawResult<&mut Self>`
- **接口说明**:绑定参数。
- **参数说明**
- `params`:参数数组。
- **返回值**:成功时返回自身的可变引用,失败时返回错误。
- `fn add_batch(&mut self) -> RawResult<&mut Self>`
- **接口说明**:添加批处理。
- **返回值**:成功时返回自身的可变引用,失败时返回错误。
- `fn execute(&mut self) -> RawResult<usize>`
- **接口说明**:执行语句。
- **返回值**:成功时返回受影响的行数,失败时返回错误。
- `fn affected_rows(&self) -> usize`
- **接口说明**:获取受影响的行数。
- **返回值**:受影响的行数。
### 数据订阅
数据订阅主要涉及三个结构体,提供连接建立的 TmqBuilder 消费数据和提交偏移量的 Consumer以及偏移量 Offset。
#### TmqBuilder
同 TaosBuilder 类似TmqBuilder 提供了创建消费者对象的功能。
- `fn available_params() -> &'static [&'static str]`
- **接口说明**:获取 DSN 中可用的参数列表。
- **返回值**:返回静态字符串切片的引用,包含可用的参数名称。
- `fn from_dsn<D: IntoDsn>(dsn: D) -> RawResult<Self>`
- **接口说明**:使用 DSN 字符串创建连接,不检查连接。
- **参数说明**
- `dsn`DSN 字符串或可转换为DSN的类型。
- **返回值**:成功时返回自身类型的 `RawResult`,失败时返回错误。
- `fn client_version() -> &'static str`
- **接口说明**:获取客户端版本。
- **返回值**:返回客户端版本的静态字符串。
- `fn ping(&self, conn: &mut Self::Target) -> RawResult<()>`
- **接口说明**:检查连接是否仍然存活。
- **参数说明**
- `conn`:目标连接的可变引用。
- **返回值**:成功时返回空的 `RawResult`,失败时返回错误。
- `fn ready(&self) -> bool`
- **接口说明**:检查是否准备好连接。
- **返回值**:大多数情况下返回 `true`,表示地址准备好连接。
- `fn build(&self) -> RawResult<Self::Target>`
- **接口说明**:从此结构创建新的连接。
- **返回值**:成功时返回目标连接类型的 `RawResult`,失败时返回错误。
#### Consumer
Consumer 结构体提供了订阅相关的功能,包括订阅,获取消息,提交偏移量,设置偏移量等。
- `fn subscribe<T: Into<String>, I: IntoIterator<Item = T> + Send>(&mut self, topics: I) -> RawResult<()>`
- **接口说明**:订阅一系列主题。
- **参数说明**
- `topics`:要订阅的主题列表。
- **返回值**:成功时返回空的 `RawResult`,失败时返回错误。
- `fn recv_timeout(&self, timeout: Timeout) -> RawResult<Option<(Self::Offset, MessageSet<Self::Meta, Self::Data>)>>`
- **接口说明**:在指定超时时间内接收消息。
- **参数说明**
- `timeout`:超时时间。
- **返回值**:成功时返回消息,失败时返回错误。
- `fn commit(&self, offset: Self::Offset) -> RawResult<()>`
- **接口说明**:提交给定的偏移量。
- **参数说明**
- `offset`:要提交的偏移量,见下文 Offset 结构体。
- **返回值**:成功时返回空的 `RawResult`,失败时返回错误。
- `fn commit_offset(&self, topic_name: &str, vgroup_id: VGroupId, offset: i64) -> RawResult<()>`
- **接口说明**:为特定主题和分区提交偏移量。
- **参数说明**
- `topic_name`:主题名称。
- `vgroup_id`:分区 ID。
- `offset`:要提交的偏移量。
- **返回值**:成功时返回空的 `RawResult`,失败时返回错误。
- `fn list_topics(&self) -> RawResult<Vec<String>>`
- **接口说明**:列出所有可用主题。
- **返回值**:成功时返回主题列表,失败时返回错误。
- `fn assignments(&self) -> Option<Vec<(String, Vec<Assignment>)>>`
- **接口说明**:获取当前分配的主题和分区。
- **返回值**:成功时返回分配信息,失败时返回 `None`。
- `fn offset_seek(&mut self, topic: &str, vg_id: VGroupId, offset: i64) -> RawResult<()>`
- **接口说明**:为特定主题和分区设置偏移量。
- **参数说明**
- `topic`:主题名称。
- `vg_id`:分区 ID。
- `offset`:要设置的偏移量。
- **返回值**:成功时返回空的 `RawResult`,失败时返回错误。
- `fn committed(&self, topic: &str, vgroup_id: VGroupId) -> RawResult<i64>`
- **接口说明**:获取特定主题和分区的已提交偏移量。
- **参数说明**
- `topic`:主题名称。
- `vgroup_id`:分区 ID。
- **返回值**:成功时返回偏移量,失败时返回错误。
- `fn position(&self, topic: &str, vgroup_id: VGroupId) -> RawResult<i64>`
- **接口说明**:获取特定主题和分区的当前位置。
- **参数说明**
- `topic`:主题名称。
- `vgroup_id`:分区 ID。
- **返回值**:成功时返回当前位置,失败时返回错误。
#### Offset
Offset 结构体提供了获取当前消息所属的数据库,主题和分区信息。
- `fn database(&self) -> &str`
- **接口说明**:获取当前消息的数据库名称。
- **返回值**:数据库名称的引用。
- `fn topic(&self) -> &str`
- **接口说明**:获取当前消息的主题名称。
- **返回值**:主题名称的引用。
- `fn vgroup_id(&self) -> VGroupId`
- **接口说明**:获取当前消息的分区 ID。
- **返回值**:分区 ID。
## 附录
- 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