From cbf666b529fd80ea72a91ee3fd17ff2c454f45ba Mon Sep 17 00:00:00 2001
From: sheyanjie-qq <249478495@qq.com>
Date: Thu, 1 Aug 2024 21:15:53 +0800
Subject: [PATCH 1/7] mod tmq example
---
docs/zh/08-develop/07-tmq.md | 66 +---
.../com/taosdata/example/AbsConsumerLoop.java | 2 +-
.../taosdata/example/AbsConsumerLoopFull.java | 142 -------
.../taosdata/example/AbsWsConsumerLoop.java | 144 -------
.../taosdata/example/ConsumerLoopFull.java | 357 +++++++++++++++++
.../example/ParameterBindingBasicDemo.java | 44 ++-
.../example/ParameterBindingBatchDemo.java | 83 ----
.../taosdata/example/WsConsumerLoopFull.java | 358 ++++++++++++++++++
8 files changed, 764 insertions(+), 432 deletions(-)
delete mode 100644 examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoopFull.java
delete mode 100644 examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsWsConsumerLoop.java
create mode 100644 examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ConsumerLoopFull.java
delete mode 100644 examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ParameterBindingBatchDemo.java
create mode 100644 examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WsConsumerLoopFull.java
diff --git a/docs/zh/08-develop/07-tmq.md b/docs/zh/08-develop/07-tmq.md
index 16a538757f..1d5b59307e 100644
--- a/docs/zh/08-develop/07-tmq.md
+++ b/docs/zh/08-develop/07-tmq.md
@@ -85,7 +85,7 @@ Java 连接器创建消费者的参数为 Properties, 可以设置的参数列
```java
-{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsWsConsumerLoop.java:create_consumer}}
+{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WsConsumerLoopFull.java:create_consumer}}
```
@@ -135,7 +135,7 @@ Java 连接器创建消费者的参数为 Properties, 可以设置的参数列
```java
-{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoop.java:create_consumer}}
+{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ConsumerLoopFull.java:create_consumer}}
```
@@ -180,7 +180,7 @@ Java 连接器创建消费者的参数为 Properties, 可以设置的参数列
```java
-{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoop.java:poll_data_code_piece}}
+{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WsConsumerLoopFull.java:poll_data_code_piece}}
```
- `subscribe` 方法的参数含义为:订阅的主题列表(即名称),支持同时订阅多个主题。
@@ -273,33 +273,7 @@ Java 连接器创建消费者的参数为 Properties, 可以设置的参数列
```java
-
-// 获取当前消费者分配的 TopicPartition 集合
-Set assignment() throws SQLException;
-
-// 获取指定分区的当前偏移量
-long position(TopicPartition partition) throws SQLException;
-// 获取指定主题的所有分区的当前偏移量
-Map position(String topic) throws SQLException;
-// 获取指定主题的所有分区的起始偏移量
-Map beginningOffsets(String topic) throws SQLException;
-// 获取指定主题的所有分区的最新偏移量
-Map endOffsets(String topic) throws SQLException;
-// 获取指定分区集合中的已提交偏移量
-Map committed(Set partitions) throws SQLException;
-
-// 设置指定分区的偏移量
-void seek(TopicPartition partition, long offset) throws SQLException;
-// 将指定分区集合的偏移量设置为最开始
-void seekToBeginning(Collection partitions) throws SQLException;
-// 将指定分区集合的偏移量设置为最新
-void seekToEnd(Collection partitions) throws SQLException;
-```
-
-示例代码:
-
-```java
-{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ConsumerOffsetSeek.java:consumer_seek}}
+{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WsConsumerLoopFull.java:consumer_seek}}
```
@@ -344,7 +318,6 @@ void seekToEnd(Collection partitions) throws SQLException;
-
同 Websocket 代码样例。
@@ -389,22 +362,9 @@ void seekToEnd(Collection partitions) throws SQLException;
-```java
-// 同步提交当前消费者的偏移量
-void commitSync() throws SQLException;
-// 同步提交指定的偏移量
-void commitSync(Map offsets) throws SQLException;
-
-// 异步提交仅在 native 连接下有效
-// 异步提交当前消费者的偏移量,需要提供回调以处理可能的提交结果
-void commitAsync(OffsetCommitCallback callback) throws SQLException;
-// 异步提交指定的偏移量,需要提供回调以处理可能的提交结果
-void commitAsync(Map offsets, OffsetCommitCallback callback) throws SQLException;
-```
-
```java
-{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoop.java:commit_code_piece}}
+{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WsConsumerLoopFull.java:commit_code_piece}}
```
@@ -501,7 +461,7 @@ void commitAsync(Map offsets, OffsetCommitCal
```java
-{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoop.java:unsubscribe_data_code_piece}}
+{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WsConsumerLoopFull.java:unsubscribe_data_code_piece}}
```
@@ -593,12 +553,14 @@ void commitAsync(Map offsets, OffsetCommitCal
### Websocket 连接
+
+完整 Websocket 连接代码示例
```java
-{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsWsConsumerLoop.java:consumer_demo}}
+{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WsConsumerLoopFull.java:consumer_demo}}
```
**注意**:这里的 value.deserializer 配置参数值应该根据测试环境的包路径做相应的调整。
-其余代码请参考: [JDBC example](https://github.com/taosdata/TDengine/tree/3.0/examples/JDBC/JDBCDemo)
+
@@ -641,12 +603,16 @@ void commitAsync(Map offsets, OffsetCommitCal
### 原生连接
+
+完整原生连接代码示例
```java
-{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoopFull.java:consumer_demo}}
+{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ConsumerLoopFull.java:consumer_demo}}
```
**注意**:这里的 value.deserializer 配置参数值应该根据测试环境的包路径做相应的调整。
-其余代码请参考: [JDBC example](https://github.com/taosdata/TDengine/tree/3.0/examples/JDBC/JDBCDemo)
+
+
+
diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoop.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoop.java
index 90e6a950cd..f7570c742a 100644
--- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoop.java
+++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoop.java
@@ -32,7 +32,7 @@ config.setProperty("msg.with.table.name", "true");
config.setProperty("enable.auto.commit", "true");
config.setProperty("auto.commit.interval.ms", "1000");
config.setProperty("group.id", "group1");
-config.setProperty("client.id", "1");
+config.setProperty("client.id", "client1");
config.setProperty("value.deserializer", "com.taosdata.example.AbsConsumerLoop$ResultDeserializer");
config.setProperty("value.deserializer.encoding", "UTF-8");
try {
diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoopFull.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoopFull.java
deleted file mode 100644
index bd8f1799f6..0000000000
--- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoopFull.java
+++ /dev/null
@@ -1,142 +0,0 @@
-package com.taosdata.example;
-
-import com.taosdata.jdbc.tmq.ConsumerRecord;
-import com.taosdata.jdbc.tmq.ConsumerRecords;
-import com.taosdata.jdbc.tmq.ReferenceDeserializer;
-import com.taosdata.jdbc.tmq.TaosConsumer;
-
-import java.sql.SQLException;
-import java.sql.Timestamp;
-import java.time.Duration;
-import java.util.Collections;
-import java.util.List;
-import java.util.Properties;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-// ANCHOR: consumer_demo
-public abstract class AbsConsumerLoopFull {
- private final TaosConsumer consumer;
- private final List topics;
- private final AtomicBoolean shutdown;
- private final CountDownLatch shutdownLatch;
-
- public AbsConsumerLoopFull() throws SQLException {
-
- Properties config = new Properties();
- config.setProperty("td.connect.type", "jni");
- config.setProperty("bootstrap.servers", "localhost:6030");
- config.setProperty("auto.offset.reset", "latest");
- config.setProperty("msg.with.table.name", "true");
- config.setProperty("enable.auto.commit", "true");
- config.setProperty("auto.commit.interval.ms", "1000");
- config.setProperty("group.id", "group1");
- config.setProperty("client.id", "1");
- config.setProperty("value.deserializer", "com.taosdata.example.AbsConsumerLoop$ResultDeserializer");
- config.setProperty("value.deserializer.encoding", "UTF-8");
-
- try {
- this.consumer = new TaosConsumer<>(config);
- } catch (SQLException ex) {
- // handle any errors, please refer to the JDBC specifications for detailed exceptions info
- System.out.println("Failed to create jni consumer, host : " + config.getProperty("bootstrap.servers") + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
- throw new SQLException("Failed to create consumer", ex);
- }
-
- this.topics = Collections.singletonList("topic_meters");
- this.shutdown = new AtomicBoolean(false);
- this.shutdownLatch = new CountDownLatch(1);
- }
-
- public abstract void process(ResultBean result);
-
- public void pollData() throws SQLException {
- try {
- // subscribe to the topics
- consumer.subscribe(topics);
- while (!shutdown.get()) {
- // poll data
- ConsumerRecords records = consumer.poll(Duration.ofMillis(100));
- for (ConsumerRecord record : records) {
- ResultBean bean = record.value();
- // process the data here
- process(bean);
- }
- }
- // unsubscribe the topics
- consumer.unsubscribe();
- } finally {
- // close the consumer
- consumer.close();
- shutdownLatch.countDown();
- }
- }
-
- public void shutdown() throws InterruptedException {
- shutdown.set(true);
- shutdownLatch.await();
- }
-
- public static class ResultDeserializer extends ReferenceDeserializer {
-
- }
-
- // use this class to define the data structure of the result record
- public static class ResultBean {
- private Timestamp ts;
- private double current;
- private int voltage;
- private double phase;
- private int groupid;
- private String location;
-
- public Timestamp getTs() {
- return ts;
- }
-
- public void setTs(Timestamp ts) {
- this.ts = ts;
- }
-
- public double getCurrent() {
- return current;
- }
-
- public void setCurrent(double current) {
- this.current = current;
- }
-
- public int getVoltage() {
- return voltage;
- }
-
- public void setVoltage(int voltage) {
- this.voltage = voltage;
- }
-
- public double getPhase() {
- return phase;
- }
-
- public void setPhase(double phase) {
- this.phase = phase;
- }
-
- public int getGroupid() {
- return groupid;
- }
-
- public void setGroupid(int groupid) {
- this.groupid = groupid;
- }
-
- public String getLocation() {
- return location;
- }
-
- public void setLocation(String location) {
- this.location = location;
- }
- }
-}
-// ANCHOR_END: consumer_demo
diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsWsConsumerLoop.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsWsConsumerLoop.java
deleted file mode 100644
index 60466629f6..0000000000
--- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsWsConsumerLoop.java
+++ /dev/null
@@ -1,144 +0,0 @@
-package com.taosdata.example;
-
-import com.taosdata.jdbc.tmq.ConsumerRecord;
-import com.taosdata.jdbc.tmq.ConsumerRecords;
-import com.taosdata.jdbc.tmq.ReferenceDeserializer;
-import com.taosdata.jdbc.tmq.TaosConsumer;
-
-import java.sql.SQLException;
-import java.sql.Timestamp;
-import java.time.Duration;
-import java.util.Collections;
-import java.util.List;
-import java.util.Properties;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-// ANCHOR: consumer_demo
-public abstract class AbsWsConsumerLoop {
- private final TaosConsumer consumer;
- private final List topics;
- private final AtomicBoolean shutdown;
- private final CountDownLatch shutdownLatch;
-
- public AbsWsConsumerLoop() throws SQLException {
-// ANCHOR: create_consumer
-Properties config = new Properties();
-config.setProperty("td.connect.type", "ws");
-config.setProperty("bootstrap.servers", "localhost:6041");
-config.setProperty("auto.offset.reset", "latest");
-config.setProperty("msg.with.table.name", "true");
-config.setProperty("enable.auto.commit", "true");
-config.setProperty("auto.commit.interval.ms", "1000");
-config.setProperty("group.id", "group1");
-config.setProperty("client.id", "client1");
-config.setProperty("value.deserializer", "com.taosdata.example.AbsConsumerLoopWs$ResultDeserializer");
-config.setProperty("value.deserializer.encoding", "UTF-8");
-
-try {
- this.consumer = new TaosConsumer<>(config);
-} catch (SQLException ex) {
- // handle any errors, please refer to the JDBC specifications for detailed exceptions info
- System.out.println("Failed to create ws consumer with " + config.getProperty("bootstrap.servers") + " ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
- throw new SQLException("Failed to create consumer", ex);
-}
-// ANCHOR_END: create_consumer
-
- this.topics = Collections.singletonList("topic_meters");
- this.shutdown = new AtomicBoolean(false);
- this.shutdownLatch = new CountDownLatch(1);
- }
-
- public abstract void process(ResultBean result);
-
- public void pollData() throws SQLException {
- try {
- // Subscribe to the topic
- consumer.subscribe(topics);
-
- while (!shutdown.get()) {
- // poll data
- ConsumerRecords records = consumer.poll(Duration.ofMillis(100));
- for (ConsumerRecord record : records) {
- ResultBean bean = record.value();
- // process data here
- process(bean);
- }
- }
- // unsubscribe the topics
- consumer.unsubscribe();
- } finally {
- // close the consumer
- consumer.close();
- shutdownLatch.countDown();
- }
- }
-
- public void shutdown() throws InterruptedException {
- shutdown.set(true);
- shutdownLatch.await();
- }
-
- public static class ResultDeserializer extends ReferenceDeserializer {
-
- }
-
- // use this class to define the data structure of the result record
- public static class ResultBean {
- private Timestamp ts;
- private double current;
- private int voltage;
- private double phase;
- private int groupid;
- private String location;
-
- public Timestamp getTs() {
- return ts;
- }
-
- public void setTs(Timestamp ts) {
- this.ts = ts;
- }
-
- public double getCurrent() {
- return current;
- }
-
- public void setCurrent(double current) {
- this.current = current;
- }
-
- public int getVoltage() {
- return voltage;
- }
-
- public void setVoltage(int voltage) {
- this.voltage = voltage;
- }
-
- public double getPhase() {
- return phase;
- }
-
- public void setPhase(double phase) {
- this.phase = phase;
- }
-
- public int getGroupid() {
- return groupid;
- }
-
- public void setGroupid(int groupid) {
- this.groupid = groupid;
- }
-
- public String getLocation() {
- return location;
- }
-
- public void setLocation(String location) {
- this.location = location;
- }
- }
-}
-// ANCHOR_END: consumer_demo
diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ConsumerLoopFull.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ConsumerLoopFull.java
new file mode 100644
index 0000000000..4012f2e679
--- /dev/null
+++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ConsumerLoopFull.java
@@ -0,0 +1,357 @@
+package com.taosdata.example;
+
+import com.alibaba.fastjson.JSON;
+import com.taosdata.jdbc.TSDBDriver;
+import com.taosdata.jdbc.tmq.*;
+
+import java.sql.*;
+import java.time.Duration;
+import java.util.*;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+// ANCHOR: consumer_demo
+public class ConsumerLoopFull {
+ static private Connection connection;
+ static private Statement statement;
+ public static TaosConsumer getConsumer() throws SQLException{
+// ANCHOR: create_consumer
+Properties config = new Properties();
+config.setProperty("td.connect.type", "jni");
+config.setProperty("bootstrap.servers", "localhost:6030");
+config.setProperty("auto.offset.reset", "latest");
+config.setProperty("msg.with.table.name", "true");
+config.setProperty("enable.auto.commit", "true");
+config.setProperty("auto.commit.interval.ms", "1000");
+config.setProperty("group.id", "group1");
+config.setProperty("client.id", "1");
+config.setProperty("td.connect.user", "root");
+config.setProperty("td.connect.pass", "taosdata");
+config.setProperty("value.deserializer", "com.taosdata.example.ConsumerLoopFull$ResultDeserializer");
+config.setProperty("value.deserializer.encoding", "UTF-8");
+
+try {
+ return new TaosConsumer<>(config);
+} catch (SQLException ex) {
+ // handle any errors, please refer to the JDBC specifications for detailed exceptions info
+ System.out.println("Failed to create jni consumer, host : " + config.getProperty("bootstrap.servers") + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
+ throw new SQLException("Failed to create consumer", ex);
+} catch (Exception e) {
+ e.printStackTrace();
+ throw new SQLException("Failed to create consumer", e);
+}
+// ANCHOR_END: create_consumer
+ }
+
+ public static void pollDataExample() throws SQLException {
+ try (TaosConsumer consumer = getConsumer()){
+ // subscribe to the topics
+ List topics = Collections.singletonList("topic_meters");
+
+ consumer.subscribe(topics);
+ System.out.println("subscribe topics successfully");
+ for (int i = 0; i < 50; i++) {
+ // poll data
+ ConsumerRecords records = consumer.poll(Duration.ofMillis(100));
+ for (ConsumerRecord record : records) {
+ ResultBean bean = record.value();
+ // process the data here
+ System.out.println("data: " + JSON.toJSONString(bean));
+ }
+ }
+ // unsubscribe the topics
+ consumer.unsubscribe();
+ System.out.println("unsubscribed topics successfully");
+ } catch (SQLException ex) {
+ // handle any errors, please refer to the JDBC specifications for detailed exceptions info
+ System.out.println("Failed to poll data from topic_meters, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
+ throw new SQLException("Failed to poll data from topic_meters", ex);
+ }
+ }
+
+ public static void pollExample() throws SQLException {
+// ANCHOR: poll_data_code_piece
+try (TaosConsumer consumer = getConsumer()){
+ List topics = Collections.singletonList("topic_meters");
+
+ // subscribe to the topics
+ consumer.subscribe(topics);
+ System.out.println("subscribe topics successfully");
+ for (int i = 0; i < 50; i++) {
+ // poll data
+ ConsumerRecords records = consumer.poll(Duration.ofMillis(100));
+ for (ConsumerRecord record : records) {
+ ResultBean bean = record.value();
+ // process the data here
+ System.out.println("data: " + JSON.toJSONString(bean));
+ }
+ }
+
+} catch (SQLException ex) {
+ // handle any errors, please refer to the JDBC specifications for detailed exceptions info
+ System.out.println("Failed to poll data; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
+ throw new SQLException("Failed to poll data", ex);
+}
+// ANCHOR_END: poll_data_code_piece
+}
+
+ public static void seekExample() throws SQLException {
+// ANCHOR: consumer_seek
+try (TaosConsumer consumer = getConsumer()){
+ List topics = Collections.singletonList("topic_meters");
+
+ // subscribe to the topics
+ consumer.subscribe(topics);
+ System.out.println("subscribe topics successfully");
+ ConsumerRecords records = ConsumerRecords.emptyRecord();
+ // make sure we have got some data
+ while (records.isEmpty()){
+ records = consumer.poll(Duration.ofMillis(100));
+ }
+
+ for (ConsumerRecord record : records) {
+ System.out.println("first data polled: " + JSON.toJSONString(record.value()));
+ Set assignment = consumer.assignment();
+ // seek to the beginning of the all partitions
+ consumer.seekToBeginning(assignment);
+ System.out.println("assignment seek to beginning successfully");
+ break;
+ }
+
+ // poll data agagin
+ records = consumer.poll(Duration.ofMillis(100));
+ for (ConsumerRecord record : records) {
+ // process the data here
+ System.out.println("second data polled: " + JSON.toJSONString(record.value()));
+ break;
+ }
+
+
+} catch (SQLException ex) {
+ // handle any errors, please refer to the JDBC specifications for detailed exceptions info
+ System.out.println("seek example failed; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
+ throw new SQLException("seek example failed", ex);
+}
+// ANCHOR_END: consumer_seek
+ }
+
+
+ public static void commitExample() throws SQLException {
+// ANCHOR: commit_code_piece
+try (TaosConsumer consumer = getConsumer()){
+ List topics = Collections.singletonList("topic_meters");
+
+ consumer.subscribe(topics);
+ for (int i = 0; i < 50; i++) {
+ ConsumerRecords records = consumer.poll(Duration.ofMillis(100));
+ for (ConsumerRecord record : records) {
+ ResultBean bean = record.value();
+ // process your data here
+ System.out.println("data: " + JSON.toJSONString(bean));
+ }
+ if (!records.isEmpty()) {
+ // after processing the data, commit the offset manually
+ consumer.commitSync();
+ }
+ }
+} catch (SQLException ex){
+ // handle any errors, please refer to the JDBC specifications for detailed exceptions info
+ System.out.println("Failed to execute consumer functions. ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
+ throw new SQLException("Failed to execute consumer functions", ex);
+}
+// ANCHOR_END: commit_code_piece
+ }
+ public static void unsubscribeExample() throws SQLException {
+ TaosConsumer consumer = getConsumer();
+ List topics = Collections.singletonList("topic_meters");
+ consumer.subscribe(topics);
+// ANCHOR: unsubscribe_data_code_piece
+ try {
+ consumer.unsubscribe();
+ } catch (SQLException ex){
+ // handle any errors, please refer to the JDBC specifications for detailed exceptions info
+ System.out.println("Failed to unsubscribe consumer. ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
+ throw new SQLException("Failed to unsubscribe consumer", ex);
+ } finally {
+ consumer.close();
+ }
+// ANCHOR_END: unsubscribe_data_code_piece
+ }
+
+ public static class ResultDeserializer extends ReferenceDeserializer {
+
+ }
+ // use this class to define the data structure of the result record
+ public static class ResultBean {
+ private Timestamp ts;
+ private double current;
+ private int voltage;
+ private double phase;
+ private int groupid;
+ private String location;
+
+ public Timestamp getTs() {
+ return ts;
+ }
+
+ public void setTs(Timestamp ts) {
+ this.ts = ts;
+ }
+
+ public double getCurrent() {
+ return current;
+ }
+
+ public void setCurrent(double current) {
+ this.current = current;
+ }
+
+ public int getVoltage() {
+ return voltage;
+ }
+
+ public void setVoltage(int voltage) {
+ this.voltage = voltage;
+ }
+
+ public double getPhase() {
+ return phase;
+ }
+
+ public void setPhase(double phase) {
+ this.phase = phase;
+ }
+
+ public int getGroupid() {
+ return groupid;
+ }
+
+ public void setGroupid(int groupid) {
+ this.groupid = groupid;
+ }
+
+ public String getLocation() {
+ return location;
+ }
+
+ public void setLocation(String location) {
+ this.location = location;
+ }
+ }
+
+ public static void prepareData() throws SQLException{
+ StringBuilder insertQuery = new StringBuilder();
+ insertQuery.append("INSERT INTO " +
+ "power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " +
+ "VALUES ");
+ for (int i = 0; i < 10000; i++){
+ insertQuery.append("(NOW + ").append(i).append("a, 10.30000, 219, 0.31000) ");
+ }
+ try {
+ int affectedRows = statement.executeUpdate(insertQuery.toString());
+ assert affectedRows == 10000;
+ } catch (SQLException ex) {
+ System.out.println("Failed to insert data to power.meters, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
+ throw new SQLException("Failed to insert data to power.meters", ex);
+ }
+ }
+ public static void prepareMeta() throws SQLException{
+ try {
+ statement.executeUpdate("CREATE DATABASE IF NOT EXISTS power");
+ statement.executeUpdate("USE power");
+ statement.executeUpdate("CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))");
+ statement.executeUpdate("CREATE TOPIC IF NOT EXISTS topic_meters AS SELECT ts, current, voltage, phase, groupid, location FROM meters");
+ } catch (SQLException ex) {
+ System.out.println("Failed to create db and table, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
+ throw new SQLException("Failed to create db and table", ex);
+ }
+ }
+
+ public static void initConnection() throws SQLException {
+ String url = "jdbc:TAOS://localhost:6030?user=root&password=taosdata";
+ Properties properties = new Properties();
+ properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "C");
+ properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
+
+ try {
+ connection = DriverManager.getConnection(url, properties);
+ } catch (SQLException ex) {
+ System.out.println("Failed to create connection, url:" + url + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
+ throw new SQLException("Failed to create connection", ex);
+ }
+ try {
+ statement = connection.createStatement();
+ } catch (SQLException ex) {
+ System.out.println("Failed to create statement, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
+ throw new SQLException("Failed to create statement", ex);
+ }
+ System.out.println("Connection created successfully.");
+ }
+ public static void closeConnection() throws SQLException {
+ try {
+ if (statement != null) {
+ statement.close();
+ }
+ } catch (SQLException ex) {
+ System.out.println("Failed to close statement, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
+ throw new SQLException("Failed to close statement", ex);
+ }
+
+ try {
+ if (connection != null) {
+ connection.close();
+ }
+ } catch (SQLException ex) {
+ System.out.println("Failed to close connection, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
+ throw new SQLException("Failed to close connection", ex);
+ }
+ System.out.println("Connection closed Successfully.");
+ }
+
+
+ public static void main(String[] args) throws SQLException {
+ initConnection();
+ prepareMeta();
+
+ // create a single thread executor
+ ExecutorService executor = Executors.newSingleThreadExecutor();
+
+ // submit a task
+ executor.submit(() -> {
+ try {
+ // please use one example at a time
+ pollDataExample();
+// seekExample();
+// pollExample();
+// commitExample();
+ unsubscribeExample();
+ } catch (SQLException ex) {
+ System.out.println("Failed to poll data from topic_meters, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
+ }
+ System.out.println("pollDataExample executed successfully");
+ });
+
+ prepareData();
+ closeConnection();
+
+ System.out.println("Data prepared successfully");
+
+ // 关闭线程池,不再接收新任务
+ executor.shutdown();
+
+ try {
+ // 等待直到所有任务完成
+ boolean result = executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
+ assert result;
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ } catch (Exception e){
+ e.printStackTrace();
+ System.out.println("Wait executor termination failed.");
+ }
+
+ System.out.println("program end.");
+ }
+}
+// ANCHOR_END: consumer_demo
diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ParameterBindingBasicDemo.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ParameterBindingBasicDemo.java
index 469316efc7..fa2efab2ee 100644
--- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ParameterBindingBasicDemo.java
+++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ParameterBindingBasicDemo.java
@@ -2,7 +2,10 @@ package com.taosdata.example;
import com.taosdata.jdbc.TSDBPreparedStatement;
-import java.sql.*;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.sql.Statement;
import java.util.ArrayList;
import java.util.Random;
@@ -24,6 +27,7 @@ public class ParameterBindingBasicDemo {
String sql = "INSERT INTO ? USING meters TAGS(?,?) VALUES (?,?,?,?)";
try (TSDBPreparedStatement pstmt = conn.prepareStatement(sql).unwrap(TSDBPreparedStatement.class)) {
+
for (int i = 1; i <= numOfSubTable; i++) {
// set table name
pstmt.setTableName("d_bind_" + i);
@@ -32,19 +36,35 @@ public class ParameterBindingBasicDemo {
pstmt.setTagInt(0, i);
pstmt.setTagString(1, "location_" + i);
- // set columns
+ // set column ts
+ ArrayList tsList = new ArrayList<>();
long current = System.currentTimeMillis();
- for (int j = 0; j < numOfRow; j++) {
- pstmt.setTimestamp(1, new Timestamp(current + j));
- pstmt.setFloat(2, random.nextFloat() * 30);
- pstmt.setInt(3, random.nextInt(300));
- pstmt.setFloat(4, random.nextFloat());
- pstmt.addBatch();
- }
- int [] exeResult = pstmt.executeBatch();
- // you can check exeResult here
- System.out.println("insert " + exeResult.length + " rows.");
+ for (int j = 0; j < numOfRow; j++)
+ tsList.add(current + j);
+ pstmt.setTimestamp(0, tsList);
+
+ // set column current
+ ArrayList currentList = new ArrayList<>();
+ for (int j = 0; j < numOfRow; j++)
+ currentList.add(random.nextFloat() * 30);
+ pstmt.setFloat(1, currentList);
+
+ // set column voltage
+ ArrayList voltageList = new ArrayList<>();
+ for (int j = 0; j < numOfRow; j++)
+ voltageList.add(random.nextInt(300));
+ pstmt.setInt(2, voltageList);
+
+ // set column phase
+ ArrayList phaseList = new ArrayList<>();
+ for (int j = 0; j < numOfRow; j++)
+ phaseList.add(random.nextFloat());
+ pstmt.setFloat(3, phaseList);
+ // add column
+ pstmt.columnDataAddBatch();
}
+ // execute column
+ pstmt.columnDataExecuteBatch();
}
} catch (SQLException ex) {
// handle any errors, please refer to the JDBC specifications for detailed exceptions info
diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ParameterBindingBatchDemo.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ParameterBindingBatchDemo.java
deleted file mode 100644
index 60d76eee4f..0000000000
--- a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ParameterBindingBatchDemo.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package com.taosdata.example;
-
-import com.taosdata.jdbc.TSDBPreparedStatement;
-
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.Random;
-
-// ANCHOR: para_bind
-public class ParameterBindingBatchDemo {
-
- // modify host to your own
- private static final String host = "127.0.0.1";
- private static final Random random = new Random(System.currentTimeMillis());
- private static final int numOfSubTable = 10, numOfRow = 10;
-
- public static void main(String[] args) throws SQLException {
-
- String jdbcUrl = "jdbc:TAOS://" + host + ":6030/";
- try (Connection conn = DriverManager.getConnection(jdbcUrl, "root", "taosdata")) {
-
- init(conn);
-
- String sql = "INSERT INTO ? USING meters TAGS(?,?) VALUES (?,?,?,?)";
-
- try (TSDBPreparedStatement pstmt = conn.prepareStatement(sql).unwrap(TSDBPreparedStatement.class)) {
-
- for (int i = 1; i <= numOfSubTable; i++) {
- // set table name
- pstmt.setTableName("d_bind_" + i);
-
- // set tags
- pstmt.setTagInt(0, i);
- pstmt.setTagString(1, "location_" + i);
-
- // set column ts
- ArrayList tsList = new ArrayList<>();
- long current = System.currentTimeMillis();
- for (int j = 0; j < numOfRow; j++)
- tsList.add(current + j);
- pstmt.setTimestamp(0, tsList);
-
- // set column current
- ArrayList f1List = new ArrayList<>();
- for (int j = 0; j < numOfRow; j++)
- f1List.add(random.nextFloat() * 30);
- pstmt.setFloat(1, f1List);
-
- // set column voltage
- ArrayList f2List = new ArrayList<>();
- for (int j = 0; j < numOfRow; j++)
- f2List.add(random.nextInt(300));
- pstmt.setInt(2, f2List);
-
- // set column phase
- ArrayList f3List = new ArrayList<>();
- for (int j = 0; j < numOfRow; j++)
- f3List.add(random.nextFloat());
- pstmt.setFloat(3, f3List);
- // add column
- pstmt.columnDataAddBatch();
- }
- // execute column
- pstmt.columnDataExecuteBatch();
- }
- } catch (SQLException ex) {
- // handle any errors, please refer to the JDBC specifications for detailed exceptions info
- System.out.println("Failed to insert to table meters using stmt, url: " + jdbcUrl + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
- }
- }
-
- private static void init(Connection conn) throws SQLException {
- try (Statement stmt = conn.createStatement()) {
- stmt.execute("CREATE DATABASE IF NOT EXISTS power");
- stmt.execute("USE power");
- stmt.execute("CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))");
- }
- }
-}
-// ANCHOR_END: para_bind
diff --git a/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WsConsumerLoopFull.java b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WsConsumerLoopFull.java
new file mode 100644
index 0000000000..d8084eb9f6
--- /dev/null
+++ b/examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WsConsumerLoopFull.java
@@ -0,0 +1,358 @@
+package com.taosdata.example;
+
+import com.alibaba.fastjson.JSON;
+import com.taosdata.jdbc.TSDBDriver;
+import com.taosdata.jdbc.tmq.*;
+
+import java.sql.*;
+import java.time.Duration;
+import java.util.Collections;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+// ANCHOR: consumer_demo
+public class WsConsumerLoopFull {
+ static private Connection connection;
+ static private Statement statement;
+ public static TaosConsumer getConsumer() throws SQLException{
+// ANCHOR: create_consumer
+Properties config = new Properties();
+config.setProperty("td.connect.type", "ws");
+config.setProperty("bootstrap.servers", "localhost:6041");
+config.setProperty("auto.offset.reset", "latest");
+config.setProperty("msg.with.table.name", "true");
+config.setProperty("enable.auto.commit", "true");
+config.setProperty("auto.commit.interval.ms", "1000");
+config.setProperty("group.id", "group1");
+config.setProperty("client.id", "client1");
+config.setProperty("td.connect.user", "root");
+config.setProperty("td.connect.pass", "taosdata");
+config.setProperty("value.deserializer", "com.taosdata.example.WsConsumerLoopFull$ResultDeserializer");
+config.setProperty("value.deserializer.encoding", "UTF-8");
+
+try {
+ return new TaosConsumer<>(config);
+ } catch (SQLException ex) {
+ // handle any errors, please refer to the JDBC specifications for detailed exceptions info
+ System.out.println("Failed to create websocket consumer, host : " + config.getProperty("bootstrap.servers") + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
+ throw new SQLException("Failed to create consumer", ex);
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new SQLException("Failed to create consumer", e);
+ }
+// ANCHOR_END: create_consumer
+}
+
+ public static void pollDataExample() throws SQLException {
+ try (TaosConsumer consumer = getConsumer()){
+ // subscribe to the topics
+ List topics = Collections.singletonList("topic_meters");
+
+ consumer.subscribe(topics);
+ System.out.println("subscribe topics successfully");
+ for (int i = 0; i < 50; i++) {
+ // poll data
+ ConsumerRecords records = consumer.poll(Duration.ofMillis(100));
+ for (ConsumerRecord record : records) {
+ ResultBean bean = record.value();
+ // process the data here
+ System.out.println("data: " + JSON.toJSONString(bean));
+ }
+ }
+ // unsubscribe the topics
+ consumer.unsubscribe();
+ System.out.println("unsubscribed topics successfully");
+ } catch (SQLException ex) {
+ // handle any errors, please refer to the JDBC specifications for detailed exceptions info
+ System.out.println("Failed to poll data from topic_meters, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
+ throw new SQLException("Failed to poll data from topic_meters", ex);
+ }
+ }
+
+ public static void pollExample() throws SQLException {
+// ANCHOR: poll_data_code_piece
+try (TaosConsumer consumer = getConsumer()){
+ List topics = Collections.singletonList("topic_meters");
+
+ // subscribe to the topics
+ consumer.subscribe(topics);
+ System.out.println("subscribe topics successfully");
+ for (int i = 0; i < 50; i++) {
+ // poll data
+ ConsumerRecords records = consumer.poll(Duration.ofMillis(100));
+ for (ConsumerRecord record : records) {
+ ResultBean bean = record.value();
+ // process the data here
+ System.out.println("data: " + JSON.toJSONString(bean));
+ }
+ }
+
+} catch (SQLException ex) {
+ // handle any errors, please refer to the JDBC specifications for detailed exceptions info
+ System.out.println("Failed to poll data; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
+ throw new SQLException("Failed to poll data", ex);
+}
+// ANCHOR_END: poll_data_code_piece
+ }
+
+ public static void seekExample() throws SQLException {
+// ANCHOR: consumer_seek
+try (TaosConsumer consumer = getConsumer()){
+ List topics = Collections.singletonList("topic_meters");
+
+ // subscribe to the topics
+ consumer.subscribe(topics);
+ System.out.println("subscribe topics successfully");
+ ConsumerRecords records = ConsumerRecords.emptyRecord();
+ // make sure we have got some data
+ while (records.isEmpty()){
+ records = consumer.poll(Duration.ofMillis(100));
+ }
+
+ for (ConsumerRecord record : records) {
+ System.out.println("first data polled: " + JSON.toJSONString(record.value()));
+ Set assignment = consumer.assignment();
+ // seek to the beginning of the all partitions
+ consumer.seekToBeginning(assignment);
+ System.out.println("assignment seek to beginning successfully");
+ break;
+ }
+
+ // poll data agagin
+ records = consumer.poll(Duration.ofMillis(100));
+ for (ConsumerRecord record : records) {
+ // process the data here
+ System.out.println("second data polled: " + JSON.toJSONString(record.value()));
+ break;
+ }
+} catch (SQLException ex) {
+ // handle any errors, please refer to the JDBC specifications for detailed exceptions info
+ System.out.println("seek example failed; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
+ throw new SQLException("seek example failed", ex);
+}
+// ANCHOR_END: consumer_seek
+ }
+
+
+ public static void commitExample() throws SQLException {
+// ANCHOR: commit_code_piece
+try (TaosConsumer consumer = getConsumer()){
+ List topics = Collections.singletonList("topic_meters");
+
+ consumer.subscribe(topics);
+ for (int i = 0; i < 50; i++) {
+ ConsumerRecords records = consumer.poll(Duration.ofMillis(100));
+ for (ConsumerRecord record : records) {
+ ResultBean bean = record.value();
+ // process your data here
+ System.out.println("data: " + JSON.toJSONString(bean));
+ }
+ if (!records.isEmpty()) {
+ // after processing the data, commit the offset manually
+ consumer.commitSync();
+ }
+ }
+} catch (SQLException ex){
+ // handle any errors, please refer to the JDBC specifications for detailed exceptions info
+ System.out.println("Failed to execute consumer functions. ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
+ throw new SQLException("Failed to execute consumer functions", ex);
+}
+// ANCHOR_END: commit_code_piece
+ }
+ public static void unsubscribeExample() throws SQLException {
+ TaosConsumer consumer = getConsumer();
+ List topics = Collections.singletonList("topic_meters");
+ consumer.subscribe(topics);
+// ANCHOR: unsubscribe_data_code_piece
+try {
+ consumer.unsubscribe();
+} catch (SQLException ex){
+ // handle any errors, please refer to the JDBC specifications for detailed exceptions info
+ System.out.println("Failed to unsubscribe consumer. ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
+ throw new SQLException("Failed to unsubscribe consumer", ex);
+} finally {
+ consumer.close();
+}
+// ANCHOR_END: unsubscribe_data_code_piece
+ }
+
+public static class ResultDeserializer extends ReferenceDeserializer {
+
+}
+// use this class to define the data structure of the result record
+public static class ResultBean {
+ private Timestamp ts;
+ private double current;
+ private int voltage;
+ private double phase;
+ private int groupid;
+ private String location;
+
+ public Timestamp getTs() {
+ return ts;
+ }
+
+ public void setTs(Timestamp ts) {
+ this.ts = ts;
+ }
+
+ public double getCurrent() {
+ return current;
+ }
+
+ public void setCurrent(double current) {
+ this.current = current;
+ }
+
+ public int getVoltage() {
+ return voltage;
+ }
+
+ public void setVoltage(int voltage) {
+ this.voltage = voltage;
+ }
+
+ public double getPhase() {
+ return phase;
+ }
+
+ public void setPhase(double phase) {
+ this.phase = phase;
+ }
+
+ public int getGroupid() {
+ return groupid;
+ }
+
+ public void setGroupid(int groupid) {
+ this.groupid = groupid;
+ }
+
+ public String getLocation() {
+ return location;
+ }
+
+ public void setLocation(String location) {
+ this.location = location;
+ }
+}
+
+ public static void prepareData() throws SQLException{
+ StringBuilder insertQuery = new StringBuilder();
+ insertQuery.append("INSERT INTO " +
+ "power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " +
+ "VALUES ");
+ for (int i = 0; i < 10000; i++){
+ insertQuery.append("(NOW + ").append(i).append("a, 10.30000, 219, 0.31000) ");
+ }
+ try {
+ int affectedRows = statement.executeUpdate(insertQuery.toString());
+ assert affectedRows == 10000;
+ } catch (SQLException ex) {
+ System.out.println("Failed to insert data to power.meters, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
+ throw new SQLException("Failed to insert data to power.meters", ex);
+ }
+ }
+ public static void prepareMeta() throws SQLException{
+ try {
+ statement.executeUpdate("CREATE DATABASE IF NOT EXISTS power");
+ statement.executeUpdate("USE power");
+ statement.executeUpdate("CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))");
+ statement.executeUpdate("CREATE TOPIC IF NOT EXISTS topic_meters AS SELECT ts, current, voltage, phase, groupid, location FROM meters");
+ } catch (SQLException ex) {
+ System.out.println("Failed to create db and table, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
+ throw new SQLException("Failed to create db and table", ex);
+ }
+ }
+
+ public static void initConnection() throws SQLException {
+ String url = "jdbc:TAOS://localhost:6030?user=root&password=taosdata";
+ Properties properties = new Properties();
+ properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "C");
+ properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
+
+ try {
+ connection = DriverManager.getConnection(url, properties);
+ } catch (SQLException ex) {
+ System.out.println("Failed to create connection, url:" + url + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
+ throw new SQLException("Failed to create connection", ex);
+ }
+ try {
+ statement = connection.createStatement();
+ } catch (SQLException ex) {
+ System.out.println("Failed to create statement, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
+ throw new SQLException("Failed to create statement", ex);
+ }
+ System.out.println("Connection created successfully.");
+ }
+ public static void closeConnection() throws SQLException {
+ try {
+ if (statement != null) {
+ statement.close();
+ }
+ } catch (SQLException ex) {
+ System.out.println("Failed to close statement, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
+ throw new SQLException("Failed to close statement", ex);
+ }
+
+ try {
+ if (connection != null) {
+ connection.close();
+ }
+ } catch (SQLException ex) {
+ System.out.println("Failed to close connection, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
+ throw new SQLException("Failed to close connection", ex);
+ }
+ System.out.println("Connection closed Successfully.");
+ }
+
+
+ public static void main(String[] args) throws SQLException {
+ initConnection();
+ prepareMeta();
+
+ // create a single thread executor
+ ExecutorService executor = Executors.newSingleThreadExecutor();
+
+ // submit a task
+ executor.submit(() -> {
+ try {
+ // please use one example at a time
+ pollDataExample();
+// seekExample();
+// pollExample();
+// commitExample();
+ unsubscribeExample();
+ } catch (SQLException ex) {
+ System.out.println("Failed to poll data from topic_meters, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
+ }
+ System.out.println("pollDataExample executed successfully");
+ });
+
+ prepareData();
+ closeConnection();
+
+ System.out.println("Data prepared successfully");
+
+ // 关闭线程池,不再接收新任务
+ executor.shutdown();
+
+ try {
+ // 等待直到所有任务完成
+ boolean result = executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
+ assert result;
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ } catch (Exception e){
+ e.printStackTrace();
+ System.out.println("Wait executor termination failed.");
+ }
+
+ System.out.println("program end.");
+ }
+}
+// ANCHOR_END: consumer_demo
From 779c46b85f75f5c06d899595afcb351557609cd3 Mon Sep 17 00:00:00 2001
From: Yaming Pei
Date: Thu, 1 Aug 2024 21:40:59 +0800
Subject: [PATCH 2/7] The Connector section of the official website
reconstructs the C language interface description
---
docs/zh/14-reference/05-connector/10-cpp.mdx | 202 +++++++++++--------
1 file changed, 115 insertions(+), 87 deletions(-)
diff --git a/docs/zh/14-reference/05-connector/10-cpp.mdx b/docs/zh/14-reference/05-connector/10-cpp.mdx
index d4761ee5c4..2e7a53a464 100644
--- a/docs/zh/14-reference/05-connector/10-cpp.mdx
+++ b/docs/zh/14-reference/05-connector/10-cpp.mdx
@@ -224,131 +224,161 @@ int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields)
基础 API 用于完成创建数据库连接等工作,为其它 API 的执行提供运行时环境。
- `int taos_init()`
-
- 初始化运行环境。如果没有主动调用该 API,那么调用 `taos_connect()` 时驱动将自动调用该 API,故程序一般无需手动调用。
+ - **接口说明**:初始化运行环境。如果没有主动调用该 API,那么调用 `taos_connect()` 时驱动将自动调用该 API,故程序一般无需手动调用。
+ - **返回值**:待补充,未找到相关资料。
- `void taos_cleanup()`
-
- 清理运行环境,应用退出前应调用。
+ - **接口说明**:清理运行环境,应用退出前应调用。
- `int taos_options(TSDB_OPTION option, const void * arg, ...)`
-
- 设置客户端选项,目前支持区域设置(`TSDB_OPTION_LOCALE`)、字符集设置(`TSDB_OPTION_CHARSET`)、时区设置(`TSDB_OPTION_TIMEZONE`)、配置文件路径设置(`TSDB_OPTION_CONFIGDIR`)。区域设置、字符集、时区默认为操作系统当前设置。
+ - **接口说明**:设置客户端选项,目前支持区域设置(`TSDB_OPTION_LOCALE`)、字符集设置(`TSDB_OPTION_CHARSET`)、时区设置(`TSDB_OPTION_TIMEZONE`)、配置文件路径设置(`TSDB_OPTION_CONFIGDIR`)。区域设置、字符集、时区默认为操作系统当前设置。
+ - **参数说明**:
+ - `option`:[入参] 设置项类型。
+ - `arg`:[入参] 设置项值。
+ - **返回值**:`0`:成功,`-1`:失败。
- `char *taos_get_client_info()`
+ - **接口说明**:获取客户端版本信息。
+ - **返回值**:返回客户端版本信息。
- 获取客户端版本信息。
-
-- `TAOS *taos_connect(const char *host, const char *user, const char *pass, const char *db, int port)`
-
- 创建数据库连接,初始化连接上下文。其中需要用户提供的参数包含:
-
- - host:TDengine 集群中任一节点的 FQDN
- - user:用户名
- - pass:密码
- - db: 数据库名字,如果用户没有提供,也可以正常连接,用户可以通过该连接创建新的数据库,如果用户提供了数据库名字,则说明该数据库用户已经创建好,缺省使用该数据库
- - port:taosd 程序监听的端口
-
- 返回值为空表示失败。应用程序需要保存返回的参数,以便后续使用。
-
+- `TAOS *taos_connect(const char *ip, const char *user, const char *pass, const char *db, uint16_t port);`
+ - **接口说明**:创建数据库连接,初始化连接上下文。
+ - **参数说明**:
+ - ip:[入参] TDengine 集群中任一节点的 FQDN。
+ - user:[入参] 用户名。
+ - pass:[入参] 密码。
+ - db:[入参] 数据库名字,如果用户没有提供,也可以正常连接,用户可以通过该连接创建新的数据库,如果用户提供了数据库名字,则说明该数据库用户已经创建好,缺省使用该数据库。
+ - port:[入参] taosd 程序监听的端口。
+ - **返回值**:返回数据库连接,返回值为空表示失败。应用程序需要保存返回的参数,以便后续使用。
:::info
同一进程可以根据不同的 host/port 连接多个 TDengine 集群
-
:::
- `TAOS *taos_connect_auth(const char *host, const char *user, const char *auth, const char *db, uint16_t port)`
-
- 功能同 taos_connect。除 pass 参数替换为 auth 外,其他参数同 taos_connect。
-
- - auth: 原始密码取 32 位小写 md5
+ - **接口说明**:功能同 taos_connect。除 pass 参数替换为 auth 外,其他参数同 taos_connect。
+ - **参数说明**:
+ - ip:[入参] TDengine 集群中任一节点的 FQDN。
+ - user:[入参] 用户名。
+ - auth: [入参] 原始密码取 32 位小写 md5。
+ - db:[入参] 数据库名称,如果用户没有提供,也可以正常连接,用户可以通过该连接创建新的数据库,如果用户提供了数据库名字,则说明该数据库用户已经创建好,缺省使用该数据库。
+ - port:[入参] taosd 程序监听的端口。
+ - **返回值**:返回数据库连接,返回值为空表示失败。应用程序需要保存返回的参数,以便后续使用。
- `char *taos_get_server_info(TAOS *taos)`
-
- 获取服务端版本信息。
+ - **接口说明**:获取服务端版本信息。
+ - **参数说明**:
+ - taos:[入参] 数据库连接。
+ - **返回值**:返回获取服务端版本信息。
- `int taos_select_db(TAOS *taos, const char *db)`
+ - **接口说明**:将当前的缺省数据库设置为 `db`。
+ - **参数说明**:
+ - taos:[入参] 数据库连接。
+ - db:[入参] 数据库名称。
+ - **返回值**:`0`:成功,`非0`:失败,详情请参考错误码。待补充。
- 将当前的缺省数据库设置为 `db`。
-
- `int taos_get_current_db(TAOS *taos, char *database, int len, int *required)`
-
- - database,len为用户在外面申请的空间,内部会把当前db赋值到database里。
- - 只要是没有正常把db名赋值到database中(包括截断),返回错误,返回值为-1,然后用户可以通过 taos_errstr(NULL) 来获取错误提示。
- - 如果,database == NULL 或者 len\<=0 返回错误,required里保存存储db需要的空间(包含最后的'\0')
- - 如果,len 小于 存储db需要的空间(包含最后的'\0'),返回错误,database里赋值截断的数据,以'\0'结尾。
- - 如果,len 大于等于 存储db需要的空间(包含最后的'\0'),返回正常0,database里赋值以'\0‘结尾的db名。
+ - **接口说明**:获取当前数据库名称。
+ - **参数说明**:
+ - taos:[入参] 数据库连接。
+ - database:[出参] 存储当前数据库名称。
+ - len:[入参] database 的空间大小。
+ - required:[出参] 存储当前数据库名称所需的空间(包含最后的'\0')。
+ - **返回值**:`0`:成功,`-1`:失败,详情请调用 taos_errstr(NULL) 函数来获取错误提示。
+ - 如果,database == NULL 或者 len\<=0 返回失败。
+ - 如果,len 小于 存储数据库名称所需的空间(包含最后的'\0'),返回失败,database 里赋值截断的数据,以'\0'结尾。
+ - 如果,len 大于等于 存储数据库名称所需的空间(包含最后的'\0'),返回成功,database 里赋值以'\0‘结尾数据库名称。
- `int taos_set_notify_cb(TAOS *taos, __taos_notify_fn_t fp, void *param, int type)`
-
- 设置事件回调函数。
-
- - fp 事件回调函数指针。函数声明:typedef void (*__taos_notify_fn_t)(void *param, void *ext, int type);其中, param 为用户自定义参数,ext 为扩展参数(依赖事件类型,针对 TAOS_NOTIFY_PASSVER 返回用户密码版本),type 为事件类型
- - param 用户自定义参数
- - type 事件类型。取值范围:1)TAOS_NOTIFY_PASSVER: 用户密码改变
+ - **接口说明**:设置事件回调函数。
+ - **参数说明**:
+ - taos:[入参] 数据库连接。
+ - fp:[入参] 事件回调函数指针。函数声明:typedef void (*__taos_notify_fn_t)(void *param, void *ext, int type);其中, param 为用户自定义参数,ext 为扩展参数(依赖事件类型,针对 TAOS_NOTIFY_PASSVER 返回用户密码版本),type 为事件类型。
+ - param:[入参] 用户自定义参数。
+ - type:[入参] 事件类型。取值范围:1)TAOS_NOTIFY_PASSVER: 用户密码改变。
+ - **返回值**:`0`:成功,`-1`:失败,详情请调用 taos_errstr(NULL) 函数来获取错误提示。
- `void taos_close(TAOS *taos)`
-
- 关闭连接,其中`taos`是 `taos_connect()` 返回的句柄。
+ - **接口说明**:关闭连接。
+ - **参数说明**:
+ - taos:[入参] 数据库连接。
### 同步查询 API
本小节介绍 API 均属于同步接口。应用调用后,会阻塞等待响应,直到获得返回结果或错误信息。
- `TAOS_RES* taos_query(TAOS *taos, const char *sql)`
-
- 执行 SQL 语句,可以是 DQL、DML 或 DDL 语句。 其中的 `taos` 参数是通过 `taos_connect()` 获得的句柄。不能通过返回值是否是 `NULL` 来判断执行结果是否失败,而是需要用 `taos_errno()` 函数解析结果集中的错误代码来进行判断。
+ - **接口说明**:执行 SQL 语句,可以是 DQL、DML 或 DDL 语句。
+ - **参数说明**:
+ - taos:[入参] 数据库连接。
+ - sql:[入参] 需要执行 SQL 语句。
+ - **返回值**:不能通过返回值是否是 `NULL` 来判断执行结果是否失败,而是需要调用 `taos_errno()` 函数解析结果集中的错误代码来进行判断。
+ - taos_errno 返回值:`0`:成功,`-1`:失败,详情请调用 taos_errstr 函数来获取错误提示。
- `int taos_result_precision(TAOS_RES *res)`
-
- 返回结果集时间戳字段的精度,`0` 代表毫秒,`1` 代表微秒,`2` 代表纳秒。
+ - **接口说明**:返回结果集时间戳字段的精度类别。
+ - **参数说明**:
+ - res:[入参] 结果集。
+ - **返回值**:`0`:毫秒,`1`:微秒,`2`:纳秒。
- `TAOS_ROW taos_fetch_row(TAOS_RES *res)`
-
- 按行获取查询结果集中的数据。
+ - **接口说明**:按行获取查询结果集中的数据。
+ - **参数说明**:
+ - res:[入参] 查询结果集。
+ - **返回值**:`非NULL`:成功,`NULL`:失败,详情请调用 taos_errstr(NULL) 函数来获取错误提示。
- `int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows)`
-
- 批量获取查询结果集中的数据,返回值为获取到的数据的行数。
+ - **接口说明**:批量获取查询结果集中的数据。
+ - **参数说明**:
+ - res:[入参] 查询结果集。
+ - rows:[出参] 用于存储从结果集中获取的行。
+ - **返回值**:返回值为获取到的数据的行数,如果没有更多的行则返回 0。
- `int taos_num_fields(TAOS_RES *res)` 和 `int taos_field_count(TAOS_RES *res)`
-
- 这两个 API 等价,用于获取查询结果集中的列数。
+ - **接口说明**:这两个 API 等价,用于获取查询结果集中的列数。
+ - **参数说明**:
+ - res:[入参] 查询结果集。
+ - **返回值**:返回值为结果集中列的数量。
- `int* taos_fetch_lengths(TAOS_RES *res)`
-
- 获取结果集中每个字段的长度。返回值是一个数组,其长度为结果集的列数。
+ - **接口说明**:获取结果集中每个字段的长度。
+ - **参数说明**:
+ - res:[入参] 结果集。
+ - **返回值**:返回值是一个数组,其长度为结果集的列数。
- `int taos_affected_rows(TAOS_RES *res)`
-
- 获取被所执行的 SQL 语句影响的行数。
+ - **接口说明**:获取被所执行的 SQL 语句影响的行数。
+ - **参数说明**:
+ - res:[入参] 结果集。
+ - **返回值**:返回值表示受影响的行数。
- `TAOS_FIELD *taos_fetch_fields(TAOS_RES *res)`
-
- 获取查询结果集每列数据的属性(列的名称、列的数据类型、列的长度),与 `taos_num_fields()` 配合使用,可用来解析 `taos_fetch_row()` 返回的一个元组(一行)的数据。 `TAOS_FIELD` 的结构如下:
-
-```c
-typedef struct taosField {
- char name[65]; // column name
- uint8_t type; // data type
- int16_t bytes; // length, in bytes
-} TAOS_FIELD;
-```
+ - **接口说明**:获取查询结果集每列数据的属性(列的名称、列的数据类型、列的长度),与 `taos_num_fields()` 配合使用,可用来解析 `taos_fetch_row()` 返回的一个元组(一行)的数据。
+ - **参数说明**:
+ - res:[入参] 查询结果集。
+ - **返回值**:`非NULL`:成功,返回一个指向 TAOS_FIELD 结构体的指针,每个元素代表一列的元数据。`NULL`:失败。
- `void taos_stop_query(TAOS_RES *res)`
-
- 停止当前查询的执行。
+ - **接口说明**:停止当前查询的执行。
+ - **参数说明**:
+ - res:[入参] 查询结果集。
- `void taos_free_result(TAOS_RES *res)`
-
- 释放查询结果集以及相关的资源。查询完成后,务必调用该 API 释放资源,否则可能导致应用内存泄露。但也需注意,释放资源后,如果再调用 `taos_consume()` 等获取查询结果的函数,将导致应用崩溃。
+ - **接口说明**:释放查询结果集以及相关的资源。查询完成后,务必调用该 API 释放资源,否则可能导致应用内存泄露。但也需注意,释放资源后,如果再调用 `taos_consume()` 等获取查询结果的函数,将导致应用崩溃。
+ - **参数说明**:
+ - res:[入参] 查询结果集。
- `char *taos_errstr(TAOS_RES *res)`
-
- 获取最近一次 API 调用失败的原因,返回值为字符串标识的错误提示信息。
+ - **接口说明**:获取最近一次 API 调用失败的原因,返回值为字符串标识的错误提示信息。
+ - **参数说明**:
+ - res:[入参] 结果集。
+ - **返回值**:字符串标识的错误提示信息。
- `int taos_errno(TAOS_RES *res)`
-
- 获取最近一次 API 调用失败的原因,返回值为错误代码。
+ - **接口说明**:获取最近一次 API 调用失败的原因,返回值为错误代码。
+ - **参数说明**:
+ - res:[入参] 结果集。
+ - **返回值**:字符串标识的错误提示信息。
:::note
2.0 及以上版本 TDengine 推荐数据库应用的每个线程都建立一个独立的连接,或基于线程建立连接池。而不推荐在应用中将该连接 (TAOS\*) 结构体传递到不同的线程共享使用。基于 TAOS 结构体发出的查询、写入等操作具有多线程安全性,但 “USE statement” 等状态量有可能在线程之间相互干扰。此外,C 语言的连接器可以按照需求动态建立面向数据库的新连接(该过程对用户不可见),同时建议只有在程序最后退出的时候才调用 `taos_close()` 关闭连接。
@@ -365,20 +395,18 @@ TDengine 还提供性能更高的异步 API 处理数据插入、查询操作。
异步 API 对于使用者的要求相对较高,用户可根据具体应用场景选择性使用。下面是两个重要的异步 API:
- `void taos_query_a(TAOS *taos, const char *sql, void (*fp)(void *param, TAOS_RES *, int code), void *param);`
-
- 异步执行 SQL 语句。
-
- - taos:调用 `taos_connect()` 返回的数据库连接
- - sql:需要执行的 SQL 语句
- - fp:用户定义的回调函数,其第三个参数 `code` 用于指示操作是否成功,`0` 表示成功,负数表示失败(调用 `taos_errstr()` 可获取失败原因)。应用在定义回调函数的时候,主要处理第二个参数 `TAOS_RES *`,该参数是查询返回的结果集
- - param:应用提供一个用于回调的参数
+ - **接口说明**:异步执行 SQL 语句。
+ - **参数说明**:
+ - taos:[入参] 数据库连接。
+ - sql: [入参] 需要执行的 SQL 语句。
+ - fp:用户定义的回调函数,其第三个参数 `code` 用于指示操作是否成功,`0` 表示成功,负数表示失败(调用 `taos_errstr()` 可获取失败原因)。应用在定义回调函数的时候,主要处理第二个参数 `TAOS_RES *`,该参数是查询返回的结果集。
+ - param:应用提供的用于回调的参数。
- `void taos_fetch_rows_a(TAOS_RES *res, void (*fp)(void *param, TAOS_RES *, int numOfRows), void *param);`
-
- 批量获取异步查询的结果集,只能与 `taos_query_a()` 配合使用。其中:
-
- - res:`taos_query_a()` 回调时返回的结果集
- - fp:回调函数。其参数 `param` 是用户可定义的传递给回调函数的参数结构体;`numOfRows` 是获取到的数据的行数(不是整个查询结果集的函数)。 在回调函数中,应用可以通过调用 `taos_fetch_row()` 前向迭代获取批量记录中每一行记录。读完一块内的所有记录后,应用需要在回调函数中继续调用 `taos_fetch_rows_a()` 获取下一批记录进行处理,直到返回的记录数 `numOfRows` 为零(结果返回完成)或记录数为负值(查询出错)。
+ - **接口说明**: 批量获取异步查询的结果集,只能与 `taos_query_a()` 配合使用。
+ - **参数说明**:
+ - res:`taos_query_a()` 回调时返回的结果集。
+ - fp:回调函数。其参数 `param` 是用户可定义的传递给回调函数的参数结构体;`numOfRows` 是获取到的数据的行数(不是整个查询结果集的函数)。 在回调函数中,应用可以通过调用 `taos_fetch_row()` 前向迭代获取批量记录中每一行记录。读完一块内的所有记录后,应用需要在回调函数中继续调用 `taos_fetch_rows_a()` 获取下一批记录进行处理,直到返回的记录数 `numOfRows` 为零(结果返回完成)或记录数为负值(查询出错)。
TDengine 的异步 API 均采用非阻塞调用模式。应用程序可以用多线程同时打开多张表,并可以同时对每张打开的表进行查询或者插入操作。需要指出的是,**客户端应用必须确保对同一张表的操作完全串行化**,即对同一个表的插入或查询操作未完成时(未返回时),不能够执行第二个插入或查询操作。
From ef1884d675a2a227a9080380ebad3e7f0ab04cbf Mon Sep 17 00:00:00 2001
From: sheyanjie-qq <249478495@qq.com>
Date: Fri, 2 Aug 2024 08:49:41 +0800
Subject: [PATCH 3/7] add rust api
---
docs/zh/14-reference/05-connector/26-rust.mdx | 397 +++++++++++++++++-
1 file changed, 396 insertions(+), 1 deletion(-)
diff --git a/docs/zh/14-reference/05-connector/26-rust.mdx b/docs/zh/14-reference/05-connector/26-rust.mdx
index 2cdfdc9e41..f6c9e5d688 100644
--- a/docs/zh/14-reference/05-connector/26-rust.mdx
+++ b/docs/zh/14-reference/05-connector/26-rust.mdx
@@ -607,7 +607,402 @@ stmt.execute()?;
一个可运行的示例请见 [GitHub 上的示例](https://github.com/taosdata/taos-connector-rust/blob/main/examples/bind.rs)。
-其他相关结构体 API 使用说明请移步 Rust 文档托管网页:\。
+## API 参考
+
+Rust 连接器的接口分为同步接口和异步接口,一般同步接口是由异步接口实现,方法签名除 async 关键字外基本相同。对于同步接口和异步接口功能一样的接口,本文档只提供同步接口的说明。
+对于 WebSocket 连接和原生连接两种方式,除了建立连接的 DSN 不同,其余接口调用没有区别。
+
+### 连接功能
+#### DSN
+
+TaosBuilder 通过 DSN 连接描述字符串创建一个连接构造器。
+DSN 描述字符串基本结构如下:
+
+```text
+[+]://[[:@]:][/][?=[&=]]
+|------|------------|---|-----------|-----------|------|------|------------|-----------------------|
+|driver| protocol | | username | password | host | port | database | params |
+```
+
+各部分意义见下表:
+
+- **driver**: 必须指定驱动名以便连接器选择何种方式创建连接,支持如下驱动名:
+ - **taos**: 表名使用 TDengine 连接器驱动。
+ - **tmq**: 使用 TMQ 订阅数据。
+ - **http/ws**: 使用 Websocket 创建连接。
+ - **https/wss**: 在 Websocket 连接方式下显示启用 SSL/TLS 连接。
+- **protocol**: 显示指定以何种方式建立连接,例如:`taos+ws://localhost:6041` 指定以 Websocket 方式建立连接。
+- **username/password**: 用于创建连接的用户名及密码。
+- **host/port**: 指定创建连接的服务器及端口,当不指定服务器地址及端口时(`taos://`),原生连接默认为 `localhost:6030`,Websocket 连接默认为 `localhost:6041` 。
+- **database**: 指定默认连接的数据库名,可选参数。
+- **params**:其他可选参数。
+
+一个完整的 DSN 描述字符串示例如下:`taos+ws://localhost:6041/test`, 表示使用 Websocket(`ws`)方式通过 `6041` 端口连接服务器 `localhost`,并指定默认数据库为 `test`。
+
+#### TaosBuilder
+TaosBuilder 结构体提供了建立连接,检查连接,以及获取服务端版本号等功能。
+
+- `fn available_params() -> &'static [&'static str]`
+ - **接口说明**:获取DSN中可用的参数列表。
+ - **返回值**:返回静态字符串切片的引用,包含可用的参数名称。
+
+- `fn from_dsn(dsn: D) -> RawResult`
+ - **接口说明**:使用DSN字符串创建连接,不检查连接。
+ - **参数说明**:
+ - `dsn`:DSN字符串或可转换为DSN的类型。
+ - **返回值**:成功时返回自身类型的 `RawResult`,失败时返回错误。
+
+- `fn client_version() -> &'static str`
+ - **接口说明**:获取客户端版本。
+ - **返回值**:返回客户端版本的静态字符串。
+
+- `fn ping(&self, _: &mut Self::Target) -> RawResult<()>`
+ - **接口说明**:检查连接是否仍然存活。
+ - **参数说明**:
+ - `_`:目标连接的可变引用。
+ - **返回值**:成功时返回空的 `RawResult`,失败时返回错误。
+
+- `fn ready(&self) -> bool`
+ - **接口说明**:检查是否准备好连接。
+ - **返回值**:大多数情况下返回true,表示地址准备好连接。
+
+- `fn build(&self) -> RawResult`
+ - **接口说明**:从此结构创建新的连接。
+ - **返回值**:成功时返回目标连接类型的 `RawResult`,失败时返回错误。
+
+### 执行 SQL
+执行 SQL 主要涉及到 Taos 结构体,以及结果集 ResultSet 结构体,还有列信息 Field。
+#### Taos
+Taos 结构体提供了多个数据库操作的 API,包括:执行 SQL,无模式写入,以及一些常用数据库查询的封装(如创建数据库,获取)
+
+- `pub fn is_native(&self) -> bool`
+ - **接口说明**:判断连接是否使用本地协议。
+ - **返回值**:如果使用本地协议,则返回 `true`,否则返回 `false`。
+
+- `pub fn is_ws(&self) -> bool`
+ - **接口说明**:判断连接是否使用websocket协议。
+ - **返回值**:如果使用websocket协议,则返回 `true`,否则返回 `false`。
+
+- `fn query>(&self, sql: T) -> RawResult`
+ - **接口说明**:执行SQL查询。
+ - **参数说明**:
+ - `sql`:要执行的SQL语句。
+ - **返回值**:成功时返回结果集 `ResultSet` 的 `RawResult`,失败时返回错误。
+
+- `fn query_with_req_id>(&self, sql: T, req_id: u64) -> RawResult`
+ - **接口说明**:带请求ID执行SQL查询。
+ - **参数说明**:
+ - `sql`:要执行的SQL语句。
+ - `req_id`:请求ID。
+ - **返回值**:成功时返回结果集 `ResultSet` 的 `RawResult`,失败时返回错误。
+
+- `fn exec>(&self, sql: T) -> RawResult`
+ - **接口说明**:执行SQL语句。
+ - **参数说明**:
+ - `sql`:要执行的SQL语句。
+ - **返回值**:成功时返回受影响的行数,失败时返回错误。
+
+- `fn exec_many, I: IntoIterator- >(&self, input: I) -> RawResult`
+ - **接口说明**:批量执行SQL语句。
+ - **参数说明**:
+ - `input`:要执行的SQL语句集合。
+ - **返回值**:成功时返回总共受影响的行数,失败时返回错误。
+
+- `fn query_one, O: DeserializeOwned>(&self, sql: T) -> RawResult
@@ -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 6/7] 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 7/7] 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