rust.mdx 11.4 KB
Newer Older
D
dingbo 已提交
1 2 3 4 5 6 7 8 9 10 11
---
toc_max_heading_level: 4
sidebar_position: 5
sidebar_label: Rust
title: TDengine Rust Connector
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

import Preparition from "./_preparition.mdx"
12 13 14 15 16
import RustInsert from "../../07-develop/03-insert-data/_rust_sql.mdx"
import RustInfluxLine from "../../07-develop/03-insert-data/_rust_line.mdx"
import RustOpenTSDBTelnet from "../../07-develop/03-insert-data/_rust_opts_telnet.mdx"
import RustOpenTSDBJson from "../../07-develop/03-insert-data/_rust_opts_json.mdx"
import RustQuery from "../../07-develop/04-query-data/_rust.mdx"
D
dingbo 已提交
17

18
`libtaos` is the official Rust language connector for TDengine. Rust developers can develop applications to access the TDengine instance data.
D
dingbo 已提交
19

20
`libtaos` provides two ways to establish connections. One is the **Native Connection**, which connects to TDengine instances via the TDengine client driver (taosc). The other is **REST connection**, which connects to TDengine instances via taosAdapter's REST interface.
D
dingbo 已提交
21

22
The source code for `libtaos` is hosted on [GitHub](https://github.com/taosdata/libtaos-rs).
D
dingbo 已提交
23

24
## Supported platforms
D
dingbo 已提交
25

26 27
The platforms supported by native connections are the same as those supported by the TDengine client driver.
REST connections are supported on all platforms that can run Rust.
D
dingbo 已提交
28

29
## Version support
D
dingbo 已提交
30

31
Please refer to [version support list](/reference/connector#version-support).
D
dingbo 已提交
32

33
The Rust Connector is still under rapid development and is not guaranteed to be backward compatible before 1.0. Recommend to use TDengine version 2.4 or higher to avoid known issues.
D
dingbo 已提交
34

35
## Installation
D
dingbo 已提交
36

37 38
### Pre-installation
* Install the Rust development toolchain
39
* If using the native connection, please install the TDengine client driver. Please refer to [install client driver](/reference/connector#install-client-driver)
D
dingbo 已提交
40

41
### Adding libtaos dependencies
D
dingbo 已提交
42

43
Add the [libtaos][libtaos] dependency to the [Rust](https://rust-lang.org) project as follows, depending on the connection method selected.
D
dingbo 已提交
44 45

<Tabs defaultValue="native">
46
<TabItem value="native" label="native connection">
D
dingbo 已提交
47

48
Add [libtaos][libtaos] to the ``Cargo.toml`'' file.
D
dingbo 已提交
49

50
``toml
D
dingbo 已提交
51 52 53 54 55
[dependencies]
# use default feature
libtaos = "*"
```

56 57
</TabItem
<TabItem value="rest" label="REST connection">
D
dingbo 已提交
58

59
Add [libtaos][libtaos] to the `Cargo.toml` file and enable the `rest` feature.
D
dingbo 已提交
60 61 62 63 64 65 66 67 68 69 70

```toml
[dependencies]
# use rest feature
libtaos = { version = "*", features = ["rest"]}
```

</TabItem>
</Tabs>


71
### Using connection pools
D
dingbo 已提交
72

73
Please enable the `r2d2` feature in `Cargo.toml`.
D
dingbo 已提交
74 75 76 77 78 79 80 81 82

```toml
[dependencies]
# with taosc
libtaos = { version = "*", features = ["r2d2"] }
# or rest
libtaos = { version = "*", features = ["rest", "r2d2"] }
```

83
## Create a connection
D
dingbo 已提交
84

85
The [TaosCfgBuilder] provides the user with an API in the form of a constructor for the subsequent creation of connections or use of connection pools.
D
dingbo 已提交
86 87 88 89 90 91 92 93 94 95 96 97 98

```rust
let cfg: TaosCfg = TaosCfgBuilder::default()
    .ip("127.0.0.1")
    .user("root")
    .pass("taosdata")
    .db("log") // do not set if not require a default database.
    .port(6030u16)
    .build()
    .expect("TaosCfg builder error");
}
```

99
You can now use this object to create the connection.
D
dingbo 已提交
100 101

```rust
102
let conn = cfg.connect()? ;
D
dingbo 已提交
103 104
```

105
The connection object can create more than one.
D
dingbo 已提交
106 107

```rust
108 109
let conn = cfg.connect()? ;
let conn2 = cfg.connect()? ;
D
dingbo 已提交
110 111
```

112
You can use connection pools in applications.
D
dingbo 已提交
113 114 115 116

```rust
let pool = r2d2::Pool::builder()
    .max_size(10000) // max connections
117
    .build(cfg)? ;
D
dingbo 已提交
118 119 120

// ...
// Use pool to get connection
121
let conn = pool.get()? ;
D
dingbo 已提交
122 123
```

124
After that, you can perform the following operations on the database.
D
dingbo 已提交
125 126 127 128 129 130

```rust
async fn demo() -> Result<(), Error> {
    // get connection ...

    // create database
131
    conn.exec("create database if not exists demo").await?
D
dingbo 已提交
132
    // change database context
133
    conn.exec("use demo").await?
D
dingbo 已提交
134
    // create table
135
    conn.exec("create table if not exists tb1 (ts timestamp, v int)").await?
D
dingbo 已提交
136
    // insert
137
    conn.exec("insert into tb1 values(now, 1)").await?
D
dingbo 已提交
138
    // query
139
    let rows = conn.query("select * from tb1").await?
D
dingbo 已提交
140 141 142 143 144 145
    for row in rows.rows {
        println!("{}", row.into_iter().join(","));
    }
}
```

146
## Usage examples
D
dingbo 已提交
147

148
### Write data
D
dingbo 已提交
149

150
#### SQL Write
D
dingbo 已提交
151 152 153

<RustInsert />

154
#### InfluxDB line protocol write
D
dingbo 已提交
155 156 157

<RustInfluxLine />

158
#### OpenTSDB Telnet line protocol write
D
dingbo 已提交
159 160 161

<RustOpenTSDBTelnet />

162
#### OpenTSDB JSON line protocol write
D
dingbo 已提交
163 164 165

<RustOpenTSDBJson />

166
### Query data
D
dingbo 已提交
167 168 169

<RustQuery />

170
### More sample programs
D
dingbo 已提交
171

172
| Program Path | Program Description |
D
dingbo 已提交
173
| -------------- | ----------------------------------------------------------------------------- |
174 175
| [demo.rs] | Basic API Usage Examples |
| [bailongma-rs] | Using TDengine as the Prometheus remote storage API adapter for the storage backend, using the r2d2 connection pool |
D
dingbo 已提交
176

177
## API Reference
D
dingbo 已提交
178

179
### Connection constructor API
D
dingbo 已提交
180

181
The [Builder Pattern](https://doc.rust-lang.org/1.0.0/style/ownership/builders.html) constructor pattern is Rust's solution for handling complex data types or optional configuration types. The [libtaos] implementation uses the connection constructor [TaosCfgBuilder] as the entry point for the TDengine Rust connector. The [TaosCfgBuilder] provides optional configuration of servers, ports, databases, usernames, passwords, etc.
D
dingbo 已提交
182

183
Using the `default()` method, you can construct a [TaosCfg] with default parameters for subsequent connections to the database or establishing connection pools.
D
dingbo 已提交
184 185

```rust
186
let cfg = TaosCfgBuilder::default().build()? ;
D
dingbo 已提交
187 188
```

189
Using the constructor pattern, the user can set on-demand.
D
dingbo 已提交
190 191 192 193 194 195 196 197

```rust
let cfg = TaosCfgBuilder::default()
    .ip("127.0.0.1")
    .user("root")
    .pass("taosdata")
    .db("log")
    .port(6030u16)
198
    .build()? ;
D
dingbo 已提交
199 200
```

201
Create TDengine connection using [TaosCfg] object.
D
dingbo 已提交
202 203 204 205 206

```rust
let conn: Taos = cfg.connect();
```

207
### Connection pooling
D
dingbo 已提交
208

209
In complex applications, recommand to enable connection pool. Connection pool for [libtaos] is implemented using [r2d2].
D
dingbo 已提交
210

211
As follows, a connection pool with default parameters can be generated.
D
dingbo 已提交
212 213

```rust
214
let pool = r2d2::Pool::new(cfg)? ;
D
dingbo 已提交
215 216
```

217
You can set the same connection pool parameters using the connection pool's constructor.
D
dingbo 已提交
218 219 220 221 222 223 224 225 226 227 228

```rust
    use std::time::Duration;
    let pool = r2d2::Pool::builder()
        .max_size(5000) // max connections
        .max_lifetime(Some(Duration::from_minutes(100))) // lifetime of each connection
        .min_idle(Some(1000)) // minimal idle connections
        .connection_timeout(Duration::from_minutes(2))
        .build(cfg);
```

229
In the application code, use `pool.get()? ` to get a connection object [Taos].
D
dingbo 已提交
230 231

```rust
232
let taos = pool.get()? ;
D
dingbo 已提交
233 234
```

235
The [Taos] structure is the connection manager in [libtaos] and provides two main APIs.
D
dingbo 已提交
236

237
1. `exec`: Execute some non-query SQL statements, such as `CREATE`, `ALTER`, `INSERT`, etc.
D
dingbo 已提交
238 239

    ```rust
240
    taos.exec().await?
D
dingbo 已提交
241 242
    ```

243
2. `query`: Execute the query statement and return the [TaosQueryData] object.
D
dingbo 已提交
244 245

    ```rust
246
    let q = taos.query("select * from log.logs").await?
D
dingbo 已提交
247 248
    ```

249
    The [TaosQueryData] object stores the query result data and basic information about the returned columns (column name, type, length).
D
dingbo 已提交
250

251
    Column information is stored using [ColumnMeta].
D
dingbo 已提交
252

253
    ``rust
D
dingbo 已提交
254 255
    let cols = &q.column_meta;
    for col in cols {
256
        println!("name: {}, type: {:?} , bytes: {}", col.name, col.type_, col.bytes);
D
dingbo 已提交
257 258 259
    }
    ```

260
    It fetches data line by line.
D
dingbo 已提交
261 262 263 264 265 266 267 268 269

    ```rust
    for (i, row) in q.rows.iter().enumerate() {
        for (j, cell) in row.iter().enumerate() {
            println!("cell({}, {}) data: {}", i, j, cell);
        }
    }
    ```

270
Note that Rust asynchronous functions and an asynchronous runtime are required.
D
dingbo 已提交
271

272
[Taos] provides partial Rust methodization of SQL to reduce the frequency of `format!` code blocks.
D
dingbo 已提交
273

274 275 276
- `.describe(table: &str)`: Executes `DESCRIBE` and returns a Rust data structure.
- `.create_database(database: &str)`: Executes the `CREATE DATABASE` statement.
- `.use_database(database: &str)`: Executes the `USE` statement.
D
dingbo 已提交
277

278
In addition, this structure is also the entry point for [Parameter Binding](#Parameter Binding Interface) and [Line Protocol Interface](#Line Protocol Interface). Please refer to the specific API descriptions for usage.
D
dingbo 已提交
279

280
### Bind Interface
D
dingbo 已提交
281

282
Similar to the C interface, Rust provides the bind interface's wraping. First, create a bind object [Stmt] for a SQL command from the [Taos] object.
D
dingbo 已提交
283 284

```rust
285
let mut stmt: Stmt = taos.stmt("insert into ? values(? ,?)") ? ;
D
dingbo 已提交
286 287
```

288
The bind object provides a set of interfaces for implementing parameter binding.
D
dingbo 已提交
289 290 291

##### `.set_tbname(tbname: impl ToCString)`

292
To bind table names.
D
dingbo 已提交
293 294 295

##### `.set_tbname_tags(tbname: impl ToCString, tags: impl IntoParams)`

296
Bind sub-table table names and tag values when the SQL statement uses a super table.
D
dingbo 已提交
297 298

```rust
299
let mut stmt = taos.stmt("insert into ? using stb0 tags(?) values(? ,?)") ? ;
D
dingbo 已提交
300
// tags can be created with any supported type, here is an example using JSON
301 302
let v = Field::Json(serde_json::from_str("{\"tag1\":\"one, two, three, four, five, six, seven, eight, nine, ten\"}").unwrap());
stmt.set_tbname_tags("tb0", [&tag])? ;
D
dingbo 已提交
303 304 305 306
```

##### `.bind(params: impl IntoParams)`

307
Bind value types. Use the [Field] structure to construct the desired type and bind.
D
dingbo 已提交
308 309 310 311

```rust
let ts = Field::Timestamp(Timestamp::now());
let value = Field::Float(0.0);
312
stmt.bind(vec![ts, value].iter())? ;
D
dingbo 已提交
313 314 315 316
```

##### `.execute()`

317
Execute SQL.[Stmt] objects can be reused, re-binded, and executed after execution.
D
dingbo 已提交
318 319

```rust
320
stmt.execute()? ;
D
dingbo 已提交
321 322

// next bind cycle.
323 324 325
// stmt.set_tbname()? ;
//stmt.bind()? ;
//stmt.execute()? ;
D
dingbo 已提交
326 327
```

328
### Line protocol interface
D
dingbo 已提交
329

330
The line protocol interface supports multiple modes and different precision and requires the introduction of constants in the schemaless module to set.
D
dingbo 已提交
331 332 333 334 335 336

```rust
use libtaos::*;
use libtaos::schemaless::*;
```

337
- InfluxDB line protocol
D
dingbo 已提交
338 339 340 341 342 343

    ```rust
    let lines = [
        "st,t1=abc,t2=def,t3=anything c1=3i64,c3=L\"pass\",c2=false 1626006833639000000"
        "st,t1=abc,t2=def,t3=anything c1=3i64,c3=L\"abc\",c4=4f64 1626006833639000000"
    ];
344
    taos.schemaless_insert(&lines, TSDB_SML_LINE_PROTOCOL, TSDB_SML_TIMESTAMP_NANOSECONDS)? ;
D
dingbo 已提交
345 346
    ```

347
- OpenTSDB Telnet Protocol
D
dingbo 已提交
348 349 350

    ```rust
    let lines = ["sys.if.bytes.out 1479496100 1.3E3 host=web01 interface=eth0"];
351
    taos.schemaless_insert(&lines, TSDB_SML_LINE_PROTOCOL, TSDB_SML_TIMESTAMP_SECONDS)? ;
D
dingbo 已提交
352 353
    ```

354
- OpenTSDB JSON protocol
D
dingbo 已提交
355 356 357 358

    ```rust
    let lines = [r#"
        {
359 360 361 362 363 364 365 366
            "metric": "st",
            "timestamp": 1626006833,
            "value": 10,
            "tags": {
                "t1": true,
                "t2": false,
                "t3": 10,
                "t4": "123_abc_.! @#$%^&*:;,. /? |+-=()[]{}<>"
D
dingbo 已提交
367 368
            }
        }"#];
369
    taos.schemaless_insert(&lines, TSDB_SML_LINE_PROTOCOL, TSDB_SML_TIMESTAMP_SECONDS)? ;
D
dingbo 已提交
370 371
    ```

372
Please move to the Rust documentation hosting page for other related structure API usage instructions: <https://docs.rs/libtaos>.
D
dingbo 已提交
373 374 375 376 377 378 379 380 381 382 383 384

[libtaos]: https://github.com/taosdata/libtaos-rs
[tdengine]: https://github.com/taosdata/TDengine
[bailongma-rs]: https://github.com/taosdata/bailongma-rs
[r2d2]: https://crates.io/crates/r2d2
[demo.rs]: https://github.com/taosdata/libtaos-rs/blob/main/examples/demo.rs
[TaosCfgBuilder]: https://docs.rs/libtaos/latest/libtaos/struct.TaosCfgBuilder.html
[TaosCfg]: https://docs.rs/libtaos/latest/libtaos/struct.TaosCfg.html
[Taos]: https://docs.rs/libtaos/latest/libtaos/struct.Taos.html
[TaosQueryData]: https://docs.rs/libtaos/latest/libtaos/field/struct.TaosQueryData.html
[Field]: https://docs.rs/libtaos/latest/libtaos/field/enum.Field.html
[Stmt]: https://docs.rs/libtaos/latest/libtaos/stmt/struct.Stmt.html