From eab486137031cc0a562c7515c7da390472e0c8ba Mon Sep 17 00:00:00 2001 From: t_max <1172915550@qq.com> Date: Thu, 14 Dec 2023 16:58:18 +0800 Subject: [PATCH] refactor(c#): refactor c# connector to v3.1.0 --- docs/en/07-develop/01-connect/index.md | 2 +- .../en/07-develop/04-query-data/_cs_async.mdx | 3 - docs/en/07-develop/04-query-data/index.mdx | 4 - docs/en/07-develop/07-tmq.mdx | 52 +- .../14-reference/03-connector/09-csharp.mdx | 1317 ++++++++++++++--- docs/examples/csharp/.gitignore | 3 +- docs/examples/csharp/asyncQuery/Program.cs | 111 -- .../csharp/asyncQuery/asyncquery.csproj | 15 - docs/examples/csharp/connect/Program.cs | 21 +- docs/examples/csharp/connect/connect.csproj | 2 +- docs/examples/csharp/csharp.sln | 6 - docs/examples/csharp/influxdbLine/Program.cs | 68 +- .../csharp/influxdbLine/influxdbline.csproj | 2 +- docs/examples/csharp/optsJSON/Program.cs | 75 +- docs/examples/csharp/optsJSON/optsJSON.csproj | 2 +- docs/examples/csharp/optsTelnet/Program.cs | 81 +- .../csharp/optsTelnet/optstelnet.csproj | 2 +- docs/examples/csharp/query/Program.cs | 87 +- docs/examples/csharp/query/query.csproj | 2 +- docs/examples/csharp/sqlInsert/Program.cs | 92 +- .../csharp/sqlInsert/sqlinsert.csproj | 2 +- docs/examples/csharp/stmtInsert/Program.cs | 119 +- .../csharp/stmtInsert/stmtinsert.csproj | 2 +- docs/examples/csharp/subscribe/Program.cs | 127 +- .../csharp/subscribe/subscribe.csproj | 2 +- docs/examples/csharp/wsConnect/Program.cs | 22 +- .../csharp/wsConnect/wsConnect.csproj | 2 +- docs/examples/csharp/wsInsert/Program.cs | 83 +- docs/examples/csharp/wsInsert/wsInsert.csproj | 2 +- docs/examples/csharp/wsQuery/Program.cs | 89 +- docs/examples/csharp/wsQuery/wsQuery.csproj | 2 +- docs/examples/csharp/wsStmt/Program.cs | 117 +- docs/examples/csharp/wsStmt/wsStmt.csproj | 2 +- docs/zh/07-develop/01-connect/index.md | 2 +- .../zh/07-develop/04-query-data/_cs_async.mdx | 3 - docs/zh/07-develop/04-query-data/index.mdx | 4 - docs/zh/07-develop/07-tmq.mdx | 52 +- docs/zh/08-connector/40-csharp.mdx | 1303 +++++++++++++--- tests/docs-examples-test/csharp.sh | 9 +- 39 files changed, 2533 insertions(+), 1358 deletions(-) delete mode 100644 docs/en/07-develop/04-query-data/_cs_async.mdx delete mode 100644 docs/examples/csharp/asyncQuery/Program.cs delete mode 100644 docs/examples/csharp/asyncQuery/asyncquery.csproj delete mode 100644 docs/zh/07-develop/04-query-data/_cs_async.mdx diff --git a/docs/en/07-develop/01-connect/index.md b/docs/en/07-develop/01-connect/index.md index 3f09f9fb6a..11375bd060 100644 --- a/docs/en/07-develop/01-connect/index.md +++ b/docs/en/07-develop/01-connect/index.md @@ -177,7 +177,7 @@ Just need to add the reference to [TDengine.Connector](https://www.nuget.org/pac - + diff --git a/docs/en/07-develop/04-query-data/_cs_async.mdx b/docs/en/07-develop/04-query-data/_cs_async.mdx deleted file mode 100644 index 19c8e58f32..0000000000 --- a/docs/en/07-develop/04-query-data/_cs_async.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```csharp -{{#include docs/examples/csharp/asyncQuery/Program.cs}} -``` diff --git a/docs/en/07-develop/04-query-data/index.mdx b/docs/en/07-develop/04-query-data/index.mdx index 413baf6b2c..70b1140748 100644 --- a/docs/en/07-develop/04-query-data/index.mdx +++ b/docs/en/07-develop/04-query-data/index.mdx @@ -15,7 +15,6 @@ import CQuery from "./_c.mdx"; import PhpQuery from "./_php.mdx"; import PyAsync from "./_py_async.mdx"; import NodeAsync from "./_js_async.mdx"; -import CsAsync from "./_cs_async.mdx"; import CAsync from "./_c_async.mdx"; ## Introduction @@ -174,9 +173,6 @@ Please note that async query can only be used with a native connection. - - - diff --git a/docs/en/07-develop/07-tmq.mdx b/docs/en/07-develop/07-tmq.mdx index 8e7bbf22e9..b920d61a59 100644 --- a/docs/en/07-develop/07-tmq.mdx +++ b/docs/en/07-develop/07-tmq.mdx @@ -248,23 +248,23 @@ function close() ```csharp +class ConsumerBuilder + ConsumerBuilder(IEnumerable> config) -virtual IConsumer Build() - -Consumer(ConsumerBuilder builder) +public IConsumer Build() void Subscribe(IEnumerable topics) void Subscribe(string topic) -ConsumeResult Consume(int millisecondsTimeout) +ConsumeResult Consume(int millisecondsTimeout) List Subscription() void Unsubscribe() -void Commit(ConsumeResult consumerResult) +List Commit() void Close() ``` @@ -500,25 +500,19 @@ let consumer = taos.consumer({ ```csharp -using TDengineTMQ; - -// Create consumer groups on demand (GourpID) and enable automatic commits (EnableAutoCommit), -// an automatic commit interval (AutoCommitIntervalMs), and a username (TDConnectUser) and password (TDConnectPasswd) -var cfg = new ConsumerConfig - { - EnableAutoCommit = "true" - AutoCommitIntervalMs = "1000" - GourpId = "TDengine-TMQ-C#", - TDConnectUser = "root", - TDConnectPasswd = "taosdata", - AutoOffsetReset = "latest" - MsgWithTableName = "true", - TDConnectIp = "127.0.0.1", - TDConnectPort = "6030" - }; - -var consumer = new ConsumerBuilder(cfg).Build(); - +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(); ``` @@ -747,10 +741,12 @@ while(true){ ## Consume data while (true) { - var consumerRes = consumer.Consume(100); - // process ConsumeResult - ProcessMsg(consumerRes); - consumer.Commit(consumerRes); + using (var result = consumer.Consume(500)) + { + if (result == null) continue; + ProcessMsg(result); + consumer.Commit(); + } } ``` diff --git a/docs/en/14-reference/03-connector/09-csharp.mdx b/docs/en/14-reference/03-connector/09-csharp.mdx index 282be3af6b..25bef1cf51 100644 --- a/docs/en/14-reference/03-connector/09-csharp.mdx +++ b/docs/en/14-reference/03-connector/09-csharp.mdx @@ -1,5 +1,5 @@ --- -title: C# Connector +title: TDengine C# Connector sidebar_label: C# description: This document describes the TDengine C# connector. toc_max_heading_level: 4 @@ -8,21 +8,16 @@ toc_max_heading_level: 4 import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -import Preparition from "./_preparation.mdx" -import CSInsert from "../../07-develop/03-insert-data/_cs_sql.mdx" -import CSInfluxLine from "../../07-develop/03-insert-data/_cs_line.mdx" -import CSOpenTSDBTelnet from "../../07-develop/03-insert-data/_cs_opts_telnet.mdx" -import CSOpenTSDBJson from "../../07-develop/03-insert-data/_cs_opts_json.mdx" -import CSQuery from "../../07-develop/04-query-data/_cs.mdx" -import CSAsyncQuery from "../../07-develop/04-query-data/_cs_async.mdx" +`TDengine.Connector` is the C# language connector provided by TDengine. C# developers can use it to develop C# application software that accesses TDengine cluster data. -`TDengine.Connector` is a C# language connector provided by TDengine that allows C# developers to develop C# applications that access TDengine cluster data. +The `TDengine.Connector` connector supports establishing a connection with the TDengine running instance through the TDengine client driver (taosc), and provides functions such as data writing, query, data subscription, schemaless data writing, and parameter binding interface data writing. `TDengine.Connector` also supports WebSocket since v3.0.1, establishes WebSocket connection, and provides functions such as data writing, query, and parameter binding interface data writing. -The `TDengine.Connector` connector supports connect to TDengine instances via the TDengine client driver (taosc), providing data writing, querying, subscription, schemaless writing, bind interface, etc.The `TDengine.Connector` also supports WebSocket from v3.0.1 and developers can build connection through DSN, which supports data writing, querying, and parameter binding, etc. +This article introduces how to install `TDengine.Connector` in a Linux or Windows environment, and connect to the TDengine cluster through `TDengine.Connector` to perform basic operations such as data writing and querying. -This article describes how to install `TDengine.Connector` in a Linux or Windows environment and connect to TDengine clusters via `TDengine.Connector` to perform basic operations such as data writing and querying. - -Note: TDengine Connector 3.x is not compatible with TDengine 2.x. In an environment with TDengine 2.x, you must use TDengine.Connector 1.x for the C# connector. +:::warning +* `TDengine.Connector` version 3.1.0 has been completely refactored and is no longer compatible with 3.0.2 and previous versions. For 3.0.2 documents, please refer to [nuget](https://www.nuget.org/packages/TDengine.Connector/3.0.2) +* `TDengine.Connector` 3.x is not compatible with TDengine 2.x. If you need to use the C# connector in an environment running TDengine 2.x version, please use the 1.x version of TDengine.Connector. +::: The source code of `TDengine.Connector` is hosted on [GitHub](https://github.com/taosdata/taos-connector-dotnet/tree/3.0). @@ -30,286 +25,1164 @@ The source code of `TDengine.Connector` is hosted on [GitHub](https://github.com The supported platforms are the same as those supported by the TDengine client driver. -:::note -Please note TDengine does not support 32bit Windows any more. +:::warning +TDengine no longer supports 32-bit Windows platforms. ::: ## Version support -Please refer to [version support list](../#version-support) +| **Connector version** | **TDengine version** | +|-----------------------|----------------------| +| 3.1.0 | 3.2.1.0/3.1.1.18 | -## Supported features +## Handling exceptions - +`TDengine.Connector` will throw an exception and the application needs to handle the exception. The taosc exception type `TDengineError` contains error code and error information, and the application can handle it based on the error code and error information. - +## TDengine DataType vs. C# DataType -1. Connection Management -2. General Query -3. Continuous Query -4. Parameter Binding -5. Subscription -6. Schemaless +| TDengine DataType | C# Type | +|-------------------|-------------------------| +| TIMESTAMP | DateTime | +| TINYINT | sbyte | +| SMALLINT | short | +| INT | int | +| BIGINT | long | +| TINYINT UNSIGNED | byte | +| SMALLINT UNSIGNED | ushort | +| INT UNSIGNED | uint | +| BIGINT UNSIGNED | ulong | +| FLOAT | float | +| DOUBLE | double | +| BOOL | bool | +| BINARY | byte[] | +| NCHAR | string (utf-8 encoding) | +| JSON | byte[] | - - - - -1. Connection Management -2. General Query -3. Continuous Query -4. Parameter Binding - - - +**Note**: JSON type is only supported in tag. ## Installation Steps ### Pre-installation preparation -* Install the [.NET SDK](https://dotnet.microsoft.com/download) +* Install [.NET SDK](https://dotnet.microsoft.com/download) * [Nuget Client](https://docs.microsoft.com/en-us/nuget/install-nuget-client-tools) (optional installation) -* Install TDengine client driver, please refer to [Install client driver](../#install-client-driver) for details +* Install the TDengine client driver. For specific steps, please refer to [Installing the client driver](../#install-client-driver) -### Install `TDengine.Connector` +### Install the connectors - - +Nuget package `TDengine.Connector` can be added to the current project through dotnet CLI under the path of the current .NET project. -You can reference the `TDengine.Connector` published in Nuget to the current project via the `dotnet` CLI under the path of the existing .NET project. - -``` bash +```bash dotnet add package TDengine.Connector ``` -You may also modify the current.NET project file. You can include the following 'ItemGroup' in your project file (.csproj). +You can also modify the `.csproj` file of the current project and add the following ItemGroup. ``` XML - - - + + + ``` - - +## Establishing a connection -In this scenario, modifying your project file is required in order to copy the WebSocket dependency dynamic library from the nuget package into your project. -```XML - - - - - - - - - -``` - -Notice: `TDengine.Connector` only version>= 3.0.2 includes the dynamic library for WebSocket. - - - - -## Establish a Connection - - - - - + + ``` csharp -using TDengineDriver; - -namespace TDengineExample +var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); +using (var client = DbDriver.Open(builder)) { - - internal class EstablishConnection - { - static void Main(String[] args) - { - string host = "localhost"; - short port = 6030; - string username = "root"; - string password = "taosdata"; - string dbname = ""; - - var conn = TDengine.Connect(host, username, password, dbname, port); - if (conn == IntPtr.Zero) - { - Console.WriteLine("Connect to TDengine failed"); - } - else - { - Console.WriteLine("Connect to TDengine success"); - } - TDengine.Close(conn); - TDengine.Cleanup(); - } - } + Console.WriteLine("connected") } - ``` + - - -The structure of the DSN description string is as follows: - -```text -[]://[[:@]:][/][?=[&=]] -|------------|---|-----------|-----------|------|------|------------|-----------------------| -| protocol | | username | password | host | port | database | params | -``` - -The parameters are described as follows: - -* **protocol**: Specify which connection method to use (support http/ws). For example, `ws://localhost:6041` uses Websocket to establish connections. -* **username/password**: Username and password used to create connections. -* **host/port**: Specifies the server and port to establish a connection. Websocket connections default to `localhost:6041`. -* **database**: Specify the default database to connect to. It's optional. -* **params**: Optional parameters. - -A sample DSN description string is as follows: - -```text -ws://localhost:6041/test -``` - -``` csharp -{{#include docs/examples/csharp/wsConnect/Program.cs}} +```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") +} ``` +The parameters supported by `ConnectionStringBuilder` are as follows: +* protocol: connection protocol, optional value is Native or WebSocket, default is Native +* host: the address of the running instance of TDengine or taosadapter, +* port: The port of the running instance of TDengine or taosadapter. + * When using WebSocket without SSL, the default is 6041. + * When using WebSocket with SSL, the default is 443. +* useSSL: Whether to use SSL, the default is false, only valid when the protocol is WebSocket +* token: The token used to connect to TDengine Cloud, only valid when the protocol is WebSocket +* username: username to connect to TDengine +* password: password to connect to TDengine +* db: database connected to TDengine +* timezone: The time zone for parsing time results, the default is `TimeZoneInfo.Local`, use the `TimeZoneInfo.FindSystemTimeZoneById` method to parse the string into a `TimeZoneInfo` object. +* connTimeout: WebSocket connection timeout, only valid when the protocol is WebSocket, the default is 1 minute, use the `TimeSpan.Parse` method to parse the string into a `TimeSpan` object. +* readTimeout: WebSocket read timeout, only valid when the protocol is WebSocket, the default is 5 minutes, use the `TimeSpan.Parse` method to parse the string into a `TimeSpan` object. +* writeTimeout: WebSocket write timeout, only valid when the protocol is WebSocket, the default is 10 seconds, use the `TimeSpan.Parse` method to parse the string into a `TimeSpan` object. + +### Specify the URL and Properties to get the connection + +The C# connector does not support this feature + +### Priority of configuration parameters + +The C# connector does not support this feature + ## Usage examples -### Write data +### Create database and tables -#### SQL Write - - - - - - - - - - + + ```csharp -{{#include docs/examples/csharp/wsInsert/Program.cs}} +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; + } + } + } + } +} ``` -#### InfluxDB line protocol write +### Insert data - + + -#### OpenTSDB Telnet line protocol write +```csharp +using System; +using System.Text; +using TDengine.Driver; +using TDengine.Driver.Client; - - -#### OpenTSDB JSON line protocol write - - - -#### Parameter Binding - - - - - -``` csharp -{{#include docs/examples/csharp/stmtInsert/Program.cs}} +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 -{{#include docs/examples/csharp/wsStmt/Program.cs}} +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; + } + } + } + } +} ``` -### Query data +### Querying data -#### Synchronous Query - - - - - - - - - - + + ```csharp -{{#include docs/examples/csharp/wsQuery/Program.cs}} +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; + } + } + } + } +} ``` -#### Asynchronous query +### execute SQL with reqId - + + + +```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; + } + } + } + } +} +``` + + + + +### Writing data via parameter binding + + + + +```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; + } + } + } + } +} +``` + + + + +Note: When using BindRow, you need to pay attention to the one-to-one correspondence between the original C# column type and the TDengine column type. For the specific correspondence, please refer to [TDengine DataType and C# DataType](#tdengine-datatype-vs-c-datatype). + +### Schemaless Writing + + + + +```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()); + } + } + } +} +``` + + + + +### Schemaless with reqId + +```csharp +public void SchemalessInsert(string[] lines, TDengineSchemalessProtocol protocol, + TDengineSchemalessPrecision precision, + int ttl, long reqId) +``` + +### Data Subscription + +#### Create a 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; + } + } + } + } +} +``` + + + + +#### Create a 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(); +``` + + + + +The configuration parameters supported by consumer are as follows: +* td.connect.type: connection type, optional value is Native or WebSocket, default is Native +* td.connect.ip: The address of the TDengine running instance or taosadapter +* td.connect.port: The port of the running instance of TDengine or taosadapter. + * When using WebSocket without SSL, the default is 6041. + * When using WebSocket with SSL, the default is 443. +* useSSL: Whether to use SSL, the default is false, only valid when the protocol is WebSocket +* token: The token used to connect to TDengine Cloud, only valid when the protocol is WebSocket +* td.connect.user: username to connect to TDengine +* td.connect.pass: Password for connecting to TDengine +* group.id: consumer group ID +* client.id: consumer ID +* enable.auto.commit: Whether to automatically commit offset, the default is true +* auto.commit.interval.ms: The interval for automatically submitting offsets, the default is 5000 milliseconds +* auto.offset.reset: When offset does not exist, where to start consumption, the optional value is earliest or latest, the default is latest +* msg.with.table.name: Whether the message contains the table name + +Supports subscribing to the result set `Dictionary` where the key is the column name and the value is the column value. + +If you use object to receive column values, you need to pay attention to: +* There needs to be a one-to-one correspondence between the original C# column type and the TDengine column type. For specific correspondence, please refer to [TDengine DataType and C# DataType] (#tdengine-datatype-and-c-datatype). +* The column name is consistent with the class attribute name and can be get and set. +* Explicitly set the value parser `ConsumerBuilder.SetValueDeserializer(new ReferenceDeserializer());` + +An example is as follows + +Result class + +```csharp + class Result + { + public DateTime ts { get; set; } + public float current { get; set; } + public int voltage { get; set; } + public float phase { get; set; } + } +``` + +Set up parser + +```csharp +var tmqBuilder = new ConsumerBuilder(cfg); +tmqBuilder.SetValueDeserializer(new ReferenceDeserializer()); +var consumer = tmqBuilder.Build(); +``` + +You can also implement a custom deserializer, implement the `IDeserializer` interface and pass it in through the `ConsumerBuilder.SetValueDeserializer` method. + +```csharp + public interface IDeserializer + { + T Deserialize(ITMQRows data, bool isNull, SerializationContext context); + } +``` + +#### Subscribe to consume data + +```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"]}}}"); + } + } +} +``` + +#### Assignment subscription 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)); +}); +``` + +#### Commit offset + +```csharp +public void Commit(ConsumeResult consumerResult) +public List Commit() +public void Commit(IEnumerable offsets) +``` + +#### Close subscriptions + +```csharp +consumer.Unsubscribe(); +consumer.Close(); +``` + +#### Full Sample Code + + + + +```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 + +The C# connector supports the ADO.NET interface, and you can connect to the TDengine running instance through the ADO.NET interface to perform operations such as data writing and querying. + + + + +```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; + } + } + } + } +} +``` + + + + +* The connection parameters are consistent with those in [Establishing a connection](#establishing-a-connection). +* The name of TDengineParameter needs to start with @, such as @0, @1, @2, etc. The value needs to have a one-to-one correspondence between the C# column type and the TDengine column type. For the specific correspondence, please refer to [TDengine DataType and C# DataType](#tdengine-datatype-vs-c-datatype). ### More sample programs -|Sample program |Sample program description | -|--------------------------------------------------------------------------------------------------------------------|--------------------------------------------| -| [CURD](https://github.com/taosdata/taos-connector-dotnet/blob/3.0/examples/NET6Examples/Query/Query.cs) | Table creation, data insertion, and query examples with TDengine.Connector | -| [JSON Tag](https://github.com/taosdata/taos-connector-dotnet/blob/3.0/examples/NET6Examples/JSONTag) | Writing and querying JSON tag data with TDengine Connector | -| [stmt](https://github.com/taosdata/taos-connector-dotnet/tree/3.0/examples/NET6Examples/Stmt) | Parameter binding with TDengine Connector | -| [schemaless](https://github.com/taosdata/taos-connector-dotnet/blob/3.0/examples/NET6Examples/schemaless) | Schemaless writes with TDengine Connector | -| [async query](https://github.com/taosdata/taos-connector-dotnet/blob/3.0/examples/NET6Examples/AsyncQuery/QueryAsync.cs) | Asynchronous queries with TDengine Connector | -| [Subscription](https://github.com/taosdata/taos-connector-dotnet/blob/3.0/examples/NET6Examples/TMQ/TMQ.cs) | Subscription example with TDengine Connector | -| [Basic WebSocket Usage](https://github.com/taosdata/taos-connector-dotnet/blob/3.0/examples/FrameWork45/WS/WebSocketSample.cs) | WebSocket basic data in and out with TDengine connector | -| [WebSocket Parameter Binding](https://github.com/taosdata/taos-connector-dotnet/blob/3.0/examples/FrameWork45/WS/WebSocketSTMT.cs) | WebSocket parameter binding example | - -## Important update records - -| TDengine.Connector | Description | -|--------------------|--------------------------------| -| 3.0.2 | Support .NET Framework 4.5 and above. Support .Net standard 2.0. Nuget package includes dynamic library for WebSocket.| -| 3.0.1 | Support WebSocket and Cloud, With function query, insert, and parameter binding| -| 3.0.0 | Supports TDengine 3.0.0.0. TDengine 2.x is not supported. Added `TDengine.Impl.GetData()` interface to deserialize query results. | -| 1.0.7 | Fixed TDengine.Query() memory leak. | -| 1.0.6 | Fix schemaless bug in 1.0.4 and 1.0.5. | -| 1.0.5 | Fix Windows sync query Chinese error bug. | 1.0.4 | Fix schemaless bug. | -| 1.0.4 | Add asynchronous query, subscription, and other functions. Fix the binding parameter bug. | -| 1.0.3 | Add parameter binding, schemaless, JSON tag, etc. | -| 1.0.2 | Add connection management, synchronous query, error messages, etc. | - -## Other descriptions - -### Third-party driver - -`Taos` is an ADO.NET connector for TDengine, supporting Linux and Windows platforms. Community contributor `Maikebing@@maikebing contributes the connector`. Please refer to: - -* Interface download: - -## Frequently Asked Questions - -1. "Unable to establish connection", "Unable to resolve FQDN" - - Usually, it's caused by an incorrect FQDN configuration. Please refer to this section in the [FAQ](https://docs.tdengine.com/2.4/train-faq/faq/#2-how-to-handle-unable-to-establish-connection) to troubleshoot. - -2. Unhandled exception. System.DllNotFoundException: Unable to load DLL 'taos' or one of its dependencies: The specified module cannot be found. - - This is usually because the program did not find the dependent client driver. The solution is to copy `C:\TDengine\driver\taos.dll` to the `C:\Windows\System32\` directory on Windows, and create the following soft link on Linux `ln -s /usr/local/taos/driver/libtaos.so.x.x .x.x /usr/lib/libtaos.so` will work. - -## API Reference - -[API Reference](https://docs.taosdata.com/api/connector-csharp/html/860d2ac1-dd52-39c9-e460-0829c4e5a40b.htm) +[sample program](https://github.com/taosdata/taos-connector-dotnet/tree/3.0/examples) \ No newline at end of file diff --git a/docs/examples/csharp/.gitignore b/docs/examples/csharp/.gitignore index c228f1be2a..b0df020f44 100644 --- a/docs/examples/csharp/.gitignore +++ b/docs/examples/csharp/.gitignore @@ -1,5 +1,5 @@ .vs -asyncQuery/bin +.idea connect/bin influxdbLine/bin optsJSON/bin @@ -12,7 +12,6 @@ wsConnect/bin wsInsert/bin wsQuery/bin wsStmt/bin -asyncQuery/obj connect/obj influxdbLine/obj optsJSON/obj diff --git a/docs/examples/csharp/asyncQuery/Program.cs b/docs/examples/csharp/asyncQuery/Program.cs deleted file mode 100644 index 864f06a15e..0000000000 --- a/docs/examples/csharp/asyncQuery/Program.cs +++ /dev/null @@ -1,111 +0,0 @@ -using System; -using System.Collections.Generic; -using TDengineDriver; -using TDengineDriver.Impl; -using System.Runtime.InteropServices; - -namespace TDengineExample -{ - public class AsyncQueryExample - { - static void Main() - { - IntPtr conn = GetConnection(); - try - { - QueryAsyncCallback queryAsyncCallback = new QueryAsyncCallback(QueryCallback); - TDengine.QueryAsync(conn, "select * from meters", queryAsyncCallback, IntPtr.Zero); - Thread.Sleep(2000); - } - finally - { - TDengine.Close(conn); - } - - } - - static void QueryCallback(IntPtr param, IntPtr taosRes, int code) - { - if (code == 0 && taosRes != IntPtr.Zero) - { - FetchRawBlockAsyncCallback fetchRowAsyncCallback = new FetchRawBlockAsyncCallback(FetchRawBlockCallback); - TDengine.FetchRawBlockAsync(taosRes, fetchRowAsyncCallback, param); - } - else - { - throw new Exception($"async query data failed,code:{code},reason:{TDengine.Error(taosRes)}"); - } - } - - // Iteratively call this interface until "numOfRows" is no greater than 0. - static void FetchRawBlockCallback(IntPtr param, IntPtr taosRes, int numOfRows) - { - if (numOfRows > 0) - { - Console.WriteLine($"{numOfRows} rows async retrieved"); - IntPtr pdata = TDengine.GetRawBlock(taosRes); - List metaList = TDengine.FetchFields(taosRes); - List dataList = LibTaos.ReadRawBlock(pdata, metaList, numOfRows); - - for (int i = 0; i < dataList.Count; i++) - { - if (i != 0 && (i + 1) % metaList.Count == 0) - { - Console.WriteLine("{0}\t|", dataList[i]); - } - else - { - Console.Write("{0}\t|", dataList[i]); - } - } - Console.WriteLine(""); - TDengine.FetchRawBlockAsync(taosRes, FetchRawBlockCallback, param); - } - else - { - if (numOfRows == 0) - { - Console.WriteLine("async retrieve complete."); - } - else - { - throw new Exception($"FetchRawBlockCallback callback error, error code {numOfRows}"); - } - TDengine.FreeResult(taosRes); - } - } - - static IntPtr GetConnection() - { - string host = "localhost"; - short port = 6030; - string username = "root"; - string password = "taosdata"; - string dbname = "power"; - var conn = TDengine.Connect(host, username, password, dbname, port); - if (conn == IntPtr.Zero) - { - throw new Exception("Connect to TDengine failed"); - } - else - { - Console.WriteLine("Connect to TDengine success"); - } - return conn; - } - } -} - -// //output: -// // Connect to TDengine success -// // 8 rows async retrieved - -// // 1538548685500 | 11.8 | 221 | 0.28 | california.losangeles | 2 | -// // 1538548696600 | 13.4 | 223 | 0.29 | california.losangeles | 2 | -// // 1538548685000 | 10.8 | 223 | 0.29 | california.losangeles | 3 | -// // 1538548686500 | 11.5 | 221 | 0.35 | california.losangeles | 3 | -// // 1538548685000 | 10.3 | 219 | 0.31 | california.sanfrancisco | 2 | -// // 1538548695000 | 12.6 | 218 | 0.33 | california.sanfrancisco | 2 | -// // 1538548696800 | 12.3 | 221 | 0.31 | california.sanfrancisco | 2 | -// // 1538548696650 | 10.3 | 218 | 0.25 | california.sanfrancisco | 3 | -// // async retrieve complete. \ No newline at end of file diff --git a/docs/examples/csharp/asyncQuery/asyncquery.csproj b/docs/examples/csharp/asyncQuery/asyncquery.csproj deleted file mode 100644 index 7c5b693f28..0000000000 --- a/docs/examples/csharp/asyncQuery/asyncquery.csproj +++ /dev/null @@ -1,15 +0,0 @@ - - - - Exe - net6.0 - enable - enable - TDengineExample.AsyncQueryExample - - - - - - - diff --git a/docs/examples/csharp/connect/Program.cs b/docs/examples/csharp/connect/Program.cs index 955db40c7c..0152b61b03 100644 --- a/docs/examples/csharp/connect/Program.cs +++ b/docs/examples/csharp/connect/Program.cs @@ -1,4 +1,5 @@ -using TDengineDriver; +using TDengine.Driver; +using TDengine.Driver.Client; namespace TDengineExample { @@ -7,23 +8,11 @@ namespace TDengineExample { static void Main(String[] args) { - string host = "localhost"; - short port = 6030; - string username = "root"; - string password = "taosdata"; - string dbname = ""; - - var conn = TDengine.Connect(host, username, password, dbname, port); - if (conn == IntPtr.Zero) + var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); + using (var client = DbDriver.Open(builder)) { - throw new Exception("Connect to TDengine failed"); + Console.WriteLine("connected"); } - else - { - Console.WriteLine("Connect to TDengine success"); - } - TDengine.Close(conn); - TDengine.Cleanup(); } } } diff --git a/docs/examples/csharp/connect/connect.csproj b/docs/examples/csharp/connect/connect.csproj index a08e86d4b4..e4412a68db 100644 --- a/docs/examples/csharp/connect/connect.csproj +++ b/docs/examples/csharp/connect/connect.csproj @@ -9,7 +9,7 @@ - + diff --git a/docs/examples/csharp/csharp.sln b/docs/examples/csharp/csharp.sln index 560dde55cb..59c198b4c9 100644 --- a/docs/examples/csharp/csharp.sln +++ b/docs/examples/csharp/csharp.sln @@ -3,8 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.30114.105 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "asyncquery", "asyncQuery\asyncquery.csproj", "{E2A5F00C-14E7-40E1-A2DE-6AB2975616D3}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "connect", "connect\connect.csproj", "{CCC5042D-93FC-4AE0-B2F6-7E692FD476B7}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "influxdbline", "influxdbLine\influxdbline.csproj", "{6A24FB80-1E3C-4E2D-A5AB-914FA583874D}" @@ -38,10 +36,6 @@ Global HideSolutionNode = FALSE EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {E2A5F00C-14E7-40E1-A2DE-6AB2975616D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E2A5F00C-14E7-40E1-A2DE-6AB2975616D3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E2A5F00C-14E7-40E1-A2DE-6AB2975616D3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E2A5F00C-14E7-40E1-A2DE-6AB2975616D3}.Release|Any CPU.Build.0 = Release|Any CPU {CCC5042D-93FC-4AE0-B2F6-7E692FD476B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {CCC5042D-93FC-4AE0-B2F6-7E692FD476B7}.Debug|Any CPU.Build.0 = Debug|Any CPU {CCC5042D-93FC-4AE0-B2F6-7E692FD476B7}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/docs/examples/csharp/influxdbLine/Program.cs b/docs/examples/csharp/influxdbLine/Program.cs index a620c01609..fcf2928f0c 100644 --- a/docs/examples/csharp/influxdbLine/Program.cs +++ b/docs/examples/csharp/influxdbLine/Program.cs @@ -1,4 +1,5 @@ -using TDengineDriver; +using TDengine.Driver; +using TDengine.Driver.Client; namespace TDengineExample { @@ -6,60 +7,23 @@ namespace TDengineExample { static void Main() { - IntPtr conn = GetConnection(); - PrepareDatabase(conn); - string[] lines = { - "meters,location=California.LosAngeles,groupid=2 current=11.8,voltage=221,phase=0.28 1648432611249", - "meters,location=California.LosAngeles,groupid=2 current=13.4,voltage=223,phase=0.29 1648432611250", - "meters,location=California.LosAngeles,groupid=3 current=10.8,voltage=223,phase=0.29 1648432611249", - "meters,location=California.LosAngeles,groupid=3 current=11.3,voltage=221,phase=0.35 1648432611250" - }; - IntPtr res = TDengine.SchemalessInsert(conn, lines, lines.Length, (int)TDengineSchemalessProtocol.TSDB_SML_LINE_PROTOCOL, (int)TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS); - if (TDengine.ErrorNo(res) != 0) + var builder = + new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); + using (var client = DbDriver.Open(builder)) { - throw new Exception("SchemalessInsert failed since " + TDengine.Error(res)); - } - else - { - int affectedRows = TDengine.AffectRows(res); - Console.WriteLine($"SchemalessInsert success, affected {affectedRows} rows"); - } - TDengine.FreeResult(res); - - } - static IntPtr GetConnection() - { - string host = "localhost"; - short port = 6030; - string username = "root"; - string password = "taosdata"; - string dbname = ""; - var conn = TDengine.Connect(host, username, password, dbname, port); - if (conn == IntPtr.Zero) - { - throw new Exception("Connect to TDengine failed"); - } - else - { - Console.WriteLine("Connect to TDengine success"); - } - return conn; - } - - static void PrepareDatabase(IntPtr conn) - { - IntPtr res = TDengine.Query(conn, "CREATE DATABASE test WAL_RETENTION_PERIOD 3600"); - if (TDengine.ErrorNo(res) != 0) - { - throw new Exception("failed to create database, reason: " + TDengine.Error(res)); - } - res = TDengine.Query(conn, "USE test"); - if (TDengine.ErrorNo(res) != 0) - { - throw new Exception("failed to change database, reason: " + TDengine.Error(res)); + client.Exec("CREATE DATABASE test WAL_RETENTION_PERIOD 3600"); + client.Exec("use test"); + string[] lines = { + "meters,location=California.LosAngeles,groupid=2 current=11.8,voltage=221,phase=0.28 1648432611249", + "meters,location=California.LosAngeles,groupid=2 current=13.4,voltage=223,phase=0.29 1648432611250", + "meters,location=California.LosAngeles,groupid=3 current=10.8,voltage=223,phase=0.29 1648432611249", + "meters,location=California.LosAngeles,groupid=3 current=11.3,voltage=221,phase=0.35 1648432611250" + }; + client.SchemalessInsert(lines, + TDengineSchemalessProtocol.TSDB_SML_LINE_PROTOCOL, + TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS, 0, ReqId.GetReqId()); } } - } } diff --git a/docs/examples/csharp/influxdbLine/influxdbline.csproj b/docs/examples/csharp/influxdbLine/influxdbline.csproj index 4889f8fde9..4fe883b6cb 100644 --- a/docs/examples/csharp/influxdbLine/influxdbline.csproj +++ b/docs/examples/csharp/influxdbLine/influxdbline.csproj @@ -9,7 +9,7 @@ - + diff --git a/docs/examples/csharp/optsJSON/Program.cs b/docs/examples/csharp/optsJSON/Program.cs index 8dcc1dce92..a93c4dad0f 100644 --- a/docs/examples/csharp/optsJSON/Program.cs +++ b/docs/examples/csharp/optsJSON/Program.cs @@ -1,69 +1,28 @@ -using TDengineDriver; +using TDengine.Driver; +using TDengine.Driver.Client; namespace TDengineExample { internal class OptsJsonExample { - static void Main() + public static void Main(string[] args) { - IntPtr conn = GetConnection(); - try + var builder = + new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); + using (var client = DbDriver.Open(builder)) { - PrepareDatabase(conn); - string[] lines = { "[{\"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}}]" - }; - - IntPtr res = TDengine.SchemalessInsert(conn, lines, 1, (int)TDengineSchemalessProtocol.TSDB_SML_JSON_PROTOCOL, (int)TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_NOT_CONFIGURED); - if (TDengine.ErrorNo(res) != 0) + client.Exec("CREATE DATABASE test WAL_RETENTION_PERIOD 3600"); + client.Exec("use test"); + string[] lines = { - throw new Exception("SchemalessInsert failed since " + TDengine.Error(res)); - } - else - { - int affectedRows = TDengine.AffectRows(res); - Console.WriteLine($"SchemalessInsert success, affected {affectedRows} rows"); - } - TDengine.FreeResult(res); - } - finally - { - TDengine.Close(conn); - } - } - static IntPtr GetConnection() - { - string host = "localhost"; - short port = 6030; - string username = "root"; - string password = "taosdata"; - string dbname = ""; - var conn = TDengine.Connect(host, username, password, dbname, port); - if (conn == IntPtr.Zero) - { - throw new Exception("Connect to TDengine failed"); - } - else - { - Console.WriteLine("Connect to TDengine success"); - } - return conn; - } - - static void PrepareDatabase(IntPtr conn) - { - IntPtr res = TDengine.Query(conn, "CREATE DATABASE test WAL_RETENTION_PERIOD 3600"); - if (TDengine.ErrorNo(res) != 0) - { - throw new Exception("failed to create database, reason: " + TDengine.Error(res)); - } - res = TDengine.Query(conn, "USE test"); - if (TDengine.ErrorNo(res) != 0) - { - throw new Exception("failed to change database, reason: " + TDengine.Error(res)); + "[{\"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()); } } } -} +} \ No newline at end of file diff --git a/docs/examples/csharp/optsJSON/optsJSON.csproj b/docs/examples/csharp/optsJSON/optsJSON.csproj index 208f04c82d..9c3edf53e3 100644 --- a/docs/examples/csharp/optsJSON/optsJSON.csproj +++ b/docs/examples/csharp/optsJSON/optsJSON.csproj @@ -9,7 +9,7 @@ - + diff --git a/docs/examples/csharp/optsTelnet/Program.cs b/docs/examples/csharp/optsTelnet/Program.cs index ccd29d0cfc..b64aa9fe2d 100644 --- a/docs/examples/csharp/optsTelnet/Program.cs +++ b/docs/examples/csharp/optsTelnet/Program.cs @@ -1,72 +1,31 @@ -using TDengineDriver; +using TDengine.Driver; +using TDengine.Driver.Client; namespace TDengineExample { internal class OptsTelnetExample { - static void Main() + public static void Main(string[] args) { - IntPtr conn = GetConnection(); - try + var builder = + new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); + using (var client = DbDriver.Open(builder)) { - PrepareDatabase(conn); + client.Exec("CREATE DATABASE test WAL_RETENTION_PERIOD 3600"); + client.Exec("USE test"); string[] lines = { - "meters.current 1648432611249 10.3 location=California.SanFrancisco groupid=2", - "meters.current 1648432611250 12.6 location=California.SanFrancisco groupid=2", - "meters.current 1648432611249 10.8 location=California.LosAngeles groupid=3", - "meters.current 1648432611250 11.3 location=California.LosAngeles groupid=3", - "meters.voltage 1648432611249 219 location=California.SanFrancisco groupid=2", - "meters.voltage 1648432611250 218 location=California.SanFrancisco groupid=2", - "meters.voltage 1648432611249 221 location=California.LosAngeles groupid=3", - "meters.voltage 1648432611250 217 location=California.LosAngeles groupid=3", - }; - IntPtr res = TDengine.SchemalessInsert(conn, lines, lines.Length, (int)TDengineSchemalessProtocol.TSDB_SML_TELNET_PROTOCOL, (int)TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_NOT_CONFIGURED); - if (TDengine.ErrorNo(res) != 0) - { - throw new Exception("SchemalessInsert failed since " + TDengine.Error(res)); - } - else - { - int affectedRows = TDengine.AffectRows(res); - Console.WriteLine($"SchemalessInsert success, affected {affectedRows} rows"); - } - TDengine.FreeResult(res); - } - catch - { - TDengine.Close(conn); - } - } - static IntPtr GetConnection() - { - string host = "localhost"; - short port = 6030; - string username = "root"; - string password = "taosdata"; - string dbname = ""; - var conn = TDengine.Connect(host, username, password, dbname, port); - if (conn == IntPtr.Zero) - { - throw new Exception("Connect to TDengine failed"); - } - else - { - Console.WriteLine("Connect to TDengine success"); - } - return conn; - } - - static void PrepareDatabase(IntPtr conn) - { - IntPtr res = TDengine.Query(conn, "CREATE DATABASE test WAL_RETENTION_PERIOD 3600"); - if (TDengine.ErrorNo(res) != 0) - { - throw new Exception("failed to create database, reason: " + TDengine.Error(res)); - } - res = TDengine.Query(conn, "USE test"); - if (TDengine.ErrorNo(res) != 0) - { - throw new Exception("failed to change database, reason: " + TDengine.Error(res)); + "meters.current 1648432611249 10.3 location=California.SanFrancisco groupid=2", + "meters.current 1648432611250 12.6 location=California.SanFrancisco groupid=2", + "meters.current 1648432611249 10.8 location=California.LosAngeles groupid=3", + "meters.current 1648432611250 11.3 location=California.LosAngeles groupid=3", + "meters.voltage 1648432611249 219 location=California.SanFrancisco groupid=2", + "meters.voltage 1648432611250 218 location=California.SanFrancisco groupid=2", + "meters.voltage 1648432611249 221 location=California.LosAngeles groupid=3", + "meters.voltage 1648432611250 217 location=California.LosAngeles groupid=3", + }; + client.SchemalessInsert(lines, + TDengineSchemalessProtocol.TSDB_SML_TELNET_PROTOCOL, + TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS, 0, ReqId.GetReqId()); } } } diff --git a/docs/examples/csharp/optsTelnet/optstelnet.csproj b/docs/examples/csharp/optsTelnet/optstelnet.csproj index 32c76ec418..4d6941e962 100644 --- a/docs/examples/csharp/optsTelnet/optstelnet.csproj +++ b/docs/examples/csharp/optsTelnet/optstelnet.csproj @@ -9,7 +9,7 @@ - + diff --git a/docs/examples/csharp/query/Program.cs b/docs/examples/csharp/query/Program.cs index 84c7f9db1f..4c354d9a5e 100644 --- a/docs/examples/csharp/query/Program.cs +++ b/docs/examples/csharp/query/Program.cs @@ -1,80 +1,35 @@ -using TDengineDriver; -using TDengineDriver.Impl; -using System.Runtime.InteropServices; +using System.Text; +using TDengine.Driver; +using TDengine.Driver.Client; namespace TDengineExample { internal class QueryExample { - static void Main() + public static void Main(string[] args) { - IntPtr conn = GetConnection(); - try + var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); + using (var client = DbDriver.Open(builder)) { - // run query - IntPtr res = TDengine.Query(conn, "SELECT * FROM meters LIMIT 2"); - if (TDengine.ErrorNo(res) != 0) + try { - throw new Exception("Failed to query since: " + TDengine.Error(res)); - } - - // get filed count - int fieldCount = TDengine.FieldCount(res); - Console.WriteLine("fieldCount=" + fieldCount); - - // print column names - List metas = LibTaos.GetMeta(res); - for (int i = 0; i < metas.Count; i++) - { - Console.Write(metas[i].name + "\t"); - } - Console.WriteLine(); - - // print values - List resData = LibTaos.GetData(res); - for (int i = 0; i < resData.Count; i++) - { - Console.Write($"|{resData[i].ToString()} \t"); - if (((i + 1) % metas.Count == 0)) + client.Exec("use power"); + string query = "SELECT * FROM meters"; + using (var rows = client.Query(query)) { - Console.WriteLine(""); + 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))}"); + } } } - Console.WriteLine(); - - // Free result after use - TDengine.FreeResult(res); + catch (Exception e) + { + Console.WriteLine(e.ToString()); + throw; + } } - finally - { - TDengine.Close(conn); - } - - } - static IntPtr GetConnection() - { - string host = "localhost"; - short port = 6030; - string username = "root"; - string password = "taosdata"; - string dbname = "power"; - var conn = TDengine.Connect(host, username, password, dbname, port); - if (conn == IntPtr.Zero) - { - throw new Exception("Connect to TDengine failed"); - } - else - { - Console.WriteLine("Connect to TDengine success"); - } - return conn; } } -} - -// output: -// Connect to TDengine success -// fieldCount=6 -// ts current voltage phase location groupid -// 1648432611249 10.3 219 0.31 California.SanFrancisco 2 -// 1648432611749 12.6 218 0.33 California.SanFrancisco 2 \ No newline at end of file +} \ No newline at end of file diff --git a/docs/examples/csharp/query/query.csproj b/docs/examples/csharp/query/query.csproj index 360d73b2c0..9924d331af 100644 --- a/docs/examples/csharp/query/query.csproj +++ b/docs/examples/csharp/query/query.csproj @@ -9,7 +9,7 @@ - + diff --git a/docs/examples/csharp/sqlInsert/Program.cs b/docs/examples/csharp/sqlInsert/Program.cs index 25a945a459..c3c700aba2 100644 --- a/docs/examples/csharp/sqlInsert/Program.cs +++ b/docs/examples/csharp/sqlInsert/Program.cs @@ -1,69 +1,47 @@ -using TDengineDriver; - +using System.Text; +using TDengine.Driver; +using TDengine.Driver.Client; namespace TDengineExample { internal class SQLInsertExample { - static void Main() + public static void Main(string[] args) { - IntPtr conn = GetConnection(); - try + var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); + using (var client = DbDriver.Open(builder)) { - IntPtr res = TDengine.Query(conn, "CREATE DATABASE power WAL_RETENTION_PERIOD 3600"); - CheckRes(conn, res, "failed to create database"); - res = TDengine.Query(conn, "USE power"); - CheckRes(conn, res, "failed to change database"); - res = TDengine.Query(conn, "CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)"); - CheckRes(conn, res, "failed to create stable"); - var sql = "INSERT INTO d1001 USING meters TAGS('California.SanFrancisco', 2) VALUES ('2018-10-03 14:38:05.000', 10.30000, 219, 0.31000) ('2018-10-03 14:38:15.000', 12.60000, 218, 0.33000) ('2018-10-03 14:38:16.800', 12.30000, 221, 0.31000) " + - "d1002 USING power.meters TAGS('California.SanFrancisco', 3) VALUES('2018-10-03 14:38:16.650', 10.30000, 218, 0.25000) " + - "d1003 USING power.meters TAGS('California.LosAngeles', 2) VALUES('2018-10-03 14:38:05.500', 11.80000, 221, 0.28000)('2018-10-03 14:38:16.600', 13.40000, 223, 0.29000) " + - "d1004 USING power.meters TAGS('California.LosAngeles', 3) VALUES('2018-10-03 14:38:05.000', 10.80000, 223, 0.29000)('2018-10-03 14:38:06.500', 11.50000, 221, 0.35000)"; - res = TDengine.Query(conn, sql); - CheckRes(conn, res, "failed to insert data"); - int affectedRows = TDengine.AffectRows(res); - Console.WriteLine("affectedRows " + affectedRows); - TDengine.FreeResult(res); - } - finally - { - TDengine.Close(conn); - } - - } - - static IntPtr GetConnection() - { - string host = "localhost"; - short port = 6030; - string username = "root"; - string password = "taosdata"; - string dbname = ""; - var conn = TDengine.Connect(host, username, password, dbname, port); - if (conn == IntPtr.Zero) - { - throw new Exception("Connect to TDengine failed"); - } - else - { - Console.WriteLine("Connect to TDengine success"); - } - return conn; - } - - static void CheckRes(IntPtr conn, IntPtr res, String errorMsg) - { - if (TDengine.ErrorNo(res) != 0) - { - throw new Exception($"{errorMsg} since: {TDengine.Error(res)}"); + 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))"); + 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; + } } } - } } - -// output: -// Connect to TDengine success -// affectedRows 8 diff --git a/docs/examples/csharp/sqlInsert/sqlinsert.csproj b/docs/examples/csharp/sqlInsert/sqlinsert.csproj index 1b6f745c82..aa8e1402ae 100644 --- a/docs/examples/csharp/sqlInsert/sqlinsert.csproj +++ b/docs/examples/csharp/sqlInsert/sqlinsert.csproj @@ -9,7 +9,7 @@ - + diff --git a/docs/examples/csharp/stmtInsert/Program.cs b/docs/examples/csharp/stmtInsert/Program.cs index 2e856a49bb..e6b11a63e4 100644 --- a/docs/examples/csharp/stmtInsert/Program.cs +++ b/docs/examples/csharp/stmtInsert/Program.cs @@ -1,109 +1,38 @@ -using TDengineDriver; +using TDengine.Driver; +using TDengine.Driver.Client; namespace TDengineExample { internal class StmtInsertExample { - private static IntPtr conn; - private static IntPtr stmt; - static void Main() + public static void Main(string[] args) { - conn = GetConnection(); - try + var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); + using (var client = DbDriver.Open(builder)) { - PrepareSTable(); - // 1. init and prepare - stmt = TDengine.StmtInit(conn); - if (stmt == IntPtr.Zero) + try { - throw new Exception("failed to init stmt."); + 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}"); + } } - int res = TDengine.StmtPrepare(stmt, "INSERT INTO ? USING meters TAGS(?, ?) VALUES(?, ?, ?, ?)"); - CheckStmtRes(res, "failed to prepare stmt"); - - // 2. bind table name and tags - TAOS_MULTI_BIND[] tags = new TAOS_MULTI_BIND[2] { TaosMultiBind.MultiBindBinary(new string[] { "California.SanFrancisco" }), TaosMultiBind.MultiBindInt(new int?[] { 2 }) }; - res = TDengine.StmtSetTbnameTags(stmt, "d1001", tags); - CheckStmtRes(res, "failed to bind table name and tags"); - - // 3. bind values - TAOS_MULTI_BIND[] values = new TAOS_MULTI_BIND[4] { - TaosMultiBind.MultiBindTimestamp(new long[2] { 1648432611249, 1648432611749}), - TaosMultiBind.MultiBindFloat(new float?[2] { 10.3f, 12.6f}), - TaosMultiBind.MultiBindInt(new int?[2] { 219, 218}), - TaosMultiBind.MultiBindFloat(new float?[2]{ 0.31f, 0.33f}) - }; - res = TDengine.StmtBindParamBatch(stmt, values); - CheckStmtRes(res, "failed to bind params"); - - // 4. add batch - res = TDengine.StmtAddBatch(stmt); - CheckStmtRes(res, "failed to add batch"); - - // 5. execute - res = TDengine.StmtExecute(stmt); - CheckStmtRes(res, "failed to execute"); - - // 6. free - TaosMultiBind.FreeTaosBind(tags); - TaosMultiBind.FreeTaosBind(values); - } - finally - { - TDengine.Close(conn); - } - - } - - static IntPtr GetConnection() - { - string host = "localhost"; - short port = 6030; - string username = "root"; - string password = "taosdata"; - string dbname = ""; - var conn = TDengine.Connect(host, username, password, dbname, port); - if (conn == IntPtr.Zero) - { - throw new Exception("Connect to TDengine failed"); - } - else - { - Console.WriteLine("Connect to TDengine success"); - } - return conn; - } - - static void PrepareSTable() - { - IntPtr res = TDengine.Query(conn, "CREATE DATABASE power WAL_RETENTION_PERIOD 3600"); - CheckResPtr(res, "failed to create database"); - res = TDengine.Query(conn, "USE power"); - CheckResPtr(res, "failed to change database"); - res = TDengine.Query(conn, "CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)"); - CheckResPtr(res, "failed to create stable"); - } - - static void CheckStmtRes(int res, string errorMsg) - { - if (res != 0) - { - Console.WriteLine(errorMsg + ", " + TDengine.StmtErrorStr(stmt)); - int code = TDengine.StmtClose(stmt); - if (code != 0) + catch (Exception e) { - throw new Exception($"failed to close stmt, {code} reason: {TDengine.StmtErrorStr(stmt)} "); + Console.WriteLine(e); + throw; } } } - - static void CheckResPtr(IntPtr res, string errorMsg) - { - if (TDengine.ErrorNo(res) != 0) - { - throw new Exception(errorMsg + " since:" + TDengine.Error(res)); - } - } - } -} +} \ No newline at end of file diff --git a/docs/examples/csharp/stmtInsert/stmtinsert.csproj b/docs/examples/csharp/stmtInsert/stmtinsert.csproj index f5b2b67397..9fa3109b80 100644 --- a/docs/examples/csharp/stmtInsert/stmtinsert.csproj +++ b/docs/examples/csharp/stmtInsert/stmtinsert.csproj @@ -9,7 +9,7 @@ - + diff --git a/docs/examples/csharp/subscribe/Program.cs b/docs/examples/csharp/subscribe/Program.cs index 1fba209f22..d7c1a52117 100644 --- a/docs/examples/csharp/subscribe/Program.cs +++ b/docs/examples/csharp/subscribe/Program.cs @@ -1,95 +1,72 @@ -using System; -using TDengineTMQ; -using TDengineDriver; -using System.Runtime.InteropServices; + +using TDengine.Driver; +using TDengine.Driver.Client; +using TDengine.TMQ; namespace TMQExample { internal class SubscribeDemo { - static void Main(string[] args) + public static void Main(string[] args) { - IntPtr conn = GetConnection(); - string topic = "topic_example"; - //create topic - IntPtr res = TDengine.Query(conn, $"create topic if not exists {topic} as select * from meters"); - - if (TDengine.ErrorNo(res) != 0 ) + var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); + using (var client = DbDriver.Open(builder)) { - throw new Exception($"create topic failed, reason:{TDengine.Error(res)}"); - } - - var cfg = new ConsumerConfig - { - GourpId = "group_1", - TDConnectUser = "root", - TDConnectPasswd = "taosdata", - MsgWithTableName = "true", - TDConnectIp = "127.0.0.1", - }; - - // create consumer - var consumer = new ConsumerBuilder(cfg) - .Build(); - - // subscribe - consumer.Subscribe(topic); - - // consume - for (int i = 0; i < 5; i++) - { - var consumeRes = consumer.Consume(300); - // print consumeResult - foreach (KeyValuePair kv in consumeRes.Message) + try { - Console.WriteLine("topic partitions:\n{0}", kv.Key.ToString()); - - kv.Value.Metas.ForEach(meta => + 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() { - Console.Write("{0} {1}({2}) \t|", meta.name, meta.TypeName(), meta.size); - }); - Console.WriteLine(""); - kv.Value.Datas.ForEach(data => + { "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) { - Console.WriteLine(data.ToString()); - }); + 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; } - - consumer.Commit(consumeRes); - Console.WriteLine("\n================ {0} done ", i); - } - - // retrieve topic list - List topics = consumer.Subscription(); - topics.ForEach(t => Console.WriteLine("topic name:{0}", t)); - - // unsubscribe - consumer.Unsubscribe(); - - // close consumer after use.Otherwise will lead memory leak. - consumer.Close(); - TDengine.Close(conn); - } - static IntPtr GetConnection() + static void InsertData() { - string host = "localhost"; - short port = 6030; - string username = "root"; - string password = "taosdata"; - string dbname = "power"; - var conn = TDengine.Connect(host, username, password, dbname, port); - if (conn == IntPtr.Zero) + var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); + using (var client = DbDriver.Open(builder)) { - throw new Exception("Connect to TDengine failed"); + 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(); + } } - else - { - Console.WriteLine("Connect to TDengine success"); - } - return conn; } } diff --git a/docs/examples/csharp/subscribe/subscribe.csproj b/docs/examples/csharp/subscribe/subscribe.csproj index 191b3f9e9b..df6618d214 100644 --- a/docs/examples/csharp/subscribe/subscribe.csproj +++ b/docs/examples/csharp/subscribe/subscribe.csproj @@ -9,7 +9,7 @@ - + diff --git a/docs/examples/csharp/wsConnect/Program.cs b/docs/examples/csharp/wsConnect/Program.cs index a534bb8a65..edf0eb31e6 100644 --- a/docs/examples/csharp/wsConnect/Program.cs +++ b/docs/examples/csharp/wsConnect/Program.cs @@ -1,28 +1,18 @@ using System; -using TDengineWS.Impl; +using TDengine.Driver; +using TDengine.Driver.Client; namespace Examples { public class WSConnExample { - static int Main(string[] args) + static void Main(string[] args) { - string DSN = "ws://root:taosdata@127.0.0.1:6041/test"; - IntPtr wsConn = LibTaosWS.WSConnectWithDSN(DSN); - - if (wsConn == IntPtr.Zero) + var builder = new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata"); + using (var client = DbDriver.Open(builder)) { - Console.WriteLine("get WS connection failed"); - return -1; + Console.WriteLine("connected"); } - else - { - Console.WriteLine("Establish connect success."); - // close connection. - LibTaosWS.WSClose(wsConn); - } - - return 0; } } } diff --git a/docs/examples/csharp/wsConnect/wsConnect.csproj b/docs/examples/csharp/wsConnect/wsConnect.csproj index c7988b6e9c..01ab149af5 100644 --- a/docs/examples/csharp/wsConnect/wsConnect.csproj +++ b/docs/examples/csharp/wsConnect/wsConnect.csproj @@ -6,7 +6,7 @@ - + diff --git a/docs/examples/csharp/wsInsert/Program.cs b/docs/examples/csharp/wsInsert/Program.cs index 7fa6af805c..73136477e7 100644 --- a/docs/examples/csharp/wsInsert/Program.cs +++ b/docs/examples/csharp/wsInsert/Program.cs @@ -1,61 +1,46 @@ using System; -using TDengineWS.Impl; +using TDengine.Driver; +using TDengine.Driver.Client; namespace Examples { public class WSInsertExample { - static int Main(string[] args) + public static void Main(string[] args) { - string DSN = "ws://root:taosdata@127.0.0.1:6041/test"; - IntPtr wsConn = LibTaosWS.WSConnectWithDSN(DSN); - - // Assert if connection is validate - if (wsConn == IntPtr.Zero) + var builder = new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata"); + using (var client = DbDriver.Open(builder)) { - Console.WriteLine("get WS connection failed"); - return -1; - } - else - { - Console.WriteLine("Establish connect success."); - } - - string createTable = "CREATE STABLE test.meters (ts timestamp, current float, voltage int, phase float) TAGS (location binary(64), groupId int);"; - string insert = "INSERT INTO test.d1001 USING test.meters TAGS('California.SanFrancisco', 2) VALUES ('2018-10-03 14:38:05.000', 10.30000, 219, 0.31000) ('2018-10-03 14:38:15.000', 12.60000, 218, 0.33000) ('2018-10-03 14:38:16.800', 12.30000, 221, 0.31000)" + - "test.d1002 USING test.meters TAGS('California.SanFrancisco', 3) VALUES('2018-10-03 14:38:16.650', 10.30000, 218, 0.25000)" + - "test.d1003 USING test.meters TAGS('California.LosAngeles', 2) VALUES('2018-10-03 14:38:05.500', 11.80000, 221, 0.28000)('2018-10-03 14:38:16.600', 13.40000, 223, 0.29000) " + - "test.d1004 USING test.meters TAGS('California.LosAngeles', 3) VALUES('2018-10-03 14:38:05.000', 10.80000, 223, 0.29000)('2018-10-03 14:38:06.500', 11.50000, 221, 0.35000)"; - - IntPtr wsRes = LibTaosWS.WSQuery(wsConn, createTable); - ValidInsert("create table", wsRes); - LibTaosWS.WSFreeResult(wsRes); - - wsRes = LibTaosWS.WSQuery(wsConn, insert); - ValidInsert("insert data", wsRes); - LibTaosWS.WSFreeResult(wsRes); - - // close connection. - LibTaosWS.WSClose(wsConn); - - return 0; - } - - static void ValidInsert(string desc, IntPtr wsRes) - { - int code = LibTaosWS.WSErrorNo(wsRes); - if (code != 0) - { - Console.WriteLine($"execute SQL failed: reason: {LibTaosWS.WSErrorStr(wsRes)}, code:{code}"); - } - else - { - Console.WriteLine("{0} success affect {2} rows, cost {1} nanoseconds", desc, LibTaosWS.WSTakeTiming(wsRes), LibTaosWS.WSAffectRows(wsRes)); + 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))"); + 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; + } } } } - } -// Establish connect success. -// create table success affect 0 rows, cost 3717542 nanoseconds -// insert data success affect 8 rows, cost 2613637 nanoseconds diff --git a/docs/examples/csharp/wsInsert/wsInsert.csproj b/docs/examples/csharp/wsInsert/wsInsert.csproj index 5aa419b2c8..0459e8e38b 100644 --- a/docs/examples/csharp/wsInsert/wsInsert.csproj +++ b/docs/examples/csharp/wsInsert/wsInsert.csproj @@ -6,7 +6,7 @@ enable - + diff --git a/docs/examples/csharp/wsQuery/Program.cs b/docs/examples/csharp/wsQuery/Program.cs index 8ee900a05a..40aac24597 100644 --- a/docs/examples/csharp/wsQuery/Program.cs +++ b/docs/examples/csharp/wsQuery/Program.cs @@ -1,79 +1,36 @@ using System; -using TDengineWS.Impl; -using System.Collections.Generic; -using TDengineDriver; +using System.Text; +using TDengine.Driver; +using TDengine.Driver.Client; namespace Examples { public class WSQueryExample { - static int Main(string[] args) + public static void Main(string[] args) { - string DSN = "ws://root:taosdata@127.0.0.1:6041/test"; - IntPtr wsConn = LibTaosWS.WSConnectWithDSN(DSN); - if (wsConn == IntPtr.Zero) + var builder = new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata"); + using (var client = DbDriver.Open(builder)) { - Console.WriteLine("get WS connection failed"); - return -1; - } - else - { - Console.WriteLine("Establish connect success."); - } - - string select = "select * from test.meters"; - - // optional:wsRes = LibTaosWS.WSQuery(wsConn, select); - IntPtr wsRes = LibTaosWS.WSQueryTimeout(wsConn, select, 1); - // Assert if query execute success. - int code = LibTaosWS.WSErrorNo(wsRes); - if (code != 0) - { - Console.WriteLine($"execute SQL failed: reason: {LibTaosWS.WSErrorStr(wsRes)}, code:{code}"); - LibTaosWS.WSFreeResult(wsRes); - return -1; - } - - // get meta data - List metas = LibTaosWS.WSGetFields(wsRes); - // get retrieved data - List dataSet = LibTaosWS.WSGetData(wsRes); - - // do something with result. - foreach (var meta in metas) - { - Console.Write("{0} {1}({2}) \t|\t", meta.name, meta.TypeName(), meta.size); - } - Console.WriteLine(""); - - for (int i = 0; i < dataSet.Count;) - { - for (int j = 0; j < metas.Count; j++) + try { - Console.Write("{0}\t|\t", dataSet[i]); - i++; + 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; } - Console.WriteLine(""); } - - // Free result after use. - LibTaosWS.WSFreeResult(wsRes); - - // close connection. - LibTaosWS.WSClose(wsConn); - - return 0; } } -} - -// Establish connect success. -// ts TIMESTAMP(8) | current FLOAT(4) | voltage INT(4) | phase FLOAT(4) | location BINARY(64) | groupid INT(4) | -// 1538548685000 | 10.8 | 223 | 0.29 | California.LosAngeles | 3 | -// 1538548686500 | 11.5 | 221 | 0.35 | California.LosAngeles | 3 | -// 1538548685500 | 11.8 | 221 | 0.28 | California.LosAngeles | 2 | -// 1538548696600 | 13.4 | 223 | 0.29 | California.LosAngeles | 2 | -// 1538548685000 | 10.3 | 219 | 0.31 | California.SanFrancisco | 2 | -// 1538548695000 | 12.6 | 218 | 0.33 | California.SanFrancisco | 2 | -// 1538548696800 | 12.3 | 221 | 0.31 | California.SanFrancisco | 2 | -// 1538548696650 | 10.3 | 218 | 0.25 | California.SanFrancisco | 3 | +} \ No newline at end of file diff --git a/docs/examples/csharp/wsQuery/wsQuery.csproj b/docs/examples/csharp/wsQuery/wsQuery.csproj index bcc7c19a59..ff283947b4 100644 --- a/docs/examples/csharp/wsQuery/wsQuery.csproj +++ b/docs/examples/csharp/wsQuery/wsQuery.csproj @@ -7,7 +7,7 @@ - + diff --git a/docs/examples/csharp/wsStmt/Program.cs b/docs/examples/csharp/wsStmt/Program.cs index f8673357db..5166dfea92 100644 --- a/docs/examples/csharp/wsStmt/Program.cs +++ b/docs/examples/csharp/wsStmt/Program.cs @@ -1,98 +1,41 @@ using System; -using TDengineWS.Impl; -using TDengineDriver; -using System.Runtime.InteropServices; +using TDengine.Driver; +using TDengine.Driver.Client; namespace Examples { public class WSStmtExample { - static int Main(string[] args) + public static void Main(string[] args) { - const string DSN = "ws://root:taosdata@127.0.0.1:6041/test"; - const string table = "meters"; - const string database = "test"; - const string childTable = "d1005"; - string insert = $"insert into ? using {database}.{table} tags(?,?) values(?,?,?,?)"; - const int numOfTags = 2; - const int numOfColumns = 4; - - // Establish connection - IntPtr wsConn = LibTaosWS.WSConnectWithDSN(DSN); - if (wsConn == IntPtr.Zero) + var builder = + new ConnectionStringBuilder( + "protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata"); + using (var client = DbDriver.Open(builder)) { - Console.WriteLine($"get WS connection failed"); - return -1; - } - else - { - Console.WriteLine("Establish connect success..."); - } - - // init stmt - IntPtr wsStmt = LibTaosWS.WSStmtInit(wsConn); - if (wsStmt != IntPtr.Zero) - { - int code = LibTaosWS.WSStmtPrepare(wsStmt, insert); - ValidStmtStep(code, wsStmt, "WSStmtPrepare"); - - TAOS_MULTI_BIND[] wsTags = new TAOS_MULTI_BIND[] { WSMultiBind.WSBindNchar(new string[] { "California.SanDiego" }), WSMultiBind.WSBindInt(new int?[] { 4 }) }; - code = LibTaosWS.WSStmtSetTbnameTags(wsStmt, $"{database}.{childTable}", wsTags, numOfTags); - ValidStmtStep(code, wsStmt, "WSStmtSetTbnameTags"); - - TAOS_MULTI_BIND[] data = new TAOS_MULTI_BIND[4]; - data[0] = WSMultiBind.WSBindTimestamp(new long[] { 1538548687000, 1538548688000, 1538548689000, 1538548690000, 1538548691000 }); - data[1] = WSMultiBind.WSBindFloat(new float?[] { 10.30F, 10.40F, 10.50F, 10.60F, 10.70F }); - data[2] = WSMultiBind.WSBindInt(new int?[] { 223, 221, 222, 220, 219 }); - data[3] = WSMultiBind.WSBindFloat(new float?[] { 0.31F, 0.32F, 0.33F, 0.35F, 0.28F }); - code = LibTaosWS.WSStmtBindParamBatch(wsStmt, data, numOfColumns); - ValidStmtStep(code, wsStmt, "WSStmtBindParamBatch"); - - code = LibTaosWS.WSStmtAddBatch(wsStmt); - ValidStmtStep(code, wsStmt, "WSStmtAddBatch"); - - IntPtr stmtAffectRowPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Int32))); - code = LibTaosWS.WSStmtExecute(wsStmt, stmtAffectRowPtr); - ValidStmtStep(code, wsStmt, "WSStmtExecute"); - Console.WriteLine("WS STMT insert {0} rows...", Marshal.ReadInt32(stmtAffectRowPtr)); - Marshal.FreeHGlobal(stmtAffectRowPtr); - - LibTaosWS.WSStmtClose(wsStmt); - - // Free unmanaged memory - WSMultiBind.WSFreeTaosBind(wsTags); - WSMultiBind.WSFreeTaosBind(data); - - //check result with SQL "SELECT * FROM test.d1005;" - } - else - { - Console.WriteLine("Init STMT failed..."); - } - - // close connection. - LibTaosWS.WSClose(wsConn); - - return 0; - } - - static void ValidStmtStep(int code, IntPtr wsStmt, string desc) - { - if (code != 0) - { - Console.WriteLine($"{desc} failed,reason: {LibTaosWS.WSErrorStr(wsStmt)}, code: {code}"); - } - else - { - Console.WriteLine("{0} success...", desc); + 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; + } } } } -} - -// WSStmtPrepare success... -// WSStmtSetTbnameTags success... -// WSStmtBindParamBatch success... -// WSStmtAddBatch success... -// WSStmtExecute success... -// WS STMT insert 5 rows... +} \ No newline at end of file diff --git a/docs/examples/csharp/wsStmt/wsStmt.csproj b/docs/examples/csharp/wsStmt/wsStmt.csproj index bcc7c19a59..ff283947b4 100644 --- a/docs/examples/csharp/wsStmt/wsStmt.csproj +++ b/docs/examples/csharp/wsStmt/wsStmt.csproj @@ -7,7 +7,7 @@ - + diff --git a/docs/zh/07-develop/01-connect/index.md b/docs/zh/07-develop/01-connect/index.md index 83032067d9..9d954f78ce 100644 --- a/docs/zh/07-develop/01-connect/index.md +++ b/docs/zh/07-develop/01-connect/index.md @@ -176,7 +176,7 @@ npm install @tdengine/rest - + diff --git a/docs/zh/07-develop/04-query-data/_cs_async.mdx b/docs/zh/07-develop/04-query-data/_cs_async.mdx deleted file mode 100644 index 19c8e58f32..0000000000 --- a/docs/zh/07-develop/04-query-data/_cs_async.mdx +++ /dev/null @@ -1,3 +0,0 @@ -```csharp -{{#include docs/examples/csharp/asyncQuery/Program.cs}} -``` diff --git a/docs/zh/07-develop/04-query-data/index.mdx b/docs/zh/07-develop/04-query-data/index.mdx index d4d6d8192d..e892f9fc8d 100644 --- a/docs/zh/07-develop/04-query-data/index.mdx +++ b/docs/zh/07-develop/04-query-data/index.mdx @@ -16,7 +16,6 @@ import CQuery from "./_c.mdx"; import PhpQuery from "./_php.mdx"; import PyAsync from "./_py_async.mdx"; import NodeAsync from "./_js_async.mdx"; -import CsAsync from "./_cs_async.mdx"; import CAsync from "./_c_async.mdx"; ## 主要查询功能 @@ -175,9 +174,6 @@ Query OK, 6 rows in database (0.005515s) - - - diff --git a/docs/zh/07-develop/07-tmq.mdx b/docs/zh/07-develop/07-tmq.mdx index d3b27fedc3..f945f53b5c 100644 --- a/docs/zh/07-develop/07-tmq.mdx +++ b/docs/zh/07-develop/07-tmq.mdx @@ -248,23 +248,23 @@ function close() ```csharp +class ConsumerBuilder + ConsumerBuilder(IEnumerable> config) -virtual IConsumer Build() - -Consumer(ConsumerBuilder builder) +public IConsumer Build() void Subscribe(IEnumerable topics) void Subscribe(string topic) -ConsumeResult Consume(int millisecondsTimeout) +ConsumeResult Consume(int millisecondsTimeout) List Subscription() void Unsubscribe() -void Commit(ConsumeResult consumerResult) +List Commit() void Close() ``` @@ -501,25 +501,19 @@ let consumer = taos.consumer({ ```csharp -using TDengineTMQ; - -// 根据需要,设置消费组 (GourpId)、自动提交 (EnableAutoCommit)、 -// 自动提交时间间隔 (AutoCommitIntervalMs)、用户名 (TDConnectUser)、密码 (TDConnectPasswd) 等参数 -var cfg = new ConsumerConfig - { - EnableAutoCommit = "true" - AutoCommitIntervalMs = "1000" - GourpId = "TDengine-TMQ-C#", - TDConnectUser = "root", - TDConnectPasswd = "taosdata", - AutoOffsetReset = "latest" - MsgWithTableName = "true", - TDConnectIp = "127.0.0.1", - TDConnectPort = "6030" - }; - -var consumer = new ConsumerBuilder(cfg).Build(); - +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(); ``` @@ -748,10 +742,12 @@ while(true){ // 消费数据 while (true) { - var consumerRes = consumer.Consume(100); - // process ConsumeResult - ProcessMsg(consumerRes); - consumer.Commit(consumerRes); + using (var result = consumer.Consume(500)) + { + if (result == null) continue; + ProcessMsg(result); + consumer.Commit(); + } } ``` diff --git a/docs/zh/08-connector/40-csharp.mdx b/docs/zh/08-connector/40-csharp.mdx index 325c71da88..f88002d3dc 100644 --- a/docs/zh/08-connector/40-csharp.mdx +++ b/docs/zh/08-connector/40-csharp.mdx @@ -1,27 +1,22 @@ --- toc_max_heading_level: 4 sidebar_label: C# -title: C# Connector +title: TDengine C# Connector --- import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -import Preparation from "./_preparation.mdx" -import CSInsert from "../07-develop/03-insert-data/_cs_sql.mdx" -import CSInfluxLine from "../07-develop/03-insert-data/_cs_line.mdx" -import CSOpenTSDBTelnet from "../07-develop/03-insert-data/_cs_opts_telnet.mdx" -import CSOpenTSDBJson from "../07-develop/03-insert-data/_cs_opts_json.mdx" -import CSQuery from "../07-develop/04-query-data/_cs.mdx" -import CSAsyncQuery from "../07-develop/04-query-data/_cs_async.mdx" - `TDengine.Connector` 是 TDengine 提供的 C# 语言连接器。C# 开发人员可以通过它开发存取 TDengine 集群数据的 C# 应用软件。 -`TDengine.Connector` 连接器支持通过 TDengine 客户端驱动(taosc)建立与 TDengine 运行实例的连接,提供数据写入、查询、数据订阅、schemaless 数据写入、参数绑定接口数据写入等功能。 `TDengine.Connector` 自 v3.0.1 起还支持 WebSocket,通过 DSN 建立 WebSocket 连接,提供数据写入、查询、参数绑定接口数据写入等功能。 +`TDengine.Connector` 连接器支持通过 TDengine 客户端驱动(taosc)建立与 TDengine 运行实例的连接,提供数据写入、查询、数据订阅、schemaless 数据写入、参数绑定接口数据写入等功能。 `TDengine.Connector` 自 v3.0.1 起还支持 WebSocket 连接,提供数据写入、查询、参数绑定接口数据写入等功能。 本文介绍如何在 Linux 或 Windows 环境中安装 `TDengine.Connector`,并通过 `TDengine.Connector` 连接 TDengine 集群,进行数据写入、查询等基本操作。 -注意:`TDengine.Connector` 3.x 不兼容 TDengine 2.x,如果在运行 TDengine 2.x 版本的环境下需要使用 C# 连接器请使用 TDengine.Connector 的 1.x 版本 。 +:::warning +* `TDengine.Connector` 3.1.0 版本进行了完整的重构,不再兼容 3.0.2 及以前版本。3.0.2 文档请参考 [nuget](https://www.nuget.org/packages/TDengine.Connector/3.0.2) +* `TDengine.Connector` 3.x 不兼容 TDengine 2.x,如果在运行 TDengine 2.x 版本的环境下需要使用 C# 连接器请使用 TDengine.Connector 的 1.x 版本。 +::: `TDengine.Connector` 的源码托管在 [GitHub](https://github.com/taosdata/taos-connector-dotnet/tree/3.0)。 @@ -29,39 +24,43 @@ import CSAsyncQuery from "../07-develop/04-query-data/_cs_async.mdx" 支持的平台和 TDengine 客户端驱动支持的平台一致。 -:::note -注意 TDengine 不再支持 32 位 Windows 平台。 +:::warning +TDengine 不再支持 32 位 Windows 平台。 ::: ## 版本支持 -请参考[版本支持列表](../#版本支持) +| **Connector version** | **TDengine version** | +|-----------------------|----------------------| +| 3.1.0 | 3.2.1.0/3.1.1.18 | -## 支持的功能特性 +## 处理异常 - +`TDengine.Connector` 会抛出异常,应用程序需要处理异常。taosc 异常类型 `TDengineError`,包含错误码和错误信息,应用程序可以根据错误码和错误信息进行处理。 - +## TDengine DataType 和 C# DataType -1. 连接管理 -2. 普通查询 -3. 连续查询 -4. 参数绑定 -5. 数据订阅(TMQ) -6. Schemaless - - +| TDengine DataType | C# Type | +|-------------------|------------------| +| TIMESTAMP | DateTime | +| TINYINT | sbyte | +| SMALLINT | short | +| INT | int | +| BIGINT | long | +| TINYINT UNSIGNED | byte | +| SMALLINT UNSIGNED | ushort | +| INT UNSIGNED | uint | +| BIGINT UNSIGNED | ulong | +| FLOAT | float | +| DOUBLE | double | +| BOOL | bool | +| BINARY | byte[] | +| NCHAR | string (utf-8编码) | +| JSON | byte[] | - - -1. 连接管理 -2. 普通查询 -3. 连续查询 -4. 参数绑定 - - - - +:::note +JSON 类型仅在 tag 中支持。 +::: ## 安装步骤 @@ -71,10 +70,7 @@ import CSAsyncQuery from "../07-develop/04-query-data/_cs_async.mdx" * [Nuget 客户端](https://docs.microsoft.com/en-us/nuget/install-nuget-client-tools) (可选安装) * 安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../#安装客户端驱动) -### 安装 TDengine.Connector - - - +### 安装连接器 可以在当前 .NET 项目的路径下,通过 dotnet CLI 添加 Nuget package `TDengine.Connector` 到当前项目。 @@ -86,234 +82,1109 @@ dotnet add package TDengine.Connector ``` XML - + ``` - - - - -需要修改目标项目的 `.csproj` 项目文件,将 `.nupkg` 中的 `runtimes` 目录中的动态库复制到当前项目的 `$(OutDir)` 目录下。 - -```XML - - - - - - - - - -``` - -注意:`TDengine.Connector` 自 version>= 3.0.2 的 nuget package 中才会有动态库( taosws.dll,libtaows.so )。 - - - - ## 建立连接 - - + -使用 host、username、password、port 等信息建立连接。 - ``` csharp -using TDengineDriver; - -namespace TDengineExample +var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); +using (var client = DbDriver.Open(builder)) { + Console.WriteLine("connected"); +} +``` - internal class EstablishConnection + + + +```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` 对象。 + +### 指定 URL 和 Properties 获取连接 + +C# 连接器不支持此功能 + +### 配置参数的优先级 + +C# 连接器不支持此功能 + +## 使用示例 + +### 创建数据库和表 + + + + +```csharp +using System; +using System.Text; +using TDengine.Driver; +using TDengine.Driver.Client; + +namespace NativeQuery +{ + internal class Query { - static void Main(String[] args) + public static void Main(string[] args) { - string host = "localhost"; - short port = 6030; - string username = "root"; - string password = "taosdata"; - string dbname = ""; - - var conn = TDengine.Connect(host, username, password, dbname, port); - if (conn == IntPtr.Zero) + var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); + using (var client = DbDriver.Open(builder)) { - Console.WriteLine("Connect to TDengine failed"); + 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; + } } - else - { - Console.WriteLine("Connect to TDengine success"); - } - TDengine.Close(conn); - TDengine.Cleanup(); } } } ``` + - +```csharp +using System; +using System.Text; +using TDengine.Driver; +using TDengine.Driver.Client; -使用 DSN 建立 WebSocket 连接 DSN 连接。 描述字符串基本结构如下: - -```text -[]://[[:@]:][/][?=[&=]] -|------------|---|-----------|-----------|------|------|------------|-----------------------| -| protocol | | username | password | host | port | database | params | -``` - -各部分意义见下表: - -* **protocol**: 显示指定以何种方式建立连接,例如:`ws://localhost:6041` 指定以 Websocket 方式建立连接(支持 http/ws )。 - -* **username/password**: 用于创建连接的用户名及密码(默认 `root/taosdata` )。 - -* **host/port**: 指定创建连接的服务器及端口,WebSocket 连接默认为 `localhost:6041` 。 - -* **database**: 指定默认连接的数据库名,可选参数。 - -* **params**:其他可选参数。 - -``` csharp -{{#include docs/examples/csharp/wsConnect/Program.cs}} +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; + } + } + } + } +} ``` -## 使用示例 - -### 写入数据 - -#### SQL 写入 - - +### 插入数据 + - +```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 -{{#include docs/examples/csharp/wsInsert/Program.cs}} +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; + } + } + } + } +} ``` - - - -#### InfluxDB 行协议写入 - - - -#### OpenTSDB Telnet 行协议写入 - - - -#### OpenTSDB JSON 行协议写入 - - - -#### 参数绑定 - - - - - -``` csharp -{{#include docs/examples/csharp/stmtInsert/Program.cs}} -``` - - - - - -```csharp -{{#include docs/examples/csharp/wsStmt/Program.cs}} -``` - - - ### 查询数据 -#### 同步查询 - - - + - - - - - - ```csharp -{{#include docs/examples/csharp/wsQuery/Program.cs}} +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: 消息是否包含表名 + + +支持订阅结果集 `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)。 ### 更多示例程序 -|示例程序 | 示例程序描述 | -|--------------------------------------------------------------------------------------------------------------------|--------------------------------------------| -| [CURD](https://github.com/taosdata/taos-connector-dotnet/blob/3.0/examples/NET6Examples/Query/Query.cs) | 使用 TDengine.Connector 实现的建表、插入、查询示例 | -| [JSON Tag](https://github.com/taosdata/taos-connector-dotnet/blob/3.0/examples/NET6Examples/JSONTag) | 使用 TDengine.Connector 实现的写入和查询 JSON tag 类型数据的示例 | -| [stmt](https://github.com/taosdata/taos-connector-dotnet/tree/3.0/examples/NET6Examples/Stmt) | 使用 TDengine.Connector 实现的参数绑定插入和查询的示例 | -| [schemaless](https://github.com/taosdata/taos-connector-dotnet/blob/3.0/examples/NET6Examples/schemaless) | 使用 TDengine.Connector 实现的使用 schemaless 写入的示例 | -| [async query](https://github.com/taosdata/taos-connector-dotnet/blob/3.0/examples/NET6Examples/AsyncQuery/QueryAsync.cs) | 使用 TDengine.Connector 实现的异步查询的示例 | -| [数据订阅(TMQ)](https://github.com/taosdata/taos-connector-dotnet/blob/3.0/examples/NET6Examples/TMQ/TMQ.cs) | 使用 TDengine.Connector 实现的订阅数据的示例 | -| [Basic WebSocket Usage](https://github.com/taosdata/taos-connector-dotnet/blob/3.0/examples/FrameWork45/WS/WebSocketSample.cs) | 使用 TDengine.Connector 的 WebSocket 基本的示例 | -| [Basic WebSocket STMT](https://github.com/taosdata/taos-connector-dotnet/blob/3.0/examples/FrameWork45/WS/WebSocketSTMT.cs) | 使用 TDengine.Connector 的 WebSocket STMT 基本的示例 | - -## 重要更新记录 - -| TDengine.Connector | 说明 | -|--------------------|--------------------------------| -| 3.0.2 | 支持 .NET Framework 4.5 及以上,支持 .NET standard 2.0。Nuget Package 包含 WebSocket 动态库。 | -| 3.0.1 | 支持 WebSocket 和 Cloud,查询,插入,参数绑定。 | -| 3.0.0 | 支持 TDengine 3.0.0.0,不兼容 2.x。新增接口TDengine.Impl.GetData(),解析查询结果。 | -| 1.0.7 | 修复 TDengine.Query()内存泄露。 | -| 1.0.6 | 修复 schemaless 在 1.0.4 和 1.0.5 中失效 bug。 | -| 1.0.5 | 修复 Windows 同步查询中文报错 bug。 | -| 1.0.4 | 新增异步查询,订阅等功能。修复绑定参数 bug。 | -| 1.0.3 | 新增参数绑定、schemaless、 json tag等功能。 | -| 1.0.2 | 新增连接管理、同步查询、错误信息等功能。 | - -## 其他说明 - -### 第三方驱动 - -[`IoTSharp.Data.Taos`](https://github.com/IoTSharp/EntityFrameworkCore.Taos) 是一个 TDengine 的 ADO.NET 连接器,其中包含了用于EntityFrameworkCore 的提供程序 IoTSharp.EntityFrameworkCore.Taos 和健康检查组件 IoTSharp.HealthChecks.Taos ,支持 Linux,Windows 平台。该连接器由社区贡献者`麦壳饼@@maikebing` 提供,具体请参考: - -* 接口下载: -* 用法说明: - -## 常见问题 - -1. "Unable to establish connection","Unable to resolve FQDN" - - 一般是因为 FQDN 配置不正确。可以参考[如何彻底搞懂 TDengine 的 FQDN](https://www.taosdata.com/blog/2021/07/29/2741.html)解决。 - -2. Unhandled exception. System.DllNotFoundException: Unable to load DLL 'taos' or one of its dependencies: 找不到指定的模块。 - - 一般是因为程序没有找到依赖的客户端驱动。解决方法为:Windows 下可以将 `C:\TDengine\driver\taos.dll` 拷贝到 `C:\Windows\System32\ ` 目录下,Linux 下建立如下软链接 `ln -s /usr/local/taos/driver/libtaos.so.x.x.x.x /usr/lib/libtaos.so` 即可。 - -## API 参考 - -[API 参考](https://docs.taosdata.com/api/connector-csharp/html/860d2ac1-dd52-39c9-e460-0829c4e5a40b.htm) +[示例程序](https://github.com/taosdata/taos-connector-dotnet/tree/3.0/examples) \ No newline at end of file diff --git a/tests/docs-examples-test/csharp.sh b/tests/docs-examples-test/csharp.sh index c08ffd6d62..9d7867d829 100644 --- a/tests/docs-examples-test/csharp.sh +++ b/tests/docs-examples-test/csharp.sh @@ -11,10 +11,9 @@ dotnet run --project connect/connect.csproj taos -s "drop database if exists power" dotnet run --project sqlInsert/sqlinsert.csproj dotnet run --project query/query.csproj -dotnet run --project asyncQuery/asyncquery.csproj -dotnet run --project subscribe/subscribe.csproj +#dotnet run --project subscribe/subscribe.csproj -taos -s "drop topic if exists topic_example" +#taos -s "drop topic if exists topic_example" taos -s "drop database if exists power" dotnet run --project stmtInsert/stmtinsert.csproj @@ -28,10 +27,12 @@ taos -s "drop database if exists test" dotnet run --project optsJSON/optsJSON.csproj taos -s "create database if not exists test" +taos -s "drop database if exists power" dotnet run --project wsConnect/wsConnect.csproj dotnet run --project wsInsert/wsInsert.csproj -dotnet run --project wsStmt/wsStmt.csproj dotnet run --project wsQuery/wsQuery.csproj +taos -s "drop database if exists power" +dotnet run --project wsStmt/wsStmt.csproj taos -s "drop database if exists test" taos -s "drop database if exists power"