diff --git a/docs/en/07-develop/01-connect/index.md b/docs/en/07-develop/01-connect/index.md index ec3ed7b6dd..90b63d96e3 100644 --- a/docs/en/07-develop/01-connect/index.md +++ b/docs/en/07-develop/01-connect/index.md @@ -172,7 +172,7 @@ npm install @tdengine/rest Just need to add the reference to [TDengine.Connector](https://www.nuget.org/packages/TDengine.Connector/) in the project configuration file. -```xml title=csharp.csproj {12} +```xml title=csharp.csproj diff --git a/docs/examples/csharp/connect/Program.cs b/docs/examples/csharp/connect/Program.cs index 0152b61b03..697871573c 100644 --- a/docs/examples/csharp/connect/Program.cs +++ b/docs/examples/csharp/connect/Program.cs @@ -3,16 +3,34 @@ using TDengine.Driver.Client; namespace TDengineExample { - internal class ConnectExample { + // ANCHOR: main static void Main(String[] args) { - var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) + try { - Console.WriteLine("connected"); + // Connect to TDengine server using Native + var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); + // Open connection with using block, it will close the connection automatically + using (var client = DbDriver.Open(builder)) + { + Console.WriteLine("connected"); + } + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; } } + // ANCHOR_END: main } -} +} \ No newline at end of file diff --git a/docs/examples/csharp/csharp.sln b/docs/examples/csharp/csharp.sln index 59c198b4c9..3e8074122c 100644 --- a/docs/examples/csharp/csharp.sln +++ b/docs/examples/csharp/csharp.sln @@ -27,6 +27,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wsStmt", "wsStmt\wsStmt.csp EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "sqlinsert", "sqlInsert\sqlinsert.csproj", "{CD24BD12-8550-4627-A11D-707B446F48C3}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nativesml", "nativesml\nativesml.csproj", "{18ADDBE8-B266-4A66-8CC5-CFF80B530EFD}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wssml", "wssml\wssml.csproj", "{C3E62FDB-CCBC-4F72-ACF6-D3B2C39630E3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wssubscribe", "wssubscribe\wssubscribe.csproj", "{CB4BCBA5-C758-433F-8B90-7389F59E46BD}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -84,5 +90,17 @@ Global {CD24BD12-8550-4627-A11D-707B446F48C3}.Debug|Any CPU.Build.0 = Debug|Any CPU {CD24BD12-8550-4627-A11D-707B446F48C3}.Release|Any CPU.ActiveCfg = Release|Any CPU {CD24BD12-8550-4627-A11D-707B446F48C3}.Release|Any CPU.Build.0 = Release|Any CPU + {18ADDBE8-B266-4A66-8CC5-CFF80B530EFD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {18ADDBE8-B266-4A66-8CC5-CFF80B530EFD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {18ADDBE8-B266-4A66-8CC5-CFF80B530EFD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {18ADDBE8-B266-4A66-8CC5-CFF80B530EFD}.Release|Any CPU.Build.0 = Release|Any CPU + {C3E62FDB-CCBC-4F72-ACF6-D3B2C39630E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C3E62FDB-CCBC-4F72-ACF6-D3B2C39630E3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C3E62FDB-CCBC-4F72-ACF6-D3B2C39630E3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C3E62FDB-CCBC-4F72-ACF6-D3B2C39630E3}.Release|Any CPU.Build.0 = Release|Any CPU + {CB4BCBA5-C758-433F-8B90-7389F59E46BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CB4BCBA5-C758-433F-8B90-7389F59E46BD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CB4BCBA5-C758-433F-8B90-7389F59E46BD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CB4BCBA5-C758-433F-8B90-7389F59E46BD}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/docs/examples/csharp/nativesml/Program.cs b/docs/examples/csharp/nativesml/Program.cs new file mode 100644 index 0000000000..c4925041a1 --- /dev/null +++ b/docs/examples/csharp/nativesml/Program.cs @@ -0,0 +1,57 @@ +using TDengine.Driver; +using TDengine.Driver.Client; + +namespace TDengineExample +{ + internal class NativeSMLExample + { + // ANCHOR: main + public static void Main(string[] args) + { + var host = "127.0.0.1"; + + var lineDemo = + "meters,groupid=2,location=California.SanFrancisco current=10.3000002f64,voltage=219i32,phase=0.31f64 1626006833639"; + + var telnetDemo = "metric_telnet 1707095283260 4 host=host0 interface=eth0"; + + var jsonDemo = + "{\"metric\": \"metric_json\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}"; + try + { + var builder = + new ConnectionStringBuilder( + $"host={host};port=6030;username=root;password=taosdata"); + using (var client = DbDriver.Open(builder)) + { + // create database + client.Exec("CREATE DATABASE IF NOT EXISTS power"); + // use database + client.Exec("USE power"); + // insert influx line protocol data + client.SchemalessInsert(new[]{lineDemo}, TDengineSchemalessProtocol.TSDB_SML_LINE_PROTOCOL, + TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS, 0, ReqId.GetReqId()); + // insert opentsdb telnet protocol data + client.SchemalessInsert(new[]{telnetDemo}, TDengineSchemalessProtocol.TSDB_SML_TELNET_PROTOCOL, + TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS, 0, ReqId.GetReqId()); + // insert json data + client.SchemalessInsert(new []{jsonDemo}, TDengineSchemalessProtocol.TSDB_SML_JSON_PROTOCOL, + TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_NOT_CONFIGURED, 0, ReqId.GetReqId()); + } + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + } + // ANCHOR_END: main + } +} \ No newline at end of file diff --git a/docs/examples/csharp/nativesml/nativesml.csproj b/docs/examples/csharp/nativesml/nativesml.csproj new file mode 100644 index 0000000000..afad009614 --- /dev/null +++ b/docs/examples/csharp/nativesml/nativesml.csproj @@ -0,0 +1,13 @@ + + + + Exe + net6.0 + enable + enable + + + + + + diff --git a/docs/examples/csharp/nativesml/obj/nativesml.csproj.nuget.dgspec.json b/docs/examples/csharp/nativesml/obj/nativesml.csproj.nuget.dgspec.json new file mode 100644 index 0000000000..74b8259305 --- /dev/null +++ b/docs/examples/csharp/nativesml/obj/nativesml.csproj.nuget.dgspec.json @@ -0,0 +1,67 @@ +{ + "format": 1, + "restore": { + "/mnt/e/github/TDengine/docs/examples/csharp/nativesml/nativesml.csproj": {} + }, + "projects": { + "/mnt/e/github/TDengine/docs/examples/csharp/nativesml/nativesml.csproj": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "/mnt/e/github/TDengine/docs/examples/csharp/nativesml/nativesml.csproj", + "projectName": "nativesml", + "projectPath": "/mnt/e/github/TDengine/docs/examples/csharp/nativesml/nativesml.csproj", + "packagesPath": "/root/.nuget/packages/", + "outputPath": "/mnt/e/github/TDengine/docs/examples/csharp/nativesml/obj/", + "projectStyle": "PackageReference", + "configFilePaths": [ + "/root/.nuget/NuGet/NuGet.Config" + ], + "originalTargetFrameworks": [ + "net6.0" + ], + "sources": { + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "net6.0": { + "targetAlias": "net6.0", + "projectReferences": {} + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + } + }, + "frameworks": { + "net6.0": { + "targetAlias": "net6.0", + "dependencies": { + "TDengine.Connector": { + "target": "Package", + "version": "[3.1.*, )" + } + }, + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48", + "net481" + ], + "assetTargetFallback": true, + "warn": true, + "frameworkReferences": { + "Microsoft.NETCore.App": { + "privateAssets": "all" + } + }, + "runtimeIdentifierGraphPath": "/root/.dotnet/sdk/8.0.100/RuntimeIdentifierGraph.json" + } + } + } + } +} \ No newline at end of file diff --git a/docs/examples/csharp/nativesml/obj/nativesml.csproj.nuget.g.props b/docs/examples/csharp/nativesml/obj/nativesml.csproj.nuget.g.props new file mode 100644 index 0000000000..a270b60d2c --- /dev/null +++ b/docs/examples/csharp/nativesml/obj/nativesml.csproj.nuget.g.props @@ -0,0 +1,15 @@ + + + + True + NuGet + $(MSBuildThisFileDirectory)project.assets.json + /root/.nuget/packages/ + /root/.nuget/packages/ + PackageReference + 6.8.0 + + + + + \ No newline at end of file diff --git a/docs/examples/csharp/nativesml/obj/nativesml.csproj.nuget.g.targets b/docs/examples/csharp/nativesml/obj/nativesml.csproj.nuget.g.targets new file mode 100644 index 0000000000..35a7576c5a --- /dev/null +++ b/docs/examples/csharp/nativesml/obj/nativesml.csproj.nuget.g.targets @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/docs/examples/csharp/nativesml/obj/project.assets.json b/docs/examples/csharp/nativesml/obj/project.assets.json new file mode 100644 index 0000000000..652bbd6688 --- /dev/null +++ b/docs/examples/csharp/nativesml/obj/project.assets.json @@ -0,0 +1,149 @@ +{ + "version": 3, + "targets": { + "net6.0": { + "Newtonsoft.Json/13.0.3": { + "type": "package", + "compile": { + "lib/net6.0/Newtonsoft.Json.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net6.0/Newtonsoft.Json.dll": { + "related": ".xml" + } + } + }, + "TDengine.Connector/3.1.3": { + "type": "package", + "dependencies": { + "Newtonsoft.Json": "13.0.3" + }, + "compile": { + "lib/net6.0/TDengine.dll": {} + }, + "runtime": { + "lib/net6.0/TDengine.dll": {} + } + } + } + }, + "libraries": { + "Newtonsoft.Json/13.0.3": { + "sha512": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==", + "type": "package", + "path": "newtonsoft.json/13.0.3", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "LICENSE.md", + "README.md", + "lib/net20/Newtonsoft.Json.dll", + "lib/net20/Newtonsoft.Json.xml", + "lib/net35/Newtonsoft.Json.dll", + "lib/net35/Newtonsoft.Json.xml", + "lib/net40/Newtonsoft.Json.dll", + "lib/net40/Newtonsoft.Json.xml", + "lib/net45/Newtonsoft.Json.dll", + "lib/net45/Newtonsoft.Json.xml", + "lib/net6.0/Newtonsoft.Json.dll", + "lib/net6.0/Newtonsoft.Json.xml", + "lib/netstandard1.0/Newtonsoft.Json.dll", + "lib/netstandard1.0/Newtonsoft.Json.xml", + "lib/netstandard1.3/Newtonsoft.Json.dll", + "lib/netstandard1.3/Newtonsoft.Json.xml", + "lib/netstandard2.0/Newtonsoft.Json.dll", + "lib/netstandard2.0/Newtonsoft.Json.xml", + "newtonsoft.json.13.0.3.nupkg.sha512", + "newtonsoft.json.nuspec", + "packageIcon.png" + ] + }, + "TDengine.Connector/3.1.3": { + "sha512": "dDX+Oex4I0X9yCalU0/YyUN0ecy+8X5xj6N8CoqeLrU6ICYDZgilSGQK9Fh3qmLobhGQvOJWwDpoO73rryHU5Q==", + "type": "package", + "path": "tdengine.connector/3.1.3", + "files": [ + ".nupkg.metadata", + "docs/README.md", + "image/logo.jpg", + "lib/net45/TDengine.dll", + "lib/net451/TDengine.dll", + "lib/net5.0/TDengine.dll", + "lib/net6.0/TDengine.dll", + "lib/netstandard2.0/TDengine.dll", + "lib/netstandard2.1/TDengine.dll", + "tdengine.connector.3.1.3.nupkg.sha512", + "tdengine.connector.nuspec" + ] + } + }, + "projectFileDependencyGroups": { + "net6.0": [ + "TDengine.Connector >= 3.1.*" + ] + }, + "packageFolders": { + "/root/.nuget/packages/": {} + }, + "project": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "/mnt/e/github/TDengine/docs/examples/csharp/nativesml/nativesml.csproj", + "projectName": "nativesml", + "projectPath": "/mnt/e/github/TDengine/docs/examples/csharp/nativesml/nativesml.csproj", + "packagesPath": "/root/.nuget/packages/", + "outputPath": "/mnt/e/github/TDengine/docs/examples/csharp/nativesml/obj/", + "projectStyle": "PackageReference", + "configFilePaths": [ + "/root/.nuget/NuGet/NuGet.Config" + ], + "originalTargetFrameworks": [ + "net6.0" + ], + "sources": { + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "net6.0": { + "targetAlias": "net6.0", + "projectReferences": {} + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + } + }, + "frameworks": { + "net6.0": { + "targetAlias": "net6.0", + "dependencies": { + "TDengine.Connector": { + "target": "Package", + "version": "[3.1.*, )" + } + }, + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48", + "net481" + ], + "assetTargetFallback": true, + "warn": true, + "frameworkReferences": { + "Microsoft.NETCore.App": { + "privateAssets": "all" + } + }, + "runtimeIdentifierGraphPath": "/root/.dotnet/sdk/8.0.100/RuntimeIdentifierGraph.json" + } + } + } +} \ No newline at end of file diff --git a/docs/examples/csharp/nativesml/obj/project.nuget.cache b/docs/examples/csharp/nativesml/obj/project.nuget.cache new file mode 100644 index 0000000000..3c34e78160 --- /dev/null +++ b/docs/examples/csharp/nativesml/obj/project.nuget.cache @@ -0,0 +1,11 @@ +{ + "version": 2, + "dgSpecHash": "xbVzGVQru/qLTE5UBOQoTSR5C+6GFj/M4fcB1h/3W6PsWOVoFQLbV4fwAAKt5f5BKxrV1phiwzm2zGYK0fpXBQ==", + "success": true, + "projectFilePath": "/mnt/e/github/TDengine/docs/examples/csharp/nativesml/nativesml.csproj", + "expectedPackageFiles": [ + "/root/.nuget/packages/newtonsoft.json/13.0.3/newtonsoft.json.13.0.3.nupkg.sha512", + "/root/.nuget/packages/tdengine.connector/3.1.3/tdengine.connector.3.1.3.nupkg.sha512" + ], + "logs": [] +} \ No newline at end of file diff --git a/docs/examples/csharp/nativesml/obj/project.packagespec.json b/docs/examples/csharp/nativesml/obj/project.packagespec.json new file mode 100644 index 0000000000..8c110899d3 --- /dev/null +++ b/docs/examples/csharp/nativesml/obj/project.packagespec.json @@ -0,0 +1 @@ +"restore":{"projectUniqueName":"E:\\github\\TDengine\\docs\\examples\\csharp\\nativesml\\nativesml.csproj","projectName":"nativesml","projectPath":"E:\\github\\TDengine\\docs\\examples\\csharp\\nativesml\\nativesml.csproj","outputPath":"E:\\github\\TDengine\\docs\\examples\\csharp\\nativesml\\obj\\","projectStyle":"PackageReference","originalTargetFrameworks":["net6.0"],"sources":{"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\":{},"E:\\github\\taos-connector-dotnet\\src\\resource":{},"https://api.nuget.org/v3/index.json":{}},"frameworks":{"net6.0":{"targetAlias":"net6.0","projectReferences":{}}},"warningProperties":{"warnAsError":["NU1605"]}}"frameworks":{"net6.0":{"targetAlias":"net6.0","dependencies":{"TDengine.Connector":{"target":"Package","version":"[3.1.*, )"}},"imports":["net461","net462","net47","net471","net472","net48","net481"],"assetTargetFallback":true,"warn":true,"frameworkReferences":{"Microsoft.NETCore.App":{"privateAssets":"all"}},"runtimeIdentifierGraphPath":"C:\\Program Files\\dotnet\\sdk\\8.0.202\\RuntimeIdentifierGraph.json"}} \ No newline at end of file diff --git a/docs/examples/csharp/nativesml/obj/rider.project.model.nuget.info b/docs/examples/csharp/nativesml/obj/rider.project.model.nuget.info new file mode 100644 index 0000000000..c922ea143f --- /dev/null +++ b/docs/examples/csharp/nativesml/obj/rider.project.model.nuget.info @@ -0,0 +1 @@ +17225691407520754 \ No newline at end of file diff --git a/docs/examples/csharp/nativesml/obj/rider.project.restore.info b/docs/examples/csharp/nativesml/obj/rider.project.restore.info new file mode 100644 index 0000000000..7559664705 --- /dev/null +++ b/docs/examples/csharp/nativesml/obj/rider.project.restore.info @@ -0,0 +1 @@ +17225689181017775 \ No newline at end of file diff --git a/docs/examples/csharp/optsJSON/Program.cs b/docs/examples/csharp/optsJSON/Program.cs index a93c4dad0f..747d89c0d3 100644 --- a/docs/examples/csharp/optsJSON/Program.cs +++ b/docs/examples/csharp/optsJSON/Program.cs @@ -7,22 +7,51 @@ namespace TDengineExample { public static void Main(string[] args) { - var builder = - new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) + // ANCHOR: main + var host = "127.0.0.1"; + + var lineDemo = + "meters,groupid=2,location=California.SanFrancisco current=10.3000002f64,voltage=219i32,phase=0.31f64 1626006833639"; + + var telnetDemo = "metric_telnet 1707095283260 4 host=host0 interface=eth0"; + + var jsonDemo = + "{\"metric\": \"metric_json\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}"; + try { - client.Exec("CREATE DATABASE test WAL_RETENTION_PERIOD 3600"); - client.Exec("use test"); - string[] lines = + var builder = + new ConnectionStringBuilder( + $"protocol=WebSocket;host={host};port=6041;username=root;password=taosdata"); + using (var client = DbDriver.Open(builder)) { - "[{\"metric\": \"meters.current\", \"timestamp\": 1648432611249, \"value\": 10.3, \"tags\": {\"location\": \"California.SanFrancisco\", \"groupid\": 2}}," + - " {\"metric\": \"meters.voltage\", \"timestamp\": 1648432611249, \"value\": 219, \"tags\": {\"location\": \"California.LosAngeles\", \"groupid\": 1}}, " + - "{\"metric\": \"meters.current\", \"timestamp\": 1648432611250, \"value\": 12.6, \"tags\": {\"location\": \"California.SanFrancisco\", \"groupid\": 2}}," + - " {\"metric\": \"meters.voltage\", \"timestamp\": 1648432611250, \"value\": 221, \"tags\": {\"location\": \"California.LosAngeles\", \"groupid\": 1}}]" - }; - client.SchemalessInsert(lines, TDengineSchemalessProtocol.TSDB_SML_JSON_PROTOCOL, - TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS, 0, ReqId.GetReqId()); + // create database + client.Exec("CREATE DATABASE IF NOT EXISTS power"); + // use database + client.Exec("USE power"); + // insert influx line protocol data + client.SchemalessInsert(new[]{lineDemo}, TDengineSchemalessProtocol.TSDB_SML_LINE_PROTOCOL, + TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS, 0, ReqId.GetReqId()); + // insert opentsdb telnet protocol data + client.SchemalessInsert(new[]{telnetDemo}, TDengineSchemalessProtocol.TSDB_SML_TELNET_PROTOCOL, + TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS, 0, ReqId.GetReqId()); + // insert json data + client.SchemalessInsert(new []{jsonDemo}, TDengineSchemalessProtocol.TSDB_SML_JSON_PROTOCOL, + TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_NOT_CONFIGURED, 0, ReqId.GetReqId()); + } } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + // ANCHOR_END: main } } } \ No newline at end of file diff --git a/docs/examples/csharp/query/Program.cs b/docs/examples/csharp/query/Program.cs index 4c354d9a5e..c901760f52 100644 --- a/docs/examples/csharp/query/Program.cs +++ b/docs/examples/csharp/query/Program.cs @@ -13,8 +13,7 @@ namespace TDengineExample { try { - client.Exec("use power"); - string query = "SELECT * FROM meters"; + string query = "SELECT * FROM power.meters"; using (var rows = client.Query(query)) { while (rows.Read()) diff --git a/docs/examples/csharp/sqlInsert/Program.cs b/docs/examples/csharp/sqlInsert/Program.cs index c3c700aba2..0ac8d55c5e 100644 --- a/docs/examples/csharp/sqlInsert/Program.cs +++ b/docs/examples/csharp/sqlInsert/Program.cs @@ -6,42 +6,125 @@ namespace TDengineExample { internal class SQLInsertExample { - public static void Main(string[] args) { - var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) + try { - try + + var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); + using (var client = DbDriver.Open(builder)) { - client.Exec("create database power"); - client.Exec("CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); - string insertQuery = - "INSERT INTO " + - "power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " + - "VALUES " + - "('2023-10-03 14:38:05.000', 10.30000, 219, 0.31000) " + - "('2023-10-03 14:38:15.000', 12.60000, 218, 0.33000) " + - "('2023-10-03 14:38:16.800', 12.30000, 221, 0.31000) " + - "power.d1002 USING power.meters TAGS(3, 'California.SanFrancisco') " + - "VALUES " + - "('2023-10-03 14:38:16.650', 10.30000, 218, 0.25000) " + - "power.d1003 USING power.meters TAGS(2,'California.LosAngeles') " + - "VALUES " + - "('2023-10-03 14:38:05.500', 11.80000, 221, 0.28000) " + - "('2023-10-03 14:38:16.600', 13.40000, 223, 0.29000) " + - "power.d1004 USING power.meters TAGS(3,'California.LosAngeles') " + - "VALUES " + - "('2023-10-03 14:38:05.000', 10.80000, 223, 0.29000) " + - "('2023-10-03 14:38:06.500', 11.50000, 221, 0.35000)"; - client.Exec(insertQuery); - } - catch (Exception e) - { - Console.WriteLine(e.ToString()); - throw; + CreateDatabaseAndTable(client); + InsertData(client); + QueryData(client); } } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + } + + private static void CreateDatabaseAndTable(ITDengineClient client) + { + // ANCHOR: create_db_and_table + try + { + // create database + var affected = client.Exec("CREATE DATABASE IF NOT EXISTS power"); + Console.WriteLine($"Create database power, affected rows: {affected}"); + // create table + affected = client.Exec( + "CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); + Console.WriteLine($"Create table meters, affected rows: {affected}"); + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + // ANCHOR_END: create_db_and_table + } + + private static void InsertData(ITDengineClient client) + { + // ANCHOR: insert_data + try + { + // insert data + var insertQuery = "INSERT INTO " + + "power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " + + "VALUES " + + "(NOW + 1a, 10.30000, 219, 0.31000) " + + "(NOW + 2a, 12.60000, 218, 0.33000) " + + "(NOW + 3a, 12.30000, 221, 0.31000) " + + "power.d1002 USING power.meters TAGS(3, 'California.SanFrancisco') " + + "VALUES " + + "(NOW + 1a, 10.30000, 218, 0.25000) "; + var affectedRows = client.Exec(insertQuery); + Console.WriteLine("inserted into " + affectedRows + " rows to power.meters successfully."); + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + // ANCHOR_END: insert_data + } + + private static void QueryData(ITDengineClient client) + { + // ANCHOR: query_data + try + { + // query data + var query = "SELECT ts, current, location FROM power.meters limit 100"; + using (var rows = client.Query(query)) + { + while (rows.Read()) + { + var ts = (DateTime)rows.GetValue(0); + var current = (float)rows.GetValue(1); + var location = Encoding.UTF8.GetString((byte[])rows.GetValue(2)); + Console.WriteLine($"ts: {ts:yyyy-MM-dd HH:mm:ss.fff}, current: {current}, location: {location}"); + } + } + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + // ANCHOR_END: query_data } } -} +} \ No newline at end of file diff --git a/docs/examples/csharp/stmtInsert/Program.cs b/docs/examples/csharp/stmtInsert/Program.cs index e6b11a63e4..5b4cf2677c 100644 --- a/docs/examples/csharp/stmtInsert/Program.cs +++ b/docs/examples/csharp/stmtInsert/Program.cs @@ -5,34 +5,72 @@ namespace TDengineExample { internal class StmtInsertExample { + // ANCHOR: main public static void Main(string[] args) { - var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) + var host = "127.0.0.1"; + var numOfSubTable = 10; + var numOfRow = 10; + var random = new Random(); + try { - try + var builder = new ConnectionStringBuilder($"host={host};port=6030;username=root;password=taosdata"); + using (var client = DbDriver.Open(builder)) { - client.Exec($"create database power"); + // create database + client.Exec("CREATE DATABASE IF NOT EXISTS power"); + // use database + client.Exec("USE power"); + // create table client.Exec( - "CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); + "CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); using (var stmt = client.StmtInit()) { - stmt.Prepare( - "Insert into power.d1001 using power.meters tags(2,'California.SanFrancisco') values(?,?,?,?)"); - var ts = new DateTime(2023, 10, 03, 14, 38, 05, 000); - stmt.BindRow(new object[] { ts, (float)10.30000, (int)219, (float)0.31000 }); - stmt.AddBatch(); - stmt.Exec(); - var affected = stmt.Affected(); - Console.WriteLine($"affected rows: {affected}"); + String sql = "INSERT INTO ? USING meters TAGS(?,?) VALUES (?,?,?,?)"; + stmt.Prepare(sql); + for (int i = 1; i <= numOfSubTable; i++) + { + var tableName = $"d_bind_{i}"; + // set table name + stmt.SetTableName(tableName); + // set tags + stmt.SetTags(new object[] { i, $"location_{i}" }); + var current = DateTime.Now; + // bind rows + for (int j = 0; j < numOfRow; j++) + { + stmt.BindRow(new object[] + { + current.Add(TimeSpan.FromMilliseconds(j)), + random.NextSingle() * 30, + random.Next(300), + random.NextSingle() + }); + } + // add batch + stmt.AddBatch(); + // execute + stmt.Exec(); + // get affected rows + var affectedRows = stmt.Affected(); + Console.WriteLine($"table {tableName} insert {affectedRows} rows."); + } } } - catch (Exception e) - { - Console.WriteLine(e); - throw; - } + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; } } + // ANCHOR_END: main } } \ No newline at end of file diff --git a/docs/examples/csharp/subscribe/Program.cs b/docs/examples/csharp/subscribe/Program.cs index d7c1a52117..80e25f1acf 100644 --- a/docs/examples/csharp/subscribe/Program.cs +++ b/docs/examples/csharp/subscribe/Program.cs @@ -1,5 +1,4 @@ - -using TDengine.Driver; +using TDengine.Driver; using TDengine.Driver.Client; using TDengine.TMQ; @@ -9,65 +8,221 @@ namespace TMQExample { public static void Main(string[] args) { - var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) + try { - try + var builder = new ConnectionStringBuilder("host=127.0.0.1;port=6030;username=root;password=taosdata"); + using (var client = DbDriver.Open(builder)) { - client.Exec("CREATE DATABASE power"); + client.Exec("CREATE DATABASE IF NOT EXISTS power"); client.Exec("USE power"); client.Exec( - "CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); - client.Exec("CREATE TOPIC topic_meters as SELECT * from power.meters"); - var cfg = new Dictionary() - { - { "group.id", "group1" }, - { "auto.offset.reset", "latest" }, - { "td.connect.ip", "127.0.0.1" }, - { "td.connect.user", "root" }, - { "td.connect.pass", "taosdata" }, - { "td.connect.port", "6030" }, - { "client.id", "tmq_example" }, - { "enable.auto.commit", "true" }, - { "msg.with.table.name", "false" }, - }; - var consumer = new ConsumerBuilder>(cfg).Build(); - consumer.Subscribe(new List() { "topic_meters" }); + "CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); + client.Exec("CREATE TOPIC IF NOT EXISTS topic_meters as SELECT * from power.meters"); + var consumer = CreateConsumer(); + // insert data Task.Run(InsertData); - while (true) - { - using (var cr = consumer.Consume(500)) - { - if (cr == null) continue; - foreach (var message in cr.Message) - { - Console.WriteLine( - $"message {{{((DateTime)message.Value["ts"]).ToString("yyyy-MM-dd HH:mm:ss.fff")}, " + - $"{message.Value["current"]}, {message.Value["voltage"]}, {message.Value["phase"]}}}"); - } - } - } - } - catch (Exception e) - { - Console.WriteLine(e.ToString()); - throw; + // consume message + Consume(consumer); + // seek + Seek(consumer); + // commit + CommitOffset(consumer); + // close + Close(consumer); + Console.WriteLine("Done"); } } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } } static void InsertData() { - var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); + var builder = new ConnectionStringBuilder("host=127.0.0.1;port=6030;username=root;password=taosdata"); using (var client = DbDriver.Open(builder)) { while (true) { - client.Exec("INSERT into power.d1001 using power.meters tags(2,'California.SanFrancisco') values(now,11.5,219,0.30)"); + client.Exec( + "INSERT into power.d1001 using power.meters tags(2,'California.SanFrancisco') values(now,11.5,219,0.30)"); Task.Delay(1000).Wait(); } } } - } -} + static IConsumer> CreateConsumer() + { + // ANCHOR: create_consumer + // consumer config + var cfg = new Dictionary() + { + { "td.connect.port", "6030" }, + { "auto.offset.reset", "latest" }, + { "msg.with.table.name", "true" }, + { "enable.auto.commit", "true" }, + { "auto.commit.interval.ms", "1000" }, + { "group.id", "group2" }, + { "client.id", "1" }, + { "td.connect.ip", "127.0.0.1" }, + { "td.connect.user", "root" }, + { "td.connect.pass", "taosdata" }, + }; + IConsumer> consumer = null!; + try + { + // create consumer + consumer = new ConsumerBuilder>(cfg).Build(); + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + + // ANCHOR_END: create_consumer + return consumer; + } + + static void Consume(IConsumer> consumer) + { + // ANCHOR: subscribe + try + { + // subscribe + consumer.Subscribe(new List() { "topic_meters" }); + for (int i = 0; i < 50; i++) + { + // consume message with using block to ensure the result is disposed + using (var cr = consumer.Consume(100)) + { + if (cr == null) continue; + foreach (var message in cr.Message) + { + // handle message + Console.WriteLine( + $"message {{{((DateTime)message.Value["ts"]).ToString("yyyy-MM-dd HH:mm:ss.fff")}, " + + $"{message.Value["current"]}, {message.Value["voltage"]}, {message.Value["phase"]}}}"); + } + } + } + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + // ANCHOR_END: subscribe + } + + static void Seek(IConsumer> consumer) + { + // ANCHOR: seek + try + { + // get assignment + var assignment = consumer.Assignment; + // seek to the beginning + foreach (var topicPartition in assignment) + { + consumer.Seek(new TopicPartitionOffset(topicPartition.Topic, topicPartition.Partition, 0)); + } + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + // ANCHOR_END: seek + } + + static void CommitOffset(IConsumer> consumer) + { + // ANCHOR: commit_offset + for (int i = 0; i < 5; i++) + { + try + { + // consume message with using block to ensure the result is disposed + using (var cr = consumer.Consume(100)) + { + if (cr == null) continue; + // commit offset + consumer.Commit(new List + { + cr.TopicPartitionOffset, + }); + } + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + } + // ANCHOR_END: commit_offset + } + + static void Close(IConsumer> consumer) + { + // ANCHOR: close + try + { + // unsubscribe + consumer.Unsubscribe(); + // close consumer + consumer.Close(); + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + // ANCHOR_END: close + } + } +} \ No newline at end of file diff --git a/docs/examples/csharp/wsConnect/Program.cs b/docs/examples/csharp/wsConnect/Program.cs index edf0eb31e6..c7423969d8 100644 --- a/docs/examples/csharp/wsConnect/Program.cs +++ b/docs/examples/csharp/wsConnect/Program.cs @@ -6,13 +6,33 @@ namespace Examples { public class WSConnExample { + // ANCHOR: main static void Main(string[] args) { - var builder = new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) + try { - Console.WriteLine("connected"); + // Connect to TDengine server using WebSocket + var builder = new ConnectionStringBuilder( + "protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata"); + // Open connection with using block, it will close the connection automatically + using (var client = DbDriver.Open(builder)) + { + Console.WriteLine("connected"); + } + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; } } + // ANCHOR_END: main } -} +} \ No newline at end of file diff --git a/docs/examples/csharp/wsInsert/Program.cs b/docs/examples/csharp/wsInsert/Program.cs index 73136477e7..d393b775ba 100644 --- a/docs/examples/csharp/wsInsert/Program.cs +++ b/docs/examples/csharp/wsInsert/Program.cs @@ -1,4 +1,5 @@ using System; +using System.Text; using TDengine.Driver; using TDengine.Driver.Client; @@ -8,39 +9,159 @@ namespace Examples { public static void Main(string[] args) { - var builder = new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) + try { - try + var builder = new ConnectionStringBuilder("protocol=WebSocket;host=127.0.0.1;port=6041;useSSL=false;username=root;password=taosdata"); + using (var client = DbDriver.Open(builder)) { - client.Exec("create database power"); - client.Exec("CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); - string insertQuery = - "INSERT INTO " + - "power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " + - "VALUES " + - "('2023-10-03 14:38:05.000', 10.30000, 219, 0.31000) " + - "('2023-10-03 14:38:15.000', 12.60000, 218, 0.33000) " + - "('2023-10-03 14:38:16.800', 12.30000, 221, 0.31000) " + - "power.d1002 USING power.meters TAGS(3, 'California.SanFrancisco') " + - "VALUES " + - "('2023-10-03 14:38:16.650', 10.30000, 218, 0.25000) " + - "power.d1003 USING power.meters TAGS(2,'California.LosAngeles') " + - "VALUES " + - "('2023-10-03 14:38:05.500', 11.80000, 221, 0.28000) " + - "('2023-10-03 14:38:16.600', 13.40000, 223, 0.29000) " + - "power.d1004 USING power.meters TAGS(3,'California.LosAngeles') " + - "VALUES " + - "('2023-10-03 14:38:05.000', 10.80000, 223, 0.29000) " + - "('2023-10-03 14:38:06.500', 11.50000, 221, 0.35000)"; - client.Exec(insertQuery); - } - catch (Exception e) - { - Console.WriteLine(e.ToString()); - throw; + CreateDatabaseAndTable(client); + InsertData(client); + QueryData(client); + QueryWithReqId(client); } } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + } + + private static void CreateDatabaseAndTable(ITDengineClient client) + { + // ANCHOR: create_db_and_table + try + { + // create database + var affected = client.Exec("CREATE DATABASE IF NOT EXISTS power"); + Console.WriteLine($"Create database power, affected rows: {affected}"); + // create table + affected = client.Exec( + "CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); + Console.WriteLine($"Create table meters, affected rows: {affected}"); + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + // ANCHOR_END: create_db_and_table + } + + private static void InsertData(ITDengineClient client) + { + // ANCHOR: insert_data + try + { + // insert data + var insertQuery = "INSERT INTO " + + "power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " + + "VALUES " + + "(NOW + 1a, 10.30000, 219, 0.31000) " + + "(NOW + 2a, 12.60000, 218, 0.33000) " + + "(NOW + 3a, 12.30000, 221, 0.31000) " + + "power.d1002 USING power.meters TAGS(3, 'California.SanFrancisco') " + + "VALUES " + + "(NOW + 1a, 10.30000, 218, 0.25000) "; + var affectedRows = client.Exec(insertQuery); + Console.WriteLine("inserted " + affectedRows + " rows to power.meters successfully."); + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + // ANCHOR_END: insert_data + } + + private static void QueryData(ITDengineClient client) + { + // ANCHOR: select_data + try + { + // query data + var query = "SELECT ts, current, location FROM power.meters limit 100"; + using (var rows = client.Query(query)) + { + while (rows.Read()) + { + var ts = (DateTime)rows.GetValue(0); + var current = (float)rows.GetValue(1); + var location = Encoding.UTF8.GetString((byte[])rows.GetValue(2)); + Console.WriteLine( + $"ts: {ts:yyyy-MM-dd HH:mm:ss.fff}, current: {current}, location: {location}"); + } + } + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + // ANCHOR_END: select_data + } + + private static void QueryWithReqId(ITDengineClient client) + { + // ANCHOR: query_id + try + { + // query data + var query = "SELECT ts, current, location FROM power.meters limit 1"; + // query with request id 1 + using (var rows = client.Query(query,1)) + { + while (rows.Read()) + { + var ts = (DateTime)rows.GetValue(0); + var current = (float)rows.GetValue(1); + var location = Encoding.UTF8.GetString((byte[])rows.GetValue(2)); + Console.WriteLine( + $"ts: {ts:yyyy-MM-dd HH:mm:ss.fff}, current: {current}, location: {location}"); + } + } + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + // ANCHOR_END: query_id } } -} +} \ No newline at end of file diff --git a/docs/examples/csharp/wsQuery/Program.cs b/docs/examples/csharp/wsQuery/Program.cs index 40aac24597..c58f23626c 100644 --- a/docs/examples/csharp/wsQuery/Program.cs +++ b/docs/examples/csharp/wsQuery/Program.cs @@ -14,8 +14,7 @@ namespace Examples { try { - client.Exec("use power"); - string query = "SELECT * FROM meters"; + string query = "SELECT * FROM power.meters"; using (var rows = client.Query(query)) { while (rows.Read()) diff --git a/docs/examples/csharp/wsStmt/Program.cs b/docs/examples/csharp/wsStmt/Program.cs index 5166dfea92..dfc98d17d6 100644 --- a/docs/examples/csharp/wsStmt/Program.cs +++ b/docs/examples/csharp/wsStmt/Program.cs @@ -6,36 +6,72 @@ namespace Examples { public class WSStmtExample { + // ANCHOR: main public static void Main(string[] args) { - var builder = - new ConnectionStringBuilder( - "protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) + var host = "127.0.0.1"; + var numOfSubTable = 10; + var numOfRow = 10; + var random = new Random(); + try { - try + var builder = new ConnectionStringBuilder($"protocol=WebSocket;host={host};port=6041;useSSL=false;username=root;password=taosdata"); + using (var client = DbDriver.Open(builder)) { - client.Exec($"create database power"); + // create database + client.Exec("CREATE DATABASE IF NOT EXISTS power"); + // use database + client.Exec("USE power"); + // create table client.Exec( - "CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); + "CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); using (var stmt = client.StmtInit()) { - stmt.Prepare( - "Insert into power.d1001 using power.meters tags(2,'California.SanFrancisco') values(?,?,?,?)"); - var ts = new DateTime(2023, 10, 03, 14, 38, 05, 000); - stmt.BindRow(new object[] { ts, (float)10.30000, (int)219, (float)0.31000 }); - stmt.AddBatch(); - stmt.Exec(); - var affected = stmt.Affected(); - Console.WriteLine($"affected rows: {affected}"); + String sql = "INSERT INTO ? USING meters TAGS(?,?) VALUES (?,?,?,?)"; + stmt.Prepare(sql); + for (int i = 1; i <= numOfSubTable; i++) + { + var tableName = $"d_bind_{i}"; + // set table name + stmt.SetTableName(tableName); + // set tags + stmt.SetTags(new object[] { i, $"location_{i}" }); + var current = DateTime.Now; + // bind rows + for (int j = 0; j < numOfRow; j++) + { + stmt.BindRow(new object[] + { + current.Add(TimeSpan.FromMilliseconds(j)), + random.NextSingle() * 30, + random.Next(300), + random.NextSingle() + }); + } + // add batch + stmt.AddBatch(); + // execute + stmt.Exec(); + // get affected rows + var affectedRows = stmt.Affected(); + Console.WriteLine($"table {tableName} insert {affectedRows} rows."); + } } } - catch (Exception e) - { - Console.WriteLine(e); - throw; - } + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; } } + // ANCHOR_END: main } } \ No newline at end of file diff --git a/docs/examples/csharp/wssml/Program.cs b/docs/examples/csharp/wssml/Program.cs new file mode 100644 index 0000000000..5c47c6651b --- /dev/null +++ b/docs/examples/csharp/wssml/Program.cs @@ -0,0 +1,57 @@ +using TDengine.Driver; +using TDengine.Driver.Client; + +namespace TDengineExample +{ + internal class WssmlExample + { + // ANCHOR: main + public static void Main(string[] args) + { + var host = "127.0.0.1"; + + var lineDemo = + "meters,groupid=2,location=California.SanFrancisco current=10.3000002f64,voltage=219i32,phase=0.31f64 1626006833639"; + + var telnetDemo = "metric_telnet 1707095283260 4 host=host0 interface=eth0"; + + var jsonDemo = + "{\"metric\": \"metric_json\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}"; + try + { + var builder = + new ConnectionStringBuilder( + $"protocol=WebSocket;host={host};port=6041;username=root;password=taosdata"); + using (var client = DbDriver.Open(builder)) + { + // create database + client.Exec("CREATE DATABASE IF NOT EXISTS power"); + // use database + client.Exec("USE power"); + // insert influx line protocol data + client.SchemalessInsert(new[]{lineDemo}, TDengineSchemalessProtocol.TSDB_SML_LINE_PROTOCOL, + TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS, 0, ReqId.GetReqId()); + // insert opentsdb telnet protocol data + client.SchemalessInsert(new[]{telnetDemo}, TDengineSchemalessProtocol.TSDB_SML_TELNET_PROTOCOL, + TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS, 0, ReqId.GetReqId()); + // insert json data + client.SchemalessInsert(new []{jsonDemo}, TDengineSchemalessProtocol.TSDB_SML_JSON_PROTOCOL, + TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_NOT_CONFIGURED, 0, ReqId.GetReqId()); + } + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + } + // ANCHOR_END: main + } +} \ No newline at end of file diff --git a/docs/examples/csharp/wssml/obj/project.assets.json b/docs/examples/csharp/wssml/obj/project.assets.json new file mode 100644 index 0000000000..a3062a28a9 --- /dev/null +++ b/docs/examples/csharp/wssml/obj/project.assets.json @@ -0,0 +1,149 @@ +{ + "version": 3, + "targets": { + "net6.0": { + "Newtonsoft.Json/13.0.3": { + "type": "package", + "compile": { + "lib/net6.0/Newtonsoft.Json.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net6.0/Newtonsoft.Json.dll": { + "related": ".xml" + } + } + }, + "TDengine.Connector/3.1.3": { + "type": "package", + "dependencies": { + "Newtonsoft.Json": "13.0.3" + }, + "compile": { + "lib/net6.0/TDengine.dll": {} + }, + "runtime": { + "lib/net6.0/TDengine.dll": {} + } + } + } + }, + "libraries": { + "Newtonsoft.Json/13.0.3": { + "sha512": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==", + "type": "package", + "path": "newtonsoft.json/13.0.3", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "LICENSE.md", + "README.md", + "lib/net20/Newtonsoft.Json.dll", + "lib/net20/Newtonsoft.Json.xml", + "lib/net35/Newtonsoft.Json.dll", + "lib/net35/Newtonsoft.Json.xml", + "lib/net40/Newtonsoft.Json.dll", + "lib/net40/Newtonsoft.Json.xml", + "lib/net45/Newtonsoft.Json.dll", + "lib/net45/Newtonsoft.Json.xml", + "lib/net6.0/Newtonsoft.Json.dll", + "lib/net6.0/Newtonsoft.Json.xml", + "lib/netstandard1.0/Newtonsoft.Json.dll", + "lib/netstandard1.0/Newtonsoft.Json.xml", + "lib/netstandard1.3/Newtonsoft.Json.dll", + "lib/netstandard1.3/Newtonsoft.Json.xml", + "lib/netstandard2.0/Newtonsoft.Json.dll", + "lib/netstandard2.0/Newtonsoft.Json.xml", + "newtonsoft.json.13.0.3.nupkg.sha512", + "newtonsoft.json.nuspec", + "packageIcon.png" + ] + }, + "TDengine.Connector/3.1.3": { + "sha512": "dDX+Oex4I0X9yCalU0/YyUN0ecy+8X5xj6N8CoqeLrU6ICYDZgilSGQK9Fh3qmLobhGQvOJWwDpoO73rryHU5Q==", + "type": "package", + "path": "tdengine.connector/3.1.3", + "files": [ + ".nupkg.metadata", + "docs/README.md", + "image/logo.jpg", + "lib/net45/TDengine.dll", + "lib/net451/TDengine.dll", + "lib/net5.0/TDengine.dll", + "lib/net6.0/TDengine.dll", + "lib/netstandard2.0/TDengine.dll", + "lib/netstandard2.1/TDengine.dll", + "tdengine.connector.3.1.3.nupkg.sha512", + "tdengine.connector.nuspec" + ] + } + }, + "projectFileDependencyGroups": { + "net6.0": [ + "TDengine.Connector >= 3.1.*" + ] + }, + "packageFolders": { + "/root/.nuget/packages/": {} + }, + "project": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "/mnt/e/github/TDengine/docs/examples/csharp/wssml/wssml.csproj", + "projectName": "wssml", + "projectPath": "/mnt/e/github/TDengine/docs/examples/csharp/wssml/wssml.csproj", + "packagesPath": "/root/.nuget/packages/", + "outputPath": "/mnt/e/github/TDengine/docs/examples/csharp/wssml/obj/", + "projectStyle": "PackageReference", + "configFilePaths": [ + "/root/.nuget/NuGet/NuGet.Config" + ], + "originalTargetFrameworks": [ + "net6.0" + ], + "sources": { + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "net6.0": { + "targetAlias": "net6.0", + "projectReferences": {} + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + } + }, + "frameworks": { + "net6.0": { + "targetAlias": "net6.0", + "dependencies": { + "TDengine.Connector": { + "target": "Package", + "version": "[3.1.*, )" + } + }, + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48", + "net481" + ], + "assetTargetFallback": true, + "warn": true, + "frameworkReferences": { + "Microsoft.NETCore.App": { + "privateAssets": "all" + } + }, + "runtimeIdentifierGraphPath": "/root/.dotnet/sdk/8.0.100/RuntimeIdentifierGraph.json" + } + } + } +} \ No newline at end of file diff --git a/docs/examples/csharp/wssml/obj/project.nuget.cache b/docs/examples/csharp/wssml/obj/project.nuget.cache new file mode 100644 index 0000000000..140c7e62da --- /dev/null +++ b/docs/examples/csharp/wssml/obj/project.nuget.cache @@ -0,0 +1,11 @@ +{ + "version": 2, + "dgSpecHash": "f/iAhsDLFU7jI95wf6NFa1XHue7HQsgzzqr1jqfMTnrejkprbps/2toSr4j9kUyRUVdJNr7/TtdHhEsxEhKo+A==", + "success": true, + "projectFilePath": "/mnt/e/github/TDengine/docs/examples/csharp/wssml/wssml.csproj", + "expectedPackageFiles": [ + "/root/.nuget/packages/newtonsoft.json/13.0.3/newtonsoft.json.13.0.3.nupkg.sha512", + "/root/.nuget/packages/tdengine.connector/3.1.3/tdengine.connector.3.1.3.nupkg.sha512" + ], + "logs": [] +} \ No newline at end of file diff --git a/docs/examples/csharp/wssml/obj/project.packagespec.json b/docs/examples/csharp/wssml/obj/project.packagespec.json new file mode 100644 index 0000000000..587dbcda23 --- /dev/null +++ b/docs/examples/csharp/wssml/obj/project.packagespec.json @@ -0,0 +1 @@ +"restore":{"projectUniqueName":"E:\\github\\TDengine\\docs\\examples\\csharp\\wssml\\wssml.csproj","projectName":"wssml","projectPath":"E:\\github\\TDengine\\docs\\examples\\csharp\\wssml\\wssml.csproj","outputPath":"E:\\github\\TDengine\\docs\\examples\\csharp\\wssml\\obj\\","projectStyle":"PackageReference","originalTargetFrameworks":["net6.0"],"sources":{"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\":{},"E:\\github\\taos-connector-dotnet\\src\\resource":{},"https://api.nuget.org/v3/index.json":{}},"frameworks":{"net6.0":{"targetAlias":"net6.0","projectReferences":{}}},"warningProperties":{"warnAsError":["NU1605"]}}"frameworks":{"net6.0":{"targetAlias":"net6.0","dependencies":{"TDengine.Connector":{"target":"Package","version":"[3.1.*, )"}},"imports":["net461","net462","net47","net471","net472","net48","net481"],"assetTargetFallback":true,"warn":true,"frameworkReferences":{"Microsoft.NETCore.App":{"privateAssets":"all"}},"runtimeIdentifierGraphPath":"C:\\Program Files\\dotnet\\sdk\\8.0.202\\RuntimeIdentifierGraph.json"}} \ No newline at end of file diff --git a/docs/examples/csharp/wssml/obj/rider.project.model.nuget.info b/docs/examples/csharp/wssml/obj/rider.project.model.nuget.info new file mode 100644 index 0000000000..8c12f7e019 --- /dev/null +++ b/docs/examples/csharp/wssml/obj/rider.project.model.nuget.info @@ -0,0 +1 @@ +17225691310239873 \ No newline at end of file diff --git a/docs/examples/csharp/wssml/obj/rider.project.restore.info b/docs/examples/csharp/wssml/obj/rider.project.restore.info new file mode 100644 index 0000000000..b11c9dec26 --- /dev/null +++ b/docs/examples/csharp/wssml/obj/rider.project.restore.info @@ -0,0 +1 @@ +17225689180359712 \ No newline at end of file diff --git a/docs/examples/csharp/wssml/obj/wssml.csproj.nuget.dgspec.json b/docs/examples/csharp/wssml/obj/wssml.csproj.nuget.dgspec.json new file mode 100644 index 0000000000..314b2831c6 --- /dev/null +++ b/docs/examples/csharp/wssml/obj/wssml.csproj.nuget.dgspec.json @@ -0,0 +1,67 @@ +{ + "format": 1, + "restore": { + "/mnt/e/github/TDengine/docs/examples/csharp/wssml/wssml.csproj": {} + }, + "projects": { + "/mnt/e/github/TDengine/docs/examples/csharp/wssml/wssml.csproj": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "/mnt/e/github/TDengine/docs/examples/csharp/wssml/wssml.csproj", + "projectName": "wssml", + "projectPath": "/mnt/e/github/TDengine/docs/examples/csharp/wssml/wssml.csproj", + "packagesPath": "/root/.nuget/packages/", + "outputPath": "/mnt/e/github/TDengine/docs/examples/csharp/wssml/obj/", + "projectStyle": "PackageReference", + "configFilePaths": [ + "/root/.nuget/NuGet/NuGet.Config" + ], + "originalTargetFrameworks": [ + "net6.0" + ], + "sources": { + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "net6.0": { + "targetAlias": "net6.0", + "projectReferences": {} + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + } + }, + "frameworks": { + "net6.0": { + "targetAlias": "net6.0", + "dependencies": { + "TDengine.Connector": { + "target": "Package", + "version": "[3.1.*, )" + } + }, + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48", + "net481" + ], + "assetTargetFallback": true, + "warn": true, + "frameworkReferences": { + "Microsoft.NETCore.App": { + "privateAssets": "all" + } + }, + "runtimeIdentifierGraphPath": "/root/.dotnet/sdk/8.0.100/RuntimeIdentifierGraph.json" + } + } + } + } +} \ No newline at end of file diff --git a/docs/examples/csharp/wssml/obj/wssml.csproj.nuget.g.props b/docs/examples/csharp/wssml/obj/wssml.csproj.nuget.g.props new file mode 100644 index 0000000000..a270b60d2c --- /dev/null +++ b/docs/examples/csharp/wssml/obj/wssml.csproj.nuget.g.props @@ -0,0 +1,15 @@ + + + + True + NuGet + $(MSBuildThisFileDirectory)project.assets.json + /root/.nuget/packages/ + /root/.nuget/packages/ + PackageReference + 6.8.0 + + + + + \ No newline at end of file diff --git a/docs/examples/csharp/wssml/obj/wssml.csproj.nuget.g.targets b/docs/examples/csharp/wssml/obj/wssml.csproj.nuget.g.targets new file mode 100644 index 0000000000..35a7576c5a --- /dev/null +++ b/docs/examples/csharp/wssml/obj/wssml.csproj.nuget.g.targets @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/docs/examples/csharp/wssml/wssml.csproj b/docs/examples/csharp/wssml/wssml.csproj new file mode 100644 index 0000000000..0b8df205bb --- /dev/null +++ b/docs/examples/csharp/wssml/wssml.csproj @@ -0,0 +1,12 @@ + + + + Exe + net6.0 + enable + enable + + + + + diff --git a/docs/examples/csharp/wssubscribe/Program.cs b/docs/examples/csharp/wssubscribe/Program.cs new file mode 100644 index 0000000000..269fc4c732 --- /dev/null +++ b/docs/examples/csharp/wssubscribe/Program.cs @@ -0,0 +1,229 @@ +using TDengine.Driver; +using TDengine.Driver.Client; +using TDengine.TMQ; + +namespace TMQExample +{ + internal class SubscribeDemo + { + public static void Main(string[] args) + { + try + { + var builder = new ConnectionStringBuilder("protocol=WebSocket;host=127.0.0.1;port=6041;username=root;password=taosdata"); + using (var client = DbDriver.Open(builder)) + { + client.Exec("CREATE DATABASE IF NOT EXISTS power"); + client.Exec("USE power"); + client.Exec( + "CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); + client.Exec("CREATE TOPIC IF NOT EXISTS topic_meters as SELECT * from power.meters"); + var consumer = CreateConsumer(); + // insert data + Task.Run(InsertData); + // consume message + Consume(consumer); + // seek + Seek(consumer); + // commit + CommitOffset(consumer); + // close + Close(consumer); + Console.WriteLine("Done"); + } + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + } + + static void InsertData() + { + var builder = new ConnectionStringBuilder("protocol=WebSocket;host=127.0.0.1;port=6041;username=root;password=taosdata"); + using (var client = DbDriver.Open(builder)) + { + while (true) + { + client.Exec( + "INSERT into power.d1001 using power.meters tags(2,'California.SanFrancisco') values(now,11.5,219,0.30)"); + Task.Delay(1000).Wait(); + } + } + } + + static IConsumer> CreateConsumer() + { + // ANCHOR: create_consumer + // consumer config + var cfg = new Dictionary() + { + {"td.connect.type", "WebSocket"}, + { "td.connect.port", "6041" }, + { "auto.offset.reset", "latest" }, + { "msg.with.table.name", "true" }, + { "enable.auto.commit", "true" }, + { "auto.commit.interval.ms", "1000" }, + { "group.id", "group2" }, + { "client.id", "1" }, + { "td.connect.ip", "127.0.0.1" }, + { "td.connect.user", "root" }, + { "td.connect.pass", "taosdata" }, + }; + IConsumer> consumer = null!; + try + { + // create consumer + consumer = new ConsumerBuilder>(cfg).Build(); + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + + // ANCHOR_END: create_consumer + return consumer; + } + + static void Consume(IConsumer> consumer) + { + // ANCHOR: subscribe + try + { + // subscribe + consumer.Subscribe(new List() { "topic_meters" }); + for (int i = 0; i < 50; i++) + { + // consume message with using block to ensure the result is disposed + using (var cr = consumer.Consume(100)) + { + if (cr == null) continue; + foreach (var message in cr.Message) + { + // handle message + Console.WriteLine( + $"message {{{((DateTime)message.Value["ts"]).ToString("yyyy-MM-dd HH:mm:ss.fff")}, " + + $"{message.Value["current"]}, {message.Value["voltage"]}, {message.Value["phase"]}}}"); + } + } + } + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + // ANCHOR_END: subscribe + } + + static void Seek(IConsumer> consumer) + { + // ANCHOR: seek + try + { + // get assignment + var assignment = consumer.Assignment; + // seek to the beginning + foreach (var topicPartition in assignment) + { + consumer.Seek(new TopicPartitionOffset(topicPartition.Topic, topicPartition.Partition, 0)); + } + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + // ANCHOR_END: seek + } + + static void CommitOffset(IConsumer> consumer) + { + // ANCHOR: commit_offset + for (int i = 0; i < 5; i++) + { + try + { + // consume message with using block to ensure the result is disposed + using (var cr = consumer.Consume(100)) + { + if (cr == null) continue; + // commit offset + consumer.Commit(new List + { + cr.TopicPartitionOffset, + }); + } + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + } + // ANCHOR_END: commit_offset + } + + static void Close(IConsumer> consumer) + { + // ANCHOR: close + try + { + // unsubscribe + consumer.Unsubscribe(); + // close consumer + consumer.Close(); + } + catch (TDengineError e) + { + // handle TDengine error + Console.WriteLine(e.Message); + throw; + } + catch (Exception e) + { + // handle other exceptions + Console.WriteLine(e.Message); + throw; + } + // ANCHOR_END: close + } + } +} \ No newline at end of file diff --git a/docs/examples/csharp/wssubscribe/obj/project.assets.json b/docs/examples/csharp/wssubscribe/obj/project.assets.json new file mode 100644 index 0000000000..8335d20e65 --- /dev/null +++ b/docs/examples/csharp/wssubscribe/obj/project.assets.json @@ -0,0 +1,150 @@ +{ + "version": 3, + "targets": { + "net6.0": { + "Newtonsoft.Json/13.0.3": { + "type": "package", + "compile": { + "lib/net6.0/Newtonsoft.Json.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/net6.0/Newtonsoft.Json.dll": { + "related": ".xml" + } + } + }, + "TDengine.Connector/3.1.3": { + "type": "package", + "dependencies": { + "Newtonsoft.Json": "13.0.3" + }, + "compile": { + "lib/net6.0/TDengine.dll": {} + }, + "runtime": { + "lib/net6.0/TDengine.dll": {} + } + } + } + }, + "libraries": { + "Newtonsoft.Json/13.0.3": { + "sha512": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==", + "type": "package", + "path": "newtonsoft.json/13.0.3", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "LICENSE.md", + "README.md", + "lib/net20/Newtonsoft.Json.dll", + "lib/net20/Newtonsoft.Json.xml", + "lib/net35/Newtonsoft.Json.dll", + "lib/net35/Newtonsoft.Json.xml", + "lib/net40/Newtonsoft.Json.dll", + "lib/net40/Newtonsoft.Json.xml", + "lib/net45/Newtonsoft.Json.dll", + "lib/net45/Newtonsoft.Json.xml", + "lib/net6.0/Newtonsoft.Json.dll", + "lib/net6.0/Newtonsoft.Json.xml", + "lib/netstandard1.0/Newtonsoft.Json.dll", + "lib/netstandard1.0/Newtonsoft.Json.xml", + "lib/netstandard1.3/Newtonsoft.Json.dll", + "lib/netstandard1.3/Newtonsoft.Json.xml", + "lib/netstandard2.0/Newtonsoft.Json.dll", + "lib/netstandard2.0/Newtonsoft.Json.xml", + "newtonsoft.json.13.0.3.nupkg.sha512", + "newtonsoft.json.nuspec", + "packageIcon.png" + ] + }, + "TDengine.Connector/3.1.3": { + "sha512": "dDX+Oex4I0X9yCalU0/YyUN0ecy+8X5xj6N8CoqeLrU6ICYDZgilSGQK9Fh3qmLobhGQvOJWwDpoO73rryHU5Q==", + "type": "package", + "path": "tdengine.connector/3.1.3", + "files": [ + ".nupkg.metadata", + "docs/README.md", + "image/logo.jpg", + "lib/net45/TDengine.dll", + "lib/net451/TDengine.dll", + "lib/net5.0/TDengine.dll", + "lib/net6.0/TDengine.dll", + "lib/netstandard2.0/TDengine.dll", + "lib/netstandard2.1/TDengine.dll", + "tdengine.connector.3.1.3.nupkg.sha512", + "tdengine.connector.nuspec" + ] + } + }, + "projectFileDependencyGroups": { + "net6.0": [ + "TDengine.Connector >= 3.1.*" + ] + }, + "packageFolders": { + "/root/.nuget/packages/": {} + }, + "project": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "/mnt/e/github/TDengine/docs/examples/csharp/wssubscribe/wssubscribe.csproj", + "projectName": "wssubscribe", + "projectPath": "/mnt/e/github/TDengine/docs/examples/csharp/wssubscribe/wssubscribe.csproj", + "packagesPath": "/root/.nuget/packages/", + "outputPath": "/mnt/e/github/TDengine/docs/examples/csharp/wssubscribe/obj/", + "projectStyle": "PackageReference", + "configFilePaths": [ + "/root/.nuget/NuGet/NuGet.Config" + ], + "originalTargetFrameworks": [ + "net6.0" + ], + "sources": { + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "net6.0": { + "targetAlias": "net6.0", + "projectReferences": {} + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + } + }, + "frameworks": { + "net6.0": { + "targetAlias": "net6.0", + "dependencies": { + "TDengine.Connector": { + "target": "Package", + "version": "[3.1.*, )", + "generatePathProperty": true + } + }, + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48", + "net481" + ], + "assetTargetFallback": true, + "warn": true, + "frameworkReferences": { + "Microsoft.NETCore.App": { + "privateAssets": "all" + } + }, + "runtimeIdentifierGraphPath": "/root/.dotnet/sdk/8.0.100/RuntimeIdentifierGraph.json" + } + } + } +} \ No newline at end of file diff --git a/docs/examples/csharp/wssubscribe/obj/project.nuget.cache b/docs/examples/csharp/wssubscribe/obj/project.nuget.cache new file mode 100644 index 0000000000..07a2d75f6b --- /dev/null +++ b/docs/examples/csharp/wssubscribe/obj/project.nuget.cache @@ -0,0 +1,11 @@ +{ + "version": 2, + "dgSpecHash": "iYS3B811DdocWqUXN2aMJdEwvfDVCixB5mK4XYN+98yFFNdPOU8hN4wQCxaOSFM7xKpvlmJvQPwkMetGBbFO8g==", + "success": true, + "projectFilePath": "/mnt/e/github/TDengine/docs/examples/csharp/wssubscribe/wssubscribe.csproj", + "expectedPackageFiles": [ + "/root/.nuget/packages/newtonsoft.json/13.0.3/newtonsoft.json.13.0.3.nupkg.sha512", + "/root/.nuget/packages/tdengine.connector/3.1.3/tdengine.connector.3.1.3.nupkg.sha512" + ], + "logs": [] +} \ No newline at end of file diff --git a/docs/examples/csharp/wssubscribe/obj/project.packagespec.json b/docs/examples/csharp/wssubscribe/obj/project.packagespec.json new file mode 100644 index 0000000000..319dd58c7f --- /dev/null +++ b/docs/examples/csharp/wssubscribe/obj/project.packagespec.json @@ -0,0 +1 @@ +"restore":{"projectUniqueName":"E:\\github\\TDengine\\docs\\examples\\csharp\\wssubscribe\\wssubscribe.csproj","projectName":"wssubscribe","projectPath":"E:\\github\\TDengine\\docs\\examples\\csharp\\wssubscribe\\wssubscribe.csproj","outputPath":"E:\\github\\TDengine\\docs\\examples\\csharp\\wssubscribe\\obj\\","projectStyle":"PackageReference","originalTargetFrameworks":["net6.0"],"sources":{"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\":{},"E:\\github\\taos-connector-dotnet\\src\\resource":{},"https://api.nuget.org/v3/index.json":{}},"frameworks":{"net6.0":{"targetAlias":"net6.0","projectReferences":{}}},"warningProperties":{"warnAsError":["NU1605"]}}"frameworks":{"net6.0":{"targetAlias":"net6.0","dependencies":{"TDengine.Connector":{"target":"Package","version":"[3.1.*, )","generatePathProperty":true}},"imports":["net461","net462","net47","net471","net472","net48","net481"],"assetTargetFallback":true,"warn":true,"frameworkReferences":{"Microsoft.NETCore.App":{"privateAssets":"all"}},"runtimeIdentifierGraphPath":"C:\\Program Files\\dotnet\\sdk\\8.0.202\\RuntimeIdentifierGraph.json"}} \ No newline at end of file diff --git a/docs/examples/csharp/wssubscribe/obj/rider.project.model.nuget.info b/docs/examples/csharp/wssubscribe/obj/rider.project.model.nuget.info new file mode 100644 index 0000000000..4a9bcd784b --- /dev/null +++ b/docs/examples/csharp/wssubscribe/obj/rider.project.model.nuget.info @@ -0,0 +1 @@ +17225691490262111 \ No newline at end of file diff --git a/docs/examples/csharp/wssubscribe/obj/rider.project.restore.info b/docs/examples/csharp/wssubscribe/obj/rider.project.restore.info new file mode 100644 index 0000000000..b8e44bdfbe --- /dev/null +++ b/docs/examples/csharp/wssubscribe/obj/rider.project.restore.info @@ -0,0 +1 @@ +17225689180408669 \ No newline at end of file diff --git a/docs/examples/csharp/wssubscribe/obj/wssubscribe.csproj.nuget.dgspec.json b/docs/examples/csharp/wssubscribe/obj/wssubscribe.csproj.nuget.dgspec.json new file mode 100644 index 0000000000..0825170a7d --- /dev/null +++ b/docs/examples/csharp/wssubscribe/obj/wssubscribe.csproj.nuget.dgspec.json @@ -0,0 +1,68 @@ +{ + "format": 1, + "restore": { + "/mnt/e/github/TDengine/docs/examples/csharp/wssubscribe/wssubscribe.csproj": {} + }, + "projects": { + "/mnt/e/github/TDengine/docs/examples/csharp/wssubscribe/wssubscribe.csproj": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "/mnt/e/github/TDengine/docs/examples/csharp/wssubscribe/wssubscribe.csproj", + "projectName": "wssubscribe", + "projectPath": "/mnt/e/github/TDengine/docs/examples/csharp/wssubscribe/wssubscribe.csproj", + "packagesPath": "/root/.nuget/packages/", + "outputPath": "/mnt/e/github/TDengine/docs/examples/csharp/wssubscribe/obj/", + "projectStyle": "PackageReference", + "configFilePaths": [ + "/root/.nuget/NuGet/NuGet.Config" + ], + "originalTargetFrameworks": [ + "net6.0" + ], + "sources": { + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "net6.0": { + "targetAlias": "net6.0", + "projectReferences": {} + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + } + }, + "frameworks": { + "net6.0": { + "targetAlias": "net6.0", + "dependencies": { + "TDengine.Connector": { + "target": "Package", + "version": "[3.1.*, )", + "generatePathProperty": true + } + }, + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48", + "net481" + ], + "assetTargetFallback": true, + "warn": true, + "frameworkReferences": { + "Microsoft.NETCore.App": { + "privateAssets": "all" + } + }, + "runtimeIdentifierGraphPath": "/root/.dotnet/sdk/8.0.100/RuntimeIdentifierGraph.json" + } + } + } + } +} \ No newline at end of file diff --git a/docs/examples/csharp/wssubscribe/obj/wssubscribe.csproj.nuget.g.props b/docs/examples/csharp/wssubscribe/obj/wssubscribe.csproj.nuget.g.props new file mode 100644 index 0000000000..939669445d --- /dev/null +++ b/docs/examples/csharp/wssubscribe/obj/wssubscribe.csproj.nuget.g.props @@ -0,0 +1,18 @@ + + + + True + NuGet + $(MSBuildThisFileDirectory)project.assets.json + /root/.nuget/packages/ + /root/.nuget/packages/ + PackageReference + 6.8.0 + + + + + + /root/.nuget/packages/tdengine.connector/3.1.3 + + \ No newline at end of file diff --git a/docs/examples/csharp/wssubscribe/obj/wssubscribe.csproj.nuget.g.targets b/docs/examples/csharp/wssubscribe/obj/wssubscribe.csproj.nuget.g.targets new file mode 100644 index 0000000000..35a7576c5a --- /dev/null +++ b/docs/examples/csharp/wssubscribe/obj/wssubscribe.csproj.nuget.g.targets @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/docs/examples/csharp/wssubscribe/wssubscribe.csproj b/docs/examples/csharp/wssubscribe/wssubscribe.csproj new file mode 100644 index 0000000000..3a2796a3af --- /dev/null +++ b/docs/examples/csharp/wssubscribe/wssubscribe.csproj @@ -0,0 +1,12 @@ + + + + Exe + net6.0 + enable + enable + + + + + diff --git a/docs/examples/go/connect/afconn/main.go b/docs/examples/go/connect/afconn/main.go index bb2574a01b..3e4dff43ac 100644 --- a/docs/examples/go/connect/afconn/main.go +++ b/docs/examples/go/connect/afconn/main.go @@ -13,6 +13,6 @@ func main() { if err != nil { log.Fatalln("failed to connect, err:", err) } else { - fmt.Println("connected") + fmt.Println("Connected") } } diff --git a/docs/examples/go/connect/cgoexample/main.go b/docs/examples/go/connect/cgoexample/main.go index 881cf15ee3..9c9b414b47 100644 --- a/docs/examples/go/connect/cgoexample/main.go +++ b/docs/examples/go/connect/cgoexample/main.go @@ -9,6 +9,9 @@ import ( ) func main() { + // use + // var taosDSN = "root:taosdata@tcp(localhost:6030)/dbName" + // if you want to connect a specified database named "dbName". var taosDSN = "root:taosdata@tcp(localhost:6030)/" taos, err := sql.Open("taosSql", taosDSN) if err != nil { @@ -18,7 +21,3 @@ func main() { fmt.Println("Connected") defer taos.Close() } - -// use -// var taosDSN = "root:taosdata@tcp(localhost:6030)/dbName" -// if you want to connect a specified database named "dbName". diff --git a/docs/examples/go/connect/connpool/main.go b/docs/examples/go/connect/connpool/main.go new file mode 100644 index 0000000000..e3058fca3f --- /dev/null +++ b/docs/examples/go/connect/connpool/main.go @@ -0,0 +1,33 @@ +package main + +import ( + "database/sql" + "fmt" + "log" + + _ "github.com/taosdata/driver-go/v3/taosSql" +) + +func main() { + // use + // var taosDSN = "root:taosdata@tcp(localhost:6030)/dbName" + // if you want to connect a specified database named "dbName". + var taosDSN = "root:taosdata@tcp(localhost:6030)/" + taos, err := sql.Open("taosSql", taosDSN) + if err != nil { + log.Fatalln("failed to connect TDengine, err:", err) + return + } + fmt.Println("Connected") + defer taos.Close() + // ANCHOR: pool + // SetMaxOpenConns sets the maximum number of open connections to the database. 0 means unlimited. + taos.SetMaxOpenConns(0) + // SetMaxIdleConns sets the maximum number of connections in the idle connection pool. + taos.SetMaxIdleConns(2) + // SetConnMaxLifetime sets the maximum amount of time a connection may be reused. + taos.SetConnMaxLifetime(0) + // SetConnMaxIdleTime sets the maximum amount of time a connection may be idle. + taos.SetConnMaxIdleTime(0) + // ANCHOR_END: pool +} diff --git a/docs/examples/go/connect/restexample/main.go b/docs/examples/go/connect/restexample/main.go index 67a129bf9c..ecc5110c60 100644 --- a/docs/examples/go/connect/restexample/main.go +++ b/docs/examples/go/connect/restexample/main.go @@ -9,6 +9,9 @@ import ( ) func main() { + // use + // var taosDSN = "root:taosdata@http(localhost:6041)/dbName" + // if you want to connect a specified database named "dbName". var taosDSN = "root:taosdata@http(localhost:6041)/" taos, err := sql.Open("taosRestful", taosDSN) if err != nil { @@ -18,7 +21,3 @@ func main() { fmt.Println("Connected") defer taos.Close() } - -// use -// var taosDSN = "root:taosdata@http(localhost:6041)/dbName" -// if you want to connect a specified database named "dbName". diff --git a/docs/examples/go/connect/wsexample/main.go b/docs/examples/go/connect/wsexample/main.go new file mode 100644 index 0000000000..c815f0aec5 --- /dev/null +++ b/docs/examples/go/connect/wsexample/main.go @@ -0,0 +1,23 @@ +package main + +import ( + "database/sql" + "fmt" + "log" + + _ "github.com/taosdata/driver-go/v3/taosWS" +) + +func main() { + // use + // var taosDSN = "root:taosdata@ws(localhost:6041)/dbName" + // if you want to connect a specified database named "dbName". + var taosDSN = "root:taosdata@ws(localhost:6041)/" + taos, err := sql.Open("taosWS", taosDSN) + if err != nil { + log.Fatalln("failed to connect TDengine, err:", err) + return + } + fmt.Println("Connected") + defer taos.Close() +} diff --git a/docs/examples/go/go.mod b/docs/examples/go/go.mod index 716a0ef5dc..ed8fde2d9f 100644 --- a/docs/examples/go/go.mod +++ b/docs/examples/go/go.mod @@ -2,5 +2,12 @@ module goexample go 1.17 -require github.com/taosdata/driver-go/v3 v3.1.0 +require github.com/taosdata/driver-go/v3 v3.5.6 +require ( + github.com/google/uuid v1.3.0 // indirect + github.com/gorilla/websocket v1.5.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect +) diff --git a/docs/examples/go/go.sum b/docs/examples/go/go.sum index 13e13adaa1..61841429ee 100644 --- a/docs/examples/go/go.sum +++ b/docs/examples/go/go.sum @@ -1,15 +1,25 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/taosdata/driver-go/v3 v3.1.0/go.mod h1:H2vo/At+rOPY1aMzUV9P49SVX7NlXb3LAbKw+MCLrmU= +github.com/taosdata/driver-go/v3 v3.5.6 h1:LDVtMyT3B9p2VREsd5KKM91D4Y7P4kSdh2SQumXi8bk= +github.com/taosdata/driver-go/v3 v3.5.6/go.mod h1:H2vo/At+rOPY1aMzUV9P49SVX7NlXb3LAbKw+MCLrmU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/docs/examples/go/queryreqid/main.go b/docs/examples/go/queryreqid/main.go new file mode 100644 index 0000000000..c7dd3d9215 --- /dev/null +++ b/docs/examples/go/queryreqid/main.go @@ -0,0 +1,55 @@ +package main + +import ( + "context" + "database/sql" + "fmt" + "time" + + _ "github.com/taosdata/driver-go/v3/taosSql" +) + +func main() { + db, err := sql.Open("taosSql", "root:taosdata@tcp(localhost:6030)/") + if err != nil { + panic(err) + } + defer db.Close() + initEnv(db) + // ANCHOR: query_id + // use context to set request id + ctx := context.WithValue(context.Background(), "taos_req_id", int64(3)) + // execute query with context + rows, err := db.QueryContext(ctx, "SELECT ts, current, location FROM power.meters limit 1") + if err != nil { + panic(err) + } + for rows.Next() { + var ( + ts time.Time + current float32 + location string + ) + err = rows.Scan(&ts, ¤t, &location) + if err != nil { + panic(err) + } + fmt.Printf("ts: %s, current: %f, location: %s\n", ts, current, location) + } + // ANCHOR_END: query_id +} + +func initEnv(conn *sql.DB) { + _, err := conn.Exec("CREATE DATABASE IF NOT EXISTS power") + if err != nil { + panic(err) + } + _, err = conn.Exec("CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))") + if err != nil { + panic(err) + } + _, err = conn.Exec("INSERT INTO power.d1001 USING power.meters TAGS (2, 'California.SanFrancisco') VALUES (NOW , 10.2, 219, 0.32)") + if err != nil { + panic(err) + } +} diff --git a/docs/examples/go/schemaless/native/main.go b/docs/examples/go/schemaless/native/main.go new file mode 100644 index 0000000000..b9cd70ef14 --- /dev/null +++ b/docs/examples/go/schemaless/native/main.go @@ -0,0 +1,41 @@ +package main + +import ( + "github.com/taosdata/driver-go/v3/af" +) + +func main() { + host := "127.0.0.1" + lineDemo := "meters,groupid=2,location=California.SanFrancisco current=10.3000002f64,voltage=219i32,phase=0.31f64 1626006833639" + telnetDemo := "metric_telnet 1707095283260 4 host=host0 interface=eth0" + jsonDemo := "{\"metric\": \"metric_json\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}" + + conn, err := af.Open(host, "root", "taosdata", "", 0) + if err != nil { + panic(err) + } + defer conn.Close() + _, err = conn.Exec("CREATE DATABASE IF NOT EXISTS power") + if err != nil { + panic(err) + } + _, err = conn.Exec("USE power") + if err != nil { + panic(err) + } + // insert influxdb line protocol + err = conn.InfluxDBInsertLines([]string{lineDemo}, "ms") + if err != nil { + panic(err) + } + // insert opentsdb telnet protocol + err = conn.OpenTSDBInsertTelnetLines([]string{telnetDemo}) + if err != nil { + panic(err) + } + // insert opentsdb json protocol + err = conn.OpenTSDBInsertJsonPayload(jsonDemo) + if err != nil { + panic(err) + } +} diff --git a/docs/examples/go/schemaless/ws/main.go b/docs/examples/go/schemaless/ws/main.go new file mode 100644 index 0000000000..c6807f213c --- /dev/null +++ b/docs/examples/go/schemaless/ws/main.go @@ -0,0 +1,57 @@ +package main + +import ( + "database/sql" + "fmt" + "log" + "time" + + "github.com/taosdata/driver-go/v3/common" + _ "github.com/taosdata/driver-go/v3/taosWS" + "github.com/taosdata/driver-go/v3/ws/schemaless" +) + +func main() { + host := "127.0.0.1" + lineDemo := "meters,groupid=2,location=California.SanFrancisco current=10.3000002f64,voltage=219i32,phase=0.31f64 1626006833639" + telnetDemo := "metric_telnet 1707095283260 4 host=host0 interface=eth0" + jsonDemo := "{\"metric\": \"metric_json\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}" + + db, err := sql.Open("taosWS", fmt.Sprintf("root:taosdata@ws(%s:6041)/", host)) + if err != nil { + log.Fatal(err) + } + defer db.Close() + _, err = db.Exec("CREATE DATABASE IF NOT EXISTS power") + if err != nil { + log.Fatal(err) + } + s, err := schemaless.NewSchemaless(schemaless.NewConfig("ws://localhost:6041", 1, + schemaless.SetDb("power"), + schemaless.SetReadTimeout(10*time.Second), + schemaless.SetWriteTimeout(10*time.Second), + schemaless.SetUser("root"), + schemaless.SetPassword("taosdata"), + schemaless.SetErrorHandler(func(err error) { + log.Fatal(err) + }), + )) + if err != nil { + panic(err) + } + // insert influxdb line protocol + err = s.Insert(lineDemo, schemaless.InfluxDBLineProtocol, "ms", 0, common.GetReqID()) + if err != nil { + panic(err) + } + // insert opentsdb telnet line protocol + err = s.Insert(telnetDemo, schemaless.OpenTSDBTelnetLineProtocol, "ms", 0, common.GetReqID()) + if err != nil { + panic(err) + } + // insert opentsdb json format protocol + err = s.Insert(jsonDemo, schemaless.OpenTSDBJsonFormatProtocol, "s", 0, common.GetReqID()) + if err != nil { + panic(err) + } +} diff --git a/docs/examples/go/sqlquery/main.go b/docs/examples/go/sqlquery/main.go new file mode 100644 index 0000000000..12e1732b31 --- /dev/null +++ b/docs/examples/go/sqlquery/main.go @@ -0,0 +1,88 @@ +package main + +import ( + "database/sql" + "fmt" + "time" + + _ "github.com/taosdata/driver-go/v3/taosSql" +) + +func main() { + db, err := sql.Open("taosSql", "root:taosdata@tcp(localhost:6030)/") + if err != nil { + panic(err) + } + defer db.Close() + // ANCHOR: create_db_and_table + // create database + res, err := db.Exec("CREATE DATABASE IF NOT EXISTS power") + if err != nil { + panic(err) + } + affected, err := res.RowsAffected() + if err != nil { + panic(err) + } + fmt.Println("create database affected:", affected) + // use database + res, err = db.Exec("USE power") + if err != nil { + panic(err) + } + affected, err = res.RowsAffected() + if err != nil { + panic(err) + } + fmt.Println("use database affected:", affected) + // create table + res, err = db.Exec("CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))") + affected, err = res.RowsAffected() + if err != nil { + panic(err) + } + fmt.Println("create table affected:", affected) + // ANCHOR_END: create_db_and_table + // ANCHOR: insert_data + // insert data, please make sure the database and table are created before + insertQuery := "INSERT INTO " + + "power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " + + "VALUES " + + "(NOW + 1a, 10.30000, 219, 0.31000) " + + "(NOW + 2a, 12.60000, 218, 0.33000) " + + "(NOW + 3a, 12.30000, 221, 0.31000) " + + "power.d1002 USING power.meters TAGS(3, 'California.SanFrancisco') " + + "VALUES " + + "(NOW + 1a, 10.30000, 218, 0.25000) " + res, err = db.Exec(insertQuery) + if err != nil { + panic(err) + } + affected, err = res.RowsAffected() + if err != nil { + panic(err) + } + // you can check affectedRows here + fmt.Println("insert data affected:", affected) + // ANCHOR_END: insert_data + // ANCHOR: select_data + // query data, make sure the database and table are created before + rows, err := db.Query("SELECT ts, current, location FROM power.meters limit 100") + if err != nil { + panic(err) + } + for rows.Next() { + var ( + ts time.Time + current float32 + location string + ) + err = rows.Scan(&ts, ¤t, &location) + if err != nil { + panic(err) + } + // you can check data here + fmt.Printf("ts: %s, current: %f, location: %s\n", ts, current, location) + } + // ANCHOR_END: select_data +} diff --git a/docs/examples/go/stmt/native/main.go b/docs/examples/go/stmt/native/main.go new file mode 100644 index 0000000000..63986912da --- /dev/null +++ b/docs/examples/go/stmt/native/main.go @@ -0,0 +1,82 @@ +package main + +import ( + "fmt" + "math/rand" + "time" + + "github.com/taosdata/driver-go/v3/af" + "github.com/taosdata/driver-go/v3/common" + "github.com/taosdata/driver-go/v3/common/param" +) + +func main() { + host := "127.0.0.1" + numOfSubTable := 10 + numOfRow := 10 + db, err := af.Open(host, "root", "taosdata", "", 0) + if err != nil { + panic(err) + } + defer db.Close() + // prepare database and table + _, err = db.Exec("CREATE DATABASE IF NOT EXISTS power") + if err != nil { + panic(err) + } + _, err = db.Exec("USE power") + if err != nil { + panic(err) + } + _, err = db.Exec("CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))") + if err != nil { + panic(err) + } + // prepare statement + sql := "INSERT INTO ? USING meters TAGS(?,?) VALUES (?,?,?,?)" + stmt := db.Stmt() + err = stmt.Prepare(sql) + if err != nil { + panic(err) + } + for i := 1; i <= numOfSubTable; i++ { + tableName := fmt.Sprintf("d_bind_%d", i) + tags := param.NewParam(2).AddInt(i).AddBinary([]byte(fmt.Sprintf("location_%d", i))) + // set tableName and tags + err = stmt.SetTableNameWithTags(tableName, tags) + if err != nil { + panic(err) + } + // bind column data + current := time.Now() + for j := 0; j < numOfRow; j++ { + row := param.NewParam(4). + AddTimestamp(current.Add(time.Millisecond*time.Duration(j)), common.PrecisionMilliSecond). + AddFloat(rand.Float32() * 30). + AddInt(rand.Intn(300)). + AddFloat(rand.Float32()) + err = stmt.BindRow(row) + if err != nil { + panic(err) + } + } + // add batch + err = stmt.AddBatch() + if err != nil { + panic(err) + } + // execute batch + err = stmt.Execute() + if err != nil { + panic(err) + } + // get affected rows + affected := stmt.GetAffectedRows() + // you can check exeResult here + fmt.Printf("table %s insert %d rows.\n", tableName, affected) + } + err = stmt.Close() + if err != nil { + panic(err) + } +} diff --git a/docs/examples/go/stmt/ws/main.go b/docs/examples/go/stmt/ws/main.go new file mode 100644 index 0000000000..ddb1d6e2a7 --- /dev/null +++ b/docs/examples/go/stmt/ws/main.go @@ -0,0 +1,102 @@ +package main + +import ( + "database/sql" + "fmt" + "math/rand" + "time" + + "github.com/taosdata/driver-go/v3/common" + "github.com/taosdata/driver-go/v3/common/param" + _ "github.com/taosdata/driver-go/v3/taosRestful" + "github.com/taosdata/driver-go/v3/ws/stmt" +) + +func main() { + host := "127.0.0.1" + numOfSubTable := 10 + numOfRow := 10 + db, err := sql.Open("taosRestful", fmt.Sprintf("root:taosdata@http(%s:6041)/", host)) + if err != nil { + panic(err) + } + defer db.Close() + // prepare database and table + _, err = db.Exec("CREATE DATABASE IF NOT EXISTS power") + if err != nil { + panic(err) + } + _, err = db.Exec("CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))") + if err != nil { + panic(err) + } + + config := stmt.NewConfig(fmt.Sprintf("ws://%s:6041", host), 0) + config.SetConnectUser("root") + config.SetConnectPass("taosdata") + config.SetConnectDB("power") + config.SetMessageTimeout(common.DefaultMessageTimeout) + config.SetWriteWait(common.DefaultWriteWait) + + connector, err := stmt.NewConnector(config) + if err != nil { + panic(err) + } + // // prepare statement + sql := "INSERT INTO ? USING meters TAGS(?,?) VALUES (?,?,?,?)" + stmt, err := connector.Init() + if err != nil { + panic(err) + } + err = stmt.Prepare(sql) + if err != nil { + panic(err) + } + for i := 1; i <= numOfSubTable; i++ { + tableName := fmt.Sprintf("d_bind_%d", i) + tags := param.NewParam(2).AddInt(i).AddBinary([]byte(fmt.Sprintf("location_%d", i))) + tagsType := param.NewColumnType(2).AddInt().AddBinary(24) + columnType := param.NewColumnType(4).AddTimestamp().AddFloat().AddInt().AddFloat() + // set tableName + err = stmt.SetTableName(tableName) + if err != nil { + panic(err) + } + // set tags + err = stmt.SetTags(tags, tagsType) + if err != nil { + panic(err) + } + // bind column data + current := time.Now() + for j := 0; j < numOfRow; j++ { + columnData := make([]*param.Param, 4) + columnData[0] = param.NewParam(1).AddTimestamp(current.Add(time.Millisecond*time.Duration(j)), common.PrecisionMilliSecond) + columnData[1] = param.NewParam(1).AddFloat(rand.Float32() * 30) + columnData[2] = param.NewParam(1).AddInt(rand.Intn(300)) + columnData[3] = param.NewParam(1).AddFloat(rand.Float32()) + err = stmt.BindParam(columnData, columnType) + if err != nil { + panic(err) + } + } + // add batch + err = stmt.AddBatch() + if err != nil { + panic(err) + } + // execute batch + err = stmt.Exec() + if err != nil { + panic(err) + } + // get affected rows + affected := stmt.GetAffectedRows() + // you can check exeResult here + fmt.Printf("table %s insert %d rows.\n", tableName, affected) + } + err = stmt.Close() + if err != nil { + panic(err) + } +} diff --git a/docs/examples/go/tmq/native/main.go b/docs/examples/go/tmq/native/main.go new file mode 100644 index 0000000000..668898239e --- /dev/null +++ b/docs/examples/go/tmq/native/main.go @@ -0,0 +1,132 @@ +package main + +import ( + "database/sql" + "fmt" + "time" + + "github.com/taosdata/driver-go/v3/af/tmq" + tmqcommon "github.com/taosdata/driver-go/v3/common/tmq" + _ "github.com/taosdata/driver-go/v3/taosSql" +) + +var done = make(chan struct{}) + +func main() { + // init env + conn, err := sql.Open("taosSql", "root:taosdata@tcp(127.0.0.1:6030)/") + if err != nil { + panic(err) + } + defer func() { + conn.Close() + }() + initEnv(conn) + // ANCHOR: create_consumer + // create consumer + consumer, err := tmq.NewConsumer(&tmqcommon.ConfigMap{ + "td.connect.user": "root", + "td.connect.pass": "taosdata", + "auto.offset.reset": "latest", + "msg.with.table.name": "true", + "enable.auto.commit": "true", + "auto.commit.interval.ms": "1000", + "group.id": "group2", + "client.id": "1", + }) + if err != nil { + panic(err) + } + // ANCHOR_END: create_consumer + // ANCHOR: subscribe + err = consumer.Subscribe("topic_meters", nil) + if err != nil { + panic(err) + } + for i := 0; i < 50; i++ { + ev := consumer.Poll(100) + if ev != nil { + switch e := ev.(type) { + case *tmqcommon.DataMessage: + // process your data here + fmt.Printf("get message:%v\n", e) + // ANCHOR: commit_offset + // commit offset + topicPartition, err := consumer.CommitOffsets([]tmqcommon.TopicPartition{e.TopicPartition}) + if err != nil { + panic(err) + } + fmt.Println(topicPartition) + // ANCHOR_END: commit_offset + case tmqcommon.Error: + fmt.Printf("%% Error: %v: %v\n", e.Code(), e) + panic(e) + } + // commit all offsets + topicPartition, err := consumer.Commit() + if err != nil { + panic(err) + } + fmt.Println(topicPartition) + + } + } + // ANCHOR_END: subscribe + // ANCHOR: seek + // get assignment + partitions, err := consumer.Assignment() + if err != nil { + panic(err) + } + for i := 0; i < len(partitions); i++ { + fmt.Println(partitions[i]) + // seek to the beginning + err = consumer.Seek(tmqcommon.TopicPartition{ + Topic: partitions[i].Topic, + Partition: partitions[i].Partition, + Offset: 0, + }, 0) + if err != nil { + panic(err) + } + } + // ANCHOR_END: seek + // ANCHOR: close + // unsubscribe + err = consumer.Unsubscribe() + if err != nil { + panic(err) + } + // close consumer + err = consumer.Close() + if err != nil { + panic(err) + } + // ANCHOR_END: close + <-done +} + +func initEnv(conn *sql.DB) { + _, err := conn.Exec("CREATE DATABASE IF NOT EXISTS power") + if err != nil { + panic(err) + } + _, err = conn.Exec("CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))") + if err != nil { + panic(err) + } + _, err = conn.Exec("CREATE TOPIC IF NOT EXISTS topic_meters AS SELECT ts, current, voltage, phase, groupid, location FROM power.meters") + if err != nil { + panic(err) + } + go func() { + for i := 0; i < 10; i++ { + time.Sleep(time.Second) + _, err = conn.Exec("INSERT INTO power.d1001 USING power.meters TAGS (2, 'California.SanFrancisco') VALUES (NOW , 10.2, 219, 0.32)") + if err != nil { + panic(err) + } + } + done <- struct{}{} + }() +} diff --git a/docs/examples/go/tmq/ws/main.go b/docs/examples/go/tmq/ws/main.go new file mode 100644 index 0000000000..48e6714957 --- /dev/null +++ b/docs/examples/go/tmq/ws/main.go @@ -0,0 +1,137 @@ +package main + +import ( + "database/sql" + "fmt" + "time" + + "github.com/taosdata/driver-go/v3/common" + tmqcommon "github.com/taosdata/driver-go/v3/common/tmq" + _ "github.com/taosdata/driver-go/v3/taosWS" + "github.com/taosdata/driver-go/v3/ws/tmq" +) + +var done = make(chan struct{}) + +func main() { + // init env + conn, err := sql.Open("taosWS", "root:taosdata@ws(127.0.0.1:6041)/") + if err != nil { + panic(err) + } + defer func() { + conn.Close() + }() + initEnv(conn) + // ANCHOR: create_consumer + // create consumer + consumer, err := tmq.NewConsumer(&tmqcommon.ConfigMap{ + "ws.url": "ws://127.0.0.1:6041", + "ws.message.channelLen": uint(0), + "ws.message.timeout": common.DefaultMessageTimeout, + "ws.message.writeWait": common.DefaultWriteWait, + "td.connect.user": "root", + "td.connect.pass": "taosdata", + "auto.offset.reset": "latest", + "msg.with.table.name": "true", + "enable.auto.commit": "true", + "auto.commit.interval.ms": "1000", + "group.id": "group2", + "client.id": "1", + }) + if err != nil { + panic(err) + } + // ANCHOR_END: create_consumer + // ANCHOR: subscribe + err = consumer.Subscribe("topic_meters", nil) + if err != nil { + panic(err) + } + for i := 0; i < 50; i++ { + ev := consumer.Poll(100) + if ev != nil { + switch e := ev.(type) { + case *tmqcommon.DataMessage: + // process your data here + fmt.Printf("get message:%v\n", e) + // ANCHOR: commit_offset + // commit offset + topicPartition, err := consumer.CommitOffsets([]tmqcommon.TopicPartition{e.TopicPartition}) + if err != nil { + panic(err) + } + fmt.Println(topicPartition) + // ANCHOR_END: commit_offset + case tmqcommon.Error: + fmt.Printf("%% Error: %v: %v\n", e.Code(), e) + panic(e) + } + // commit all offsets + topicPartition, err := consumer.Commit() + if err != nil { + panic(err) + } + fmt.Println(topicPartition) + + } + } + // ANCHOR_END: subscribe + // ANCHOR: seek + // get assignment + partitions, err := consumer.Assignment() + if err != nil { + panic(err) + } + for i := 0; i < len(partitions); i++ { + fmt.Println(partitions[i]) + // seek to the beginning + err = consumer.Seek(tmqcommon.TopicPartition{ + Topic: partitions[i].Topic, + Partition: partitions[i].Partition, + Offset: 0, + }, 0) + if err != nil { + panic(err) + } + } + // ANCHOR_END: seek + // ANCHOR: close + // unsubscribe + err = consumer.Unsubscribe() + if err != nil { + panic(err) + } + // close consumer + err = consumer.Close() + if err != nil { + panic(err) + } + // ANCHOR_END: close + <-done +} + +func initEnv(conn *sql.DB) { + _, err := conn.Exec("CREATE DATABASE IF NOT EXISTS power") + if err != nil { + panic(err) + } + _, err = conn.Exec("CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))") + if err != nil { + panic(err) + } + _, err = conn.Exec("CREATE TOPIC IF NOT EXISTS topic_meters AS SELECT ts, current, voltage, phase, groupid, location FROM power.meters") + if err != nil { + panic(err) + } + go func() { + for i := 0; i < 10; i++ { + time.Sleep(time.Second) + _, err = conn.Exec("INSERT INTO power.d1001 USING power.meters TAGS (2, 'California.SanFrancisco') VALUES (NOW , 10.2, 219, 0.32)") + if err != nil { + panic(err) + } + } + done <- struct{}{} + }() +} diff --git a/docs/zh/08-develop/01-connect/index.md b/docs/zh/08-develop/01-connect/index.md index 48af1f7a63..89c3dd7f69 100644 --- a/docs/zh/08-develop/01-connect/index.md +++ b/docs/zh/08-develop/01-connect/index.md @@ -220,7 +220,7 @@ taos = { version = "*", default-features = false, features = ["ws"] } 编辑项目配置文件中添加 [TDengine.Connector](https://www.nuget.org/packages/TDengine.Connector/) 的引用即可: -```xml title=csharp.csproj {12} +```xml title=csharp.csproj @@ -327,6 +327,40 @@ URL 和 Properties 的详细参数说明和如何使用详见 [url 规范](../.. + + 数据源名称具有通用格式,例如 [PEAR DB](http://pear.php.net/manual/en/package.database.db.intro-dsn.php),但没有类型前缀(方括号表示可选): + + ``` text + [username[:password]@][protocol[(address)]]/[dbname][?param1=value1&...¶mN=valueN] + ``` + + 完整形式的 DSN: + + ```text + username:password@protocol(address)/dbname?param=value + ``` + + 支持的 DSN 参数如下 + + 原生连接: + + - `cfg` 指定 taos.cfg 目录 + - `cgoThread` 指定 cgo 同时执行的数量,默认为系统核数 + - `cgoAsyncHandlerPoolSize` 指定异步函数的 handle 大小,默认为 10000 + + REST 连接: + + - `disableCompression` 是否接受压缩数据,默认为 true 不接受压缩数据,如果传输数据使用 gzip 压缩设置为 false。 + - `readBufferSize` 读取数据的缓存区大小默认为 4K(4096),当查询结果数据量多时可以适当调大该值。 + - `token` 连接云服务时使用的 token。 + - `skipVerify` 是否跳过证书验证,默认为 false 不跳过证书验证,如果连接的是不安全的服务设置为 true。 + + WebSocket 连接: + + - `enableCompression` 是否发送压缩数据,默认为 false 不发送压缩数据,如果传输数据使用压缩设置为 true。 + - `readTimeout` 读取数据的超时时间,默认为 5m。 + - `writeTimeout` 写入数据的超时时间,默认为 10s。 + Rust 连接器使用 DSN 来创建连接, DSN 描述字符串基本结构如下: @@ -341,6 +375,34 @@ DSN 的详细说明和如何使用详见 [连接功能](../../reference/connecto + ConnectionStringBuilder 使用 key-value 对方式设置连接参数,key 为参数名,value 为参数值,不同参数之间使用分号 `;` 分割。 + + 例如: + + ```csharp + "protocol=WebSocket;host=127.0.0.1;port=6041;useSSL=false" + ``` + 支持的参数如下: + + - `host`:TDengine 运行实例的地址。 + - `port`:TDengine 运行实例的端口。 + - `username`:连接的用户名。 + - `password`:连接的密码。 + - `protocol`:连接的协议,可选值为 Native 或 WebSocket,默认为 Native。 + - `db`:连接的数据库。 + - `timezone`:时区,默认为本地时区。 + - `connTimeout`:连接超时时间,默认为 1 分钟。 + + WebSocket 连接额外支持以下参数: + + - `readTimeout`:读取超时时间,默认为 5 分钟。 + - `writeTimeout`:发送超时时间,默认为 10 秒。 + - `token`:连接 TDengine cloud 的 token。 + - `useSSL`:是否使用 SSL 连接,默认为 false。 + - `enableCompression`:是否启用 WebSocket 压缩,默认为 false。 + - `autoReconnect`:是否自动重连,默认为 false。 + - `reconnectRetryCount`:重连次数,默认为 3。 + - `reconnectIntervalMs`:重连间隔毫秒时间,默认为 2000。 @@ -383,7 +445,7 @@ DSN 的详细说明和如何使用详见 [连接功能](../../reference/connecto 下面是各语言连接器建立 Websocket 连接代码样例。演示了如何使用 Websocket 连接方式连接到 TDengine 数据库,并对连接设定一些参数。整个过程主要涉及到数据库连接的建立和异常处理。 - + ```java {{#include docs/examples/java/src/main/java/com/taos/example/WSConnectExample.java:main}} ``` @@ -394,7 +456,9 @@ DSN 的详细说明和如何使用详见 [连接功能](../../reference/connecto ``` - +```go +{{#include docs/examples/go/connect/wsexample/main.go}} +``` ```rust @@ -407,7 +471,9 @@ DSN 的详细说明和如何使用详见 [连接功能](../../reference/connecto ``` - +```csharp +{{#include docs/examples/csharp/wsConnect/Program.cs:main}} +``` @@ -428,36 +494,39 @@ DSN 的详细说明和如何使用详见 [连接功能](../../reference/connecto ```java {{#include docs/examples/java/src/main/java/com/taos/example/JNIConnectExample.java:main}} ``` - - - - - - - - + + + + + +```go +{{#include docs/examples/go/connect/cgoexample/main.go}} +``` + + ```rust {{#include docs/examples/rust/nativeexample/examples/connect.rs}} ``` - - - - - - - - - - - - - - + + +```csharp title="WebSocket 连接" +{{#include docs/examples/csharp/connect/Program.cs:main}} +``` + + + + + + + + + + ### REST 连接 -下面是各语言连接器建立 RESt 连接代码样例。演示了如何使用 REST 连接方式连接到 TDengine 数据库。整个过程主要涉及到数据库连接的建立和异常处理。 +下面是各语言连接器建立 REST 连接代码样例。演示了如何使用 REST 连接方式连接到 TDengine 数据库。整个过程主要涉及到数据库连接的建立和异常处理。 @@ -471,13 +540,15 @@ DSN 的详细说明和如何使用详见 [连接功能](../../reference/connecto ``` - + ```go + {{#include docs/examples/go/connect/restexample/main.go}} + ``` 不支持 - + C# 只支持 WebSocket 连接与原生连接 @@ -531,7 +602,13 @@ DSN 的详细说明和如何使用详见 [连接功能](../../reference/connecto - + +使用 `sql.Open` 创建出来的连接已经实现了连接池,可以通过 API 设置连接池参数,样例如下 + +```go +{{#include docs/examples/go/connect/connpool/main.go:pool}} +``` + @@ -563,7 +640,7 @@ let taos = pool.get()?; - + 不支持 diff --git a/docs/zh/08-develop/02-sql.md b/docs/zh/08-develop/02-sql.md index f24a35eb75..5476154158 100644 --- a/docs/zh/08-develop/02-sql.md +++ b/docs/zh/08-develop/02-sql.md @@ -11,6 +11,15 @@ TDengine 对 SQL 语言提供了全面的支持,允许用户以熟悉的 SQL 下面介绍使用各语言连接器通过执行 SQL 完成建库、建表、写入数据和查询数据。 +:::note + +REST 连接:各编程语言的连接器封装使用 `HTTP` 请求的连接,支持数据写入和查询操作。 + +REST API:通过 `curl` 命令进行数据写入和查询操作。 + +::: + + ## 建库和表 下面以智能电表为例,展示使用各语言连接器如何执行 SQL 命令创建一个名为 `power` 的数据库,然后使用 `power` 数据库为默认数据库。 接着创建一个名为 `meters` 的超级表(STABLE),其表结构包含时间戳、电流、电压、相位等列,以及分组 ID 和位置作为标签。 @@ -28,6 +37,9 @@ TDengine 对 SQL 语言提供了全面的支持,允许用户以熟悉的 SQL +```go +{{#include docs/examples/go/queryreqid/main.go:query_id}} +``` @@ -37,6 +49,9 @@ TDengine 对 SQL 语言提供了全面的支持,允许用户以熟悉的 SQL +```csharp +{{#include docs/examples/csharp/wsInsert/Program.cs:create_db_and_table}} +``` @@ -47,6 +62,23 @@ TDengine 对 SQL 语言提供了全面的支持,允许用户以熟悉的 SQL > **注意**:如果不使用 `USE power` 指定数据库,则后续对表的操作都需要增加数据库名称作为前缀,如 power.meters。 + + + +创建数据库 + +```bash +curl --location -uroot:taosdata 'http://127.0.0.1:6041/rest/sql' \ +--data 'CREATE DATABASE IF NOT EXISTS power' +``` + +创建表,在 url 中指定数据库为 `power` + +```bash +curl --location -uroot:taosdata 'http://127.0.0.1:6041/rest/sql/power' \ +--data 'CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))' +``` + > **注意**:如果不使用 `USE power` 指定数据库,则后续对表的操作都需要增加数据库名称作为前缀,如 `power.meters`。 @@ -68,6 +100,9 @@ NOW 为系统内部函数,默认为客户端所在计算机当前时间。 NOW +```go +{{#include docs/examples/go/sqlquery/main.go:create_db_and_table}} +``` @@ -77,6 +112,9 @@ NOW 为系统内部函数,默认为客户端所在计算机当前时间。 NOW +```csharp +{{#include docs/examples/csharp/wsInsert/Program.cs:insert_data}} +``` @@ -89,6 +127,16 @@ NOW 为系统内部函数,默认为客户端所在计算机当前时间。 NOW NOW 为系统内部函数,默认为客户端所在计算机当前时间。 NOW + 1s 代表客户端当前时间往后加 1 秒,数字后面代表时间单位:a(毫秒),s(秒),m(分),h(小时),d(天),w(周),n(月),y(年)。 + + + +写入数据 + +```bash +curl --location -uroot:taosdata 'http://127.0.0.1:6041/rest/sql' \ +--data 'INSERT INTO power.d1001 USING power.meters TAGS(2,'\''California.SanFrancisco'\'') VALUES (NOW + 1a, 10.30000, 219, 0.31000) (NOW + 2a, 12.60000, 218, 0.33000) (NOW + 3a, 12.30000, 221, 0.31000) power.d1002 USING power.meters TAGS(3, '\''California.SanFrancisco'\'') VALUES (NOW + 1a, 10.30000, 218, 0.25000)' +``` + @@ -108,6 +156,9 @@ NOW 为系统内部函数,默认为客户端所在计算机当前时间。 NOW +```go +{{#include docs/examples/go/sqlquery/main.go:insert_data}} +``` @@ -117,6 +168,9 @@ NOW 为系统内部函数,默认为客户端所在计算机当前时间。 NOW +```csharp +{{#include docs/examples/csharp/wsInsert/Program.cs:select_data}} +``` @@ -126,6 +180,16 @@ NOW 为系统内部函数,默认为客户端所在计算机当前时间。 NOW ``` + + + +查询数据 + +```bash +curl --location -uroot:taosdata 'http://127.0.0.1:6041/rest/sql' \ +--data 'SELECT ts, current, location FROM power.meters limit 100' +``` + @@ -153,6 +217,9 @@ reqId 可用于请求链路追踪,reqId 就像分布式系统中的 traceId +```go +{{#include docs/examples/go/sqlquery/main.go:select_data}} +``` @@ -162,6 +229,9 @@ reqId 可用于请求链路追踪,reqId 就像分布式系统中的 traceId +```csharp +{{#include docs/examples/csharp/wsInsert/Program.cs:query_id}} +``` @@ -171,5 +241,15 @@ reqId 可用于请求链路追踪,reqId 就像分布式系统中的 traceId ``` + + + +查询数据,指定 reqId 为 3 + +```bash +curl --location -uroot:taosdata 'http://127.0.0.1:6041/rest/sql?req_id=3' \ +--data 'SELECT ts, current, location FROM power.meters limit 1' +``` + diff --git a/docs/zh/08-develop/04-schemaless.md b/docs/zh/08-develop/04-schemaless.md index 9c136cb109..71c9a5e1bd 100644 --- a/docs/zh/08-develop/04-schemaless.md +++ b/docs/zh/08-develop/04-schemaless.md @@ -179,6 +179,9 @@ writer.write(lineDemo, SchemalessProtocolType.LINE, SchemalessTimestampType.NANO +```go +{{#include docs/examples/go/schemaless/ws/main.go}} +``` @@ -188,6 +191,9 @@ writer.write(lineDemo, SchemalessProtocolType.LINE, SchemalessTimestampType.NANO +```csharp +{{#include docs/examples/csharp/wssml/Program.cs:main}} +``` @@ -210,22 +216,25 @@ writer.write(lineDemo, SchemalessProtocolType.LINE, SchemalessTimestampType.NANO writer.write(lineDemo, SchemalessProtocolType.LINE, SchemalessTimestampType.NANO_SECONDS, 1L); ``` - - - - - - + + + + + + 除 DSN 不同,其余同 Websocket 代码示例。 - - - - - - - - - + + +```csharp +{{#include docs/examples/csharp/nativesml/Program.cs:main}} +``` + + + + + + + @@ -238,11 +247,15 @@ writer.write(lineDemo, SchemalessProtocolType.LINE, SchemalessTimestampType.NANO + ```go + {{#include docs/examples/go/schemaless/native/main.go}} + ``` 不支持 + 不支持 diff --git a/docs/zh/08-develop/05-stmt.md b/docs/zh/08-develop/05-stmt.md index 5dd9daaed5..b8c3c60d47 100644 --- a/docs/zh/08-develop/05-stmt.md +++ b/docs/zh/08-develop/05-stmt.md @@ -39,7 +39,9 @@ import TabItem from "@theme/TabItem"; ``` - +```go +{{#include docs/examples/go/stmt/ws/main.go}} +``` @@ -55,7 +57,9 @@ import TabItem from "@theme/TabItem"; ``` - +```csharp +{{#include docs/examples/csharp/wsStmt/Program.cs:main}} +``` @@ -83,13 +87,17 @@ import TabItem from "@theme/TabItem"; - +```go +{{#include docs/examples/go/stmt/native/main.go}} +``` 除 DSN 不同,其余同 Websocket 代码示例。 - +```csharp +{{#include docs/examples/csharp/stmtInsert/Program.cs:main}} +``` diff --git a/docs/zh/08-develop/07-tmq.md b/docs/zh/08-develop/07-tmq.md index a5795b5b6e..6f259cf521 100644 --- a/docs/zh/08-develop/07-tmq.md +++ b/docs/zh/08-develop/07-tmq.md @@ -56,6 +56,19 @@ Java 连接器创建消费者的参数为 Properties, 可以设置的参数列 +创建消费者支持属性列表: + +- `ws.url`:WebSocket 连接地址。 +- `ws.message.channelLen`:WebSocket 消息通道缓存长度,默认 0。 +- `ws.message.timeout`:WebSocket 消息超时时间,默认 5m。 +- `ws.message.writeWait`:WebSocket 写入消息超时时间,默认 10s。 +- `ws.message.enableCompression`:WebSocket 是否启用压缩,默认 false。 +- `ws.autoReconnect`:WebSocket 是否自动重连,默认 false。 +- `ws.reconnectIntervalMs`:WebSocket 重连间隔时间毫秒,默认 2000。 +- `ws.reconnectRetryCount`:WebSocket 重连重试次数,默认 3。 + +其他参数见上表。 + Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请参考 [DSN](../../reference/connector/rust/#dsn) @@ -66,6 +79,16 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 +创建消费者支持属性列表: + +- `useSSL`:是否使用 SSL 连接,默认为 false。 +- `token`:连接 TDengine cloud 的 token。 +- `ws.message.enableCompression`:是否启用 WebSocket 压缩,默认为 false。 +- `ws.autoReconnect`:是否自动重连,默认为 false。 +- `ws.reconnect.retry.count`:重连次数,默认为 3。 +- `ws.reconnect.interval.ms`:重连间隔毫秒时间,默认为 2000。 + +其他参数见上表。 @@ -99,7 +122,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```go +{{#include docs/examples/go/tmq/ws/main.go:create_consumer}} +``` @@ -117,7 +142,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```csharp +{{#include docs/examples/csharp/wssubscribe/Program.cs:create_consumer}} +``` @@ -157,7 +184,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```go +{{#include docs/examples/go/tmq/native/main.go:create_consumer}} +``` @@ -165,7 +194,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```csharp +{{#include docs/examples/csharp/subscribe/Program.cs:create_consumer}} +``` @@ -205,7 +236,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```go +{{#include docs/examples/go/tmq/ws/main.go:subscribe}} +``` @@ -217,7 +250,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```csharp +{{#include docs/examples/csharp/wssubscribe/Program.cs:subscribe}} +``` @@ -249,7 +284,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```go +{{#include docs/examples/go/tmq/native/main.go:subscribe}} +``` @@ -257,7 +294,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```csharp +{{#include docs/examples/csharp/subscribe/Program.cs:subscribe}} +``` @@ -294,7 +333,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```go +{{#include docs/examples/go/tmq/ws/main.go:seek}} +``` @@ -306,7 +347,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```csharp +{{#include docs/examples/csharp/wssubscribe/Program.cs:seek}} +``` @@ -338,7 +381,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```go +{{#include docs/examples/go/tmq/native/main.go:seek}} +``` @@ -346,7 +391,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```csharp +{{#include docs/examples/csharp/subscribe/Program.cs:seek}} +``` @@ -385,7 +432,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```go +{{#include docs/examples/go/tmq/ws/main.go:commit_offset}} +``` @@ -397,7 +446,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```csharp +{{#include docs/examples/csharp/wssubscribe/Program.cs:commit_offset}} +``` @@ -431,7 +482,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```go +{{#include docs/examples/go/tmq/native/main.go:commit_offset}} +``` @@ -443,7 +496,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```csharp +{{#include docs/examples/csharp/subscribe/Program.cs:commit_offset}} +``` @@ -482,7 +537,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```go +{{#include docs/examples/go/tmq/ws/main.go:close}} +``` @@ -494,7 +551,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```csharp +{{#include docs/examples/csharp/wssubscribe/Program.cs:close}} +``` @@ -512,7 +571,7 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 ### 原生连接 - + 同 Websocket 代码样例。 @@ -527,7 +586,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```go +{{#include docs/examples/go/tmq/native/main.go:close}} +``` @@ -539,7 +600,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```csharp +{{#include docs/examples/csharp/subscribe/Program.cs:close}} +``` @@ -579,7 +642,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```go +{{#include docs/examples/go/tmq/ws/main.go}} +``` @@ -591,7 +656,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```csharp +{{#include docs/examples/csharp/wssubscribe/Program.cs}} +``` @@ -632,7 +699,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```go +{{#include docs/examples/go/tmq/native/main.go}} +``` @@ -644,7 +713,9 @@ Rust 连接器创建消费者的参数为 DSN, 可以设置的参数列表请 - +```csharp +{{#include docs/examples/csharp/subscribe/Program.cs}} +``` diff --git a/docs/zh/14-reference/05-connector/20-go.mdx b/docs/zh/14-reference/05-connector/20-go.mdx index c53f681f06..ff10a31124 100644 --- a/docs/zh/14-reference/05-connector/20-go.mdx +++ b/docs/zh/14-reference/05-connector/20-go.mdx @@ -12,16 +12,6 @@ import RequestId from "./_request_id.mdx"; `driver-go` 是 TDengine 的官方 Go 语言连接器,实现了 Go 语言 [database/sql](https://golang.org/pkg/database/sql/) 包的接口。Go 开发人员可以通过它开发存取 TDengine 集群数据的应用软件。 -## 连接方式 - -`driver-go` 提供三种建立连接的方式。 - -* **原生连接**,通过 TDengine 客户端驱动程序(taosc)原生连接 TDengine 实例,支持数据写入、查询、数据订阅、schemaless 接口和参数绑定接口等功能。 -* **REST 连接**,通过 taosAdapter 提供的 HTTP 接口连接 TDengine 实例,不支持 schemaless 和数据订阅等特性。 -* **Websocket 连接**,通过 taosAdapter 提供的 Websocket 接口连接 TDengine 实例,WebSocket 连接实现的功能集合和原生连接有少量不同。 - -连接方式的详细介绍请参考:[连接器建立连接的方式](../../develop/connect/#连接器建立连接的方式) - ## 兼容性 支持最低 Go 版本 1.14,建议使用最新 Go 版本 @@ -74,300 +64,6 @@ REST 连接支持所有能运行 Go 的平台。 **注意**:JSON 类型仅在 tag 中支持。 -## 安装步骤 - -### 安装前准备 - -* 安装 Go 开发环境(Go 1.14 及以上,GCC 4.8.5 及以上) -* 如果使用原生连接器,请安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../#安装客户端驱动) - -配置好环境变量,检查命令: - -* ```go env``` -* ```gcc -v``` - -### 安装连接器 - -1. 使用 `go mod` 命令初始化项目: - - ```text - go mod init taos-demo - ``` - -2. 引入 taosSql : - - ```go - import ( - "database/sql" - _ "github.com/taosdata/driver-go/v3/taosSql" - ) - ``` - -3. 使用 `go mod tidy` 更新依赖包: - - ```text - go mod tidy - ``` - -4. 使用 `go run taos-demo` 运行程序或使用 `go build` 命令编译出二进制文件。 - - ```text - go run taos-demo - go build - ``` - -## 建立连接 - -数据源名称具有通用格式,例如 [PEAR DB](http://pear.php.net/manual/en/package.database.db.intro-dsn.php),但没有类型前缀(方括号表示可选): - -``` text -[username[:password]@][protocol[(address)]]/[dbname][?param1=value1&...¶mN=valueN] -``` - -完整形式的 DSN: - -```text -username:password@protocol(address)/dbname?param=value -``` - - - - -_taosSql_ 通过 cgo 实现了 Go 的 `database/sql/driver` 接口。只需要引入驱动就可以使用 [`database/sql`](https://golang.org/pkg/database/sql/) 的接口。 - -使用 `taosSql` 作为 `driverName` 并且使用一个正确的 [DSN](#DSN) 作为 `dataSourceName`,DSN 支持的参数: - -* cfg 指定 taos.cfg 目录 - -示例: - -```go -package main - -import ( - "database/sql" - "fmt" - - _ "github.com/taosdata/driver-go/v3/taosSql" -) - -func main() { - var taosUri = "root:taosdata@tcp(localhost:6030)/" - taos, err := sql.Open("taosSql", taosUri) - if err != nil { - fmt.Println("failed to connect TDengine, err:", err) - return - } -} -``` - - - - -_taosRestful_ 通过 `http client` 实现了 Go 的 `database/sql/driver` 接口。只需要引入驱动就可以使用[`database/sql`](https://golang.org/pkg/database/sql/)的接口。 - -使用 `taosRestful` 作为 `driverName` 并且使用一个正确的 [DSN](#DSN) 作为 `dataSourceName`,DSN 支持的参数: - -* `disableCompression` 是否接受压缩数据,默认为 true 不接受压缩数据,如果传输数据使用 gzip 压缩设置为 false。 -* `readBufferSize` 读取数据的缓存区大小默认为 4K(4096),当查询结果数据量多时可以适当调大该值。 - -示例: - -```go -package main - -import ( - "database/sql" - "fmt" - - _ "github.com/taosdata/driver-go/v3/taosRestful" -) - -func main() { - var taosUri = "root:taosdata@http(localhost:6041)/" - taos, err := sql.Open("taosRestful", taosUri) - if err != nil { - fmt.Println("failed to connect TDengine, err:", err) - return - } -} -``` - - - - -_taosWS_ 通过 `WebSocket` 实现了 Go 的 `database/sql/driver` 接口。只需要引入驱动(driver-go 最低版本 3.0.2)就可以使用[`database/sql`](https://golang.org/pkg/database/sql/)的接口。 - -使用 `taosWS` 作为 `driverName` 并且使用一个正确的 [DSN](#DSN) 作为 `dataSourceName`,DSN 支持的参数: - -* `writeTimeout` 通过 WebSocket 发送数据的超时时间。 -* `readTimeout` 通过 WebSocket 接收响应数据的超时时间。 - -示例: - -```go -package main - -import ( - "database/sql" - "fmt" - - _ "github.com/taosdata/driver-go/v3/taosWS" -) - -func main() { - var taosUri = "root:taosdata@ws(localhost:6041)/" - taos, err := sql.Open("taosWS", taosUri) - if err != nil { - fmt.Println("failed to connect TDengine, err:", err) - return - } -} -``` - - - - -### 指定 URL 和 Properties 获取连接 - -Go 连接器不支持此功能 - -### 配置参数的优先级 - -Go 连接器不支持此功能 - -## 使用示例 - -### 创建数据库和表 - -```go -{{#include docs/examples/go/demo/query/main.go:create_db_and_table}} -``` - -### 插入数据 - -```go -{{#include docs/examples/go/demo/query/main.go:insert_data}} -``` - -### 查询数据 - -```go -{{#include docs/examples/go/demo/query/main.go:query_data}} -``` - -### 执行带有 reqId 的 SQL - - - -```go -{{#include docs/examples/go/demo/query/main.go:with_reqid}} -``` - -### 通过参数绑定写入数据 - - - - -```go -{{#include docs/examples/go/demo/stmt/main.go}} -``` - - - - -```go -{{#include docs/examples/go/demo/stmtws/main.go}} -``` - - - - -### 无模式写入 - - - - -```go -{{#include docs/examples/go/demo/sml/main.go}} -``` - - - - -```go -{{#include docs/examples/go/demo/smlws/main.go}} -``` - - - - -### 执行带有 reqId 的无模式写入 - -```go -func (s *Schemaless) Insert(lines string, protocol int, precision string, ttl int, reqID int64) error -``` - -可以通过 `common.GetReqID()` 获取唯一 id。 - -### 数据订阅 - -TDengine Go 连接器支持订阅功能,应用 API 如下: - -#### 创建 Topic - -```go -{{#include docs/examples/go/demo/consumer/main.go:create_topic}} -``` - -#### 创建 Consumer - -```go -{{#include docs/examples/go/demo/consumer/main.go:create_consumer}} -``` - -#### 订阅消费数据 - -```go -{{#include docs/examples/go/demo/consumer/main.go:poll_data}} -``` - -#### 指定订阅 Offset - -```go -{{#include docs/examples/go/demo/consumer/main.go:consumer_seek}} -``` - -#### 关闭订阅 - -```go -{{#include docs/examples/go/demo/consumer/main.go:consumer_close}} -``` - -#### 完整示例 - - - - -```go -{{#include docs/examples/go/demo/consumer/main.go}} -``` - - - - -```go -{{#include docs/examples/go/demo/consumerws/main.go}} -``` - - - - -### 更多示例程序 - -* [示例程序](https://github.com/taosdata/driver-go/tree/3.0/examples) -* [视频教程](https://www.taosdata.com/blog/2020/11/11/1951.html)。 - ## 常见问题 1. database/sql 中 stmt(参数绑定)相关接口崩溃 @@ -1065,7 +761,7 @@ type ConfigMap map[string]ConfigValue - `ws.reconnectIntervalMs`:WebSocket 重连间隔时间毫秒,默认 2000。 - `ws.reconnectRetryCount`:WebSocket 重连重试次数,默认 3。 -其他参数请参考:[Consumer 参数列表](../../../develop/tmq/#数据订阅相关参数), 注意TDengine服务端自 3.2.0.0 版本开始消息订阅中的 auto.offset.reset 默认值发生变化。 +其他参数请参考:[Consumer 参数列表](../../../develop/tmq/#创建参数), 注意TDengine服务端自 3.2.0.0 版本开始消息订阅中的 auto.offset.reset 默认值发生变化。 - `func (c *Consumer) Subscribe(topic string, rebalanceCb RebalanceCb) error` - **接口说明**:订阅主题。 @@ -1195,4 +891,6 @@ type TopicPartition struct { ## 附录 -[driver-go 文档](https://pkg.go.dev/github.com/taosdata/driver-go/v3) +* [driver-go 文档](https://pkg.go.dev/github.com/taosdata/driver-go/v3)。 +* [示例程序](https://github.com/taosdata/driver-go/tree/3.0/examples)。 +* [视频教程](https://www.taosdata.com/blog/2020/11/11/1951.html)。 diff --git a/docs/zh/14-reference/05-connector/40-csharp.mdx b/docs/zh/14-reference/05-connector/40-csharp.mdx index ad316d581c..9ac4369c57 100644 --- a/docs/zh/14-reference/05-connector/40-csharp.mdx +++ b/docs/zh/14-reference/05-connector/40-csharp.mdx @@ -70,1144 +70,6 @@ TDengine 不再支持 32 位 Windows 平台。 JSON 类型仅在 tag 中支持。 ::: -## 安装步骤 - -### 安装前准备 - -* 安装 [.NET SDK](https://dotnet.microsoft.com/download) -* [Nuget 客户端](https://docs.microsoft.com/en-us/nuget/install-nuget-client-tools) (可选安装) -* 对于 Native 连接方式,需要安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../#安装客户端驱动),WebSocket 连接方式无需安装。 - -### 安装连接器 - -可以在当前 .NET 项目的路径下,通过 dotnet CLI 添加 Nuget package `TDengine.Connector` 到当前项目。 - -``` bash -dotnet add package TDengine.Connector -``` - -也可以修改当前项目的 `.csproj` 文件,添加如下 ItemGroup。 - -``` XML - - - -``` - -## 建立连接 - - - - -``` csharp -var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); -using (var client = DbDriver.Open(builder)) -{ - Console.WriteLine("connected"); -} -``` - - - - -```csharp -var builder = new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata"); -using (var client = DbDriver.Open(builder)) -{ - Console.WriteLine("connected"); -} -``` - - - -ConnectionStringBuilder 支持的参数如下: -* protocol: 连接协议,可选值为 Native 或 WebSocket,默认为 Native -* host: TDengine 或 taosadapter 运行实例的地址 -* port: TDengine 或 taosadapter 运行实例的端口 - * 当 protocol 为 WebSocket 时 useSSL 为 false 时,port 默认为 6041 - * 当 protocol 为 WebSocket 时 useSSL 为 true 时,port 默认为 443 -* useSSL: 是否使用 SSL 连接,仅当 protocol 为 WebSocket 时有效,默认为 false -* token: 连接 TDengine cloud 的 token,仅当 protocol 为 WebSocket 时有效 -* username: 连接 TDengine 的用户名 -* password: 连接 TDengine 的密码 -* db: 连接 TDengine 的数据库 -* timezone: 解析时间结果的时区,默认为 `TimeZoneInfo.Local`,使用 `TimeZoneInfo.FindSystemTimeZoneById` 方法解析字符串为 `TimeZoneInfo` 对象。 -* connTimeout: WebSocket 连接超时时间,仅当 protocol 为 WebSocket 时有效,默认为 1 分钟,使用 `TimeSpan.Parse` 方法解析字符串为 `TimeSpan` 对象。 -* readTimeout: WebSocket 读超时时间,仅当 protocol 为 WebSocket 时有效,默认为 5 分钟,使用 `TimeSpan.Parse` 方法解析字符串为 `TimeSpan` 对象。 -* writeTimeout: WebSocket 写超时时间,仅当 protocol 为 WebSocket 时有效,默认为 10 秒,使用 `TimeSpan.Parse` 方法解析字符串为 `TimeSpan` 对象。 -* autoReconnect: 是否自动重连(连接器版本 3.1.3 及以上生效),默认为 false -> **注意**:启用自动重连仅对简单执行 SQL 语句以及 无模式写入、数据订阅有效。对于参数绑定无效。自动重连仅对连接建立时通过参数指定数据库有效,对后面的 `use db` 语句切换数据库无效。 - -* reconnectRetryCount: 重连次数(连接器版本 3.1.3 及以上生效),默认为 3 -* reconnectIntervalMs: 重连间隔时间(连接器版本 3.1.3 及以上生效),默认为 2000 - -### 指定 URL 和 Properties 获取连接 - -C# 连接器不支持此功能 - -### 配置参数的优先级 - -C# 连接器不支持此功能 - -## 使用示例 - -### 创建数据库和表 - - - - -```csharp -using System; -using System.Text; -using TDengine.Driver; -using TDengine.Driver.Client; - -namespace NativeQuery -{ - internal class Query - { - public static void Main(string[] args) - { - var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) - { - try - { - client.Exec("create database power"); - client.Exec("CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); - } - catch (Exception e) - { - Console.WriteLine(e.ToString()); - throw; - } - } - } - } -} -``` - - - - -```csharp -using System; -using System.Text; -using TDengine.Driver; -using TDengine.Driver.Client; - -namespace WSQuery -{ - internal class Query - { - public static void Main(string[] args) - { - var builder = new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) - { - try - { - client.Exec("create database power"); - client.Exec("CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); - } - catch (Exception e) - { - Console.WriteLine(e.ToString()); - throw; - } - } - } - } -} -``` - - - - -### 插入数据 - - - - -```csharp -using System; -using System.Text; -using TDengine.Driver; -using TDengine.Driver.Client; - -namespace NativeQuery -{ - internal class Query - { - public static void Main(string[] args) - { - var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) - { - try - { - string insertQuery = - "INSERT INTO " + - "power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " + - "VALUES " + - "('2023-10-03 14:38:05.000', 10.30000, 219, 0.31000) " + - "('2023-10-03 14:38:15.000', 12.60000, 218, 0.33000) " + - "('2023-10-03 14:38:16.800', 12.30000, 221, 0.31000) " + - "power.d1002 USING power.meters TAGS(3, 'California.SanFrancisco') " + - "VALUES " + - "('2023-10-03 14:38:16.650', 10.30000, 218, 0.25000) " + - "power.d1003 USING power.meters TAGS(2,'California.LosAngeles') " + - "VALUES " + - "('2023-10-03 14:38:05.500', 11.80000, 221, 0.28000) " + - "('2023-10-03 14:38:16.600', 13.40000, 223, 0.29000) " + - "power.d1004 USING power.meters TAGS(3,'California.LosAngeles') " + - "VALUES " + - "('2023-10-03 14:38:05.000', 10.80000, 223, 0.29000) " + - "('2023-10-03 14:38:06.500', 11.50000, 221, 0.35000)"; - client.Exec(insertQuery); - } - catch (Exception e) - { - Console.WriteLine(e.ToString()); - throw; - } - } - } - } -} -``` - - - - -```csharp -using System; -using System.Text; -using TDengine.Driver; -using TDengine.Driver.Client; - -namespace WSQuery -{ - internal class Query - { - public static void Main(string[] args) - { - var builder = new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) - { - try - { - string insertQuery = - "INSERT INTO " + - "power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " + - "VALUES " + - "('2023-10-03 14:38:05.000', 10.30000, 219, 0.31000) " + - "('2023-10-03 14:38:15.000', 12.60000, 218, 0.33000) " + - "('2023-10-03 14:38:16.800', 12.30000, 221, 0.31000) " + - "power.d1002 USING power.meters TAGS(3, 'California.SanFrancisco') " + - "VALUES " + - "('2023-10-03 14:38:16.650', 10.30000, 218, 0.25000) " + - "power.d1003 USING power.meters TAGS(2,'California.LosAngeles') " + - "VALUES " + - "('2023-10-03 14:38:05.500', 11.80000, 221, 0.28000) " + - "('2023-10-03 14:38:16.600', 13.40000, 223, 0.29000) " + - "power.d1004 USING power.meters TAGS(3,'California.LosAngeles') " + - "VALUES " + - "('2023-10-03 14:38:05.000', 10.80000, 223, 0.29000) " + - "('2023-10-03 14:38:06.500', 11.50000, 221, 0.35000)"; - client.Exec(insertQuery); - } - catch (Exception e) - { - Console.WriteLine(e.ToString()); - throw; - } - } - } - } -} -``` - - - - -### 查询数据 - - - - -```csharp -using System; -using System.Text; -using TDengine.Driver; -using TDengine.Driver.Client; - -namespace NativeQuery -{ - internal class Query - { - public static void Main(string[] args) - { - var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) - { - try - { - client.Exec("use power"); - string query = "SELECT * FROM meters"; - using (var rows = client.Query(query)) - { - while (rows.Read()) - { - Console.WriteLine($"{((DateTime)rows.GetValue(0)):yyyy-MM-dd HH:mm:ss.fff}, {rows.GetValue(1)}, {rows.GetValue(2)}, {rows.GetValue(3)}, {rows.GetValue(4)}, {Encoding.UTF8.GetString((byte[])rows.GetValue(5))}"); - } - } - } - catch (Exception e) - { - Console.WriteLine(e.ToString()); - throw; - } - } - } - } -} -``` - - - - -```csharp -using System; -using System.Text; -using TDengine.Driver; -using TDengine.Driver.Client; - -namespace WSQuery -{ - internal class Query - { - public static void Main(string[] args) - { - var builder = new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) - { - try - { - client.Exec("use power"); - string query = "SELECT * FROM meters"; - using (var rows = client.Query(query)) - { - while (rows.Read()) - { - Console.WriteLine($"{((DateTime)rows.GetValue(0)):yyyy-MM-dd HH:mm:ss.fff}, {rows.GetValue(1)}, {rows.GetValue(2)}, {rows.GetValue(3)}, {rows.GetValue(4)}, {Encoding.UTF8.GetString((byte[])rows.GetValue(5))}"); - } - } - } - catch (Exception e) - { - Console.WriteLine(e.ToString()); - throw; - } - } - } - } -} -``` - - - - -### 执行带有 reqId 的 SQL - - - - - - -```csharp -using System; -using System.Text; -using TDengine.Driver; -using TDengine.Driver.Client; - -namespace NativeQueryWithReqID -{ - internal abstract class QueryWithReqID - { - public static void Main(string[] args) - { - var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) - { - try - { - client.Exec($"create database if not exists test_db",ReqId.GetReqId()); - } - catch (Exception e) - { - Console.WriteLine(e.ToString()); - throw; - } - } - } - } -} -``` - - - - -```csharp -using System; -using System.Text; -using TDengine.Driver; -using TDengine.Driver.Client; - -namespace WSQueryWithReqID -{ - internal abstract class QueryWithReqID - { - public static void Main(string[] args) - { - var builder = new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) - { - try - { - client.Exec($"create database if not exists test_db",ReqId.GetReqId()); - } - catch (Exception e) - { - Console.WriteLine(e.ToString()); - throw; - } - } - } - } -} -``` - - - - -### 通过参数绑定写入数据 - - - - -```csharp -using System; -using TDengine.Driver; -using TDengine.Driver.Client; - -namespace NativeStmt -{ - internal abstract class NativeStmt - { - public static void Main(string[] args) - { - var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) - { - try - { - client.Exec("create database power"); - client.Exec( - "CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); - using (var stmt = client.StmtInit()) - { - stmt.Prepare( - "Insert into power.d1001 using power.meters tags(2,'California.SanFrancisco') values(?,?,?,?)"); - var ts = new DateTime(2023, 10, 03, 14, 38, 05, 000); - stmt.BindRow(new object[] { ts, (float)10.30000, (int)219, (float)0.31000 }); - stmt.AddBatch(); - stmt.Exec(); - var affected = stmt.Affected(); - Console.WriteLine($"affected rows: {affected}"); - } - } - catch (Exception e) - { - Console.WriteLine(e); - throw; - } - } - } - } -} -``` - - - - -```csharp -using System; -using TDengine.Driver; -using TDengine.Driver.Client; - -namespace WSStmt -{ - internal abstract class WSStmt - { - public static void Main(string[] args) - { - var builder = new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) - { - try - { - client.Exec("create database power"); - client.Exec( - "CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); - using (var stmt = client.StmtInit()) - { - stmt.Prepare( - "Insert into power.d1001 using power.meters tags(2,'California.SanFrancisco') values(?,?,?,?)"); - var ts = new DateTime(2023, 10, 03, 14, 38, 05, 000); - stmt.BindRow(new object[] { ts, (float)10.30000, (int)219, (float)0.31000 }); - stmt.AddBatch(); - stmt.Exec(); - var affected = stmt.Affected(); - Console.WriteLine($"affected rows: {affected}"); - } - } - catch (Exception e) - { - Console.WriteLine(e); - throw; - } - } - } - } -} -``` - - - - -注意:使用 BindRow 需要注意原始 C# 列类型与 TDengine 列类型的需要一一对应,具体对应关系请参考 [TDengine DataType 和 C# DataType](#tdengine-datatype-和-c-datatype)。 - -### 无模式写入 - - - - -```csharp -using TDengine.Driver; -using TDengine.Driver.Client; - -namespace NativeSchemaless -{ - internal class Program - { - public static void Main(string[] args) - { - var builder = - new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) - { - client.Exec("create database sml"); - client.Exec("use sml"); - var influxDBData = - "st,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000"; - client.SchemalessInsert(new string[] { influxDBData }, - TDengineSchemalessProtocol.TSDB_SML_LINE_PROTOCOL, - TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_NANO_SECONDS, 0, ReqId.GetReqId()); - var telnetData = "stb0_0 1626006833 4 host=host0 interface=eth0"; - client.SchemalessInsert(new string[] { telnetData }, - TDengineSchemalessProtocol.TSDB_SML_TELNET_PROTOCOL, - TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS, 0, ReqId.GetReqId()); - var jsonData = - "{\"metric\": \"meter_current\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}"; - client.SchemalessInsert(new string[] { jsonData }, TDengineSchemalessProtocol.TSDB_SML_JSON_PROTOCOL, - TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS, 0, ReqId.GetReqId()); - } - } - } -} -``` - - - - -```csharp -using TDengine.Driver; -using TDengine.Driver.Client; - -namespace WSSchemaless -{ - internal class Program - { - public static void Main(string[] args) - { - var builder = - new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) - { - client.Exec("create database sml"); - client.Exec("use sml"); - var influxDBData = - "st,t1=3i64,t2=4f64,t3=\"t3\" c1=3i64,c3=L\"passit\",c2=false,c4=4f64 1626006833639000000"; - client.SchemalessInsert(new string[] { influxDBData }, - TDengineSchemalessProtocol.TSDB_SML_LINE_PROTOCOL, - TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_NANO_SECONDS, 0, ReqId.GetReqId()); - var telnetData = "stb0_0 1626006833 4 host=host0 interface=eth0"; - client.SchemalessInsert(new string[] { telnetData }, - TDengineSchemalessProtocol.TSDB_SML_TELNET_PROTOCOL, - TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS, 0, ReqId.GetReqId()); - var jsonData = - "{\"metric\": \"meter_current\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}"; - client.SchemalessInsert(new string[] { jsonData }, TDengineSchemalessProtocol.TSDB_SML_JSON_PROTOCOL, - TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS, 0, ReqId.GetReqId()); - } - } - } -} -``` - - - - -### 执行带有 reqId 的无模式写入 - -```csharp -public void SchemalessInsert(string[] lines, TDengineSchemalessProtocol protocol, - TDengineSchemalessPrecision precision, - int ttl, long reqId) -``` - -### 数据订阅 - -#### 创建 Topic - - - - -```csharp -using System; -using System.Text; -using TDengine.Driver; -using TDengine.Driver.Client; - -namespace NativeSubscription -{ - internal class Program - { - public static void Main(string[] args) - { - var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) - { - try - { - client.Exec("create database power"); - client.Exec("CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); - client.Exec("CREATE TOPIC topic_meters as SELECT * from power.meters"); - } - catch (Exception e) - { - Console.WriteLine(e.ToString()); - throw; - } - } - } - } -} -``` - - - - -```csharp -using System; -using System.Text; -using TDengine.Driver; -using TDengine.Driver.Client; - -namespace WSSubscription -{ - internal class Program - { - public static void Main(string[] args) - { - var builder = new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) - { - try - { - client.Exec("create database power"); - client.Exec("CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); - client.Exec("CREATE TOPIC topic_meters as SELECT * from power.meters"); - } - catch (Exception e) - { - Console.WriteLine(e.ToString()); - throw; - } - } - } - } -} -``` - - - - -#### 创建 Consumer - - - - -```csharp -var cfg = new Dictionary() -{ - { "group.id", "group1" }, - { "auto.offset.reset", "latest" }, - { "td.connect.ip", "127.0.0.1" }, - { "td.connect.user", "root" }, - { "td.connect.pass", "taosdata" }, - { "td.connect.port", "6030" }, - { "client.id", "tmq_example" }, - { "enable.auto.commit", "true" }, - { "msg.with.table.name", "false" }, -}; -var consumer = new ConsumerBuilder>(cfg).Build(); -``` - - - - -```csharp -var cfg = new Dictionary() -{ - { "td.connect.type", "WebSocket" }, - { "group.id", "group1" }, - { "auto.offset.reset", "latest" }, - { "td.connect.ip", "localhost" }, - { "td.connect.port", "6041" }, - { "useSSL", "false" }, - { "td.connect.user", "root" }, - { "td.connect.pass", "taosdata" }, - { "client.id", "tmq_example" }, - { "enable.auto.commit", "true" }, - { "msg.with.table.name", "false" }, -}; -var consumer = new ConsumerBuilder>(cfg).Build(); -``` - - - - -consumer 支持的配置参数如下: -* td.connect.type: 连接类型,可选值为 Native 或 WebSocket,默认为 Native -* td.connect.ip: TDengine 或 taosadapter 运行实例的地址 -* td.connect.port: TDengine 或 taosadapter 运行实例的端口 - * 当 td.connect.type 为 WebSocket 且 useSSL 为 false 时,td.connect.port 默认为 6041 - * 当 td.connect.type 为 WebSocket 且 useSSL 为 true 时,td.connect.port 默认为 443 -* useSSL: 是否使用 SSL 连接,仅当 td.connect.type 为 WebSocket 时有效,默认为 false -* token: 连接 TDengine cloud 的 token,仅当 td.connect.type 为 WebSocket 时有效 - -* td.connect.user: 连接 TDengine 的用户名 -* td.connect.pass: 连接 TDengine 的密码 -* group.id: 消费者组 ID -* client.id: 消费者 ID -* enable.auto.commit: 是否自动提交 offset,默认为 true -* auto.commit.interval.ms: 自动提交 offset 的间隔时间,默认为 5000 毫秒 -* auto.offset.reset: 当 offset 不存在时,从哪里开始消费,可选值为 earliest 或 latest,默认为 latest -* msg.with.table.name: 消息是否包含表名 -* ws.message.enableCompression: 是否启用 WebSocket 压缩(dotnet 版本 6 及以上,连接器版本 3.1.1 及以上生效),默认为 false -* ws.autoReconnect: 是否自动重连(连接器版本 3.1.3 及以上生效),默认为 false -* ws.reconnect.retry.count: 重连次数(连接器版本 3.1.3 及以上生效),默认为 3 -* ws.reconnect.interval.ms: 重连间隔时间(连接器版本 3.1.3 及以上生效),默认为 2000 - - -支持订阅结果集 `Dictionary` key 为列名,value 为列值。 - -如果使用 object 接收列值,需要注意: -* 原始 C# 列类型与 TDengine 列类型的需要一一对应,具体对应关系请参考 [TDengine DataType 和 C# DataType](#tdengine-datatype-和-c-datatype)。 -* 列名与 class 属性名一致,并可读写。 -* 明确设置 value 解析器`ConsumerBuilder.SetValueDeserializer(new ReferenceDeserializer());` - -样例如下 - -结果 class - -```csharp - class Result - { - public DateTime ts { get; set; } - public float current { get; set; } - public int voltage { get; set; } - public float phase { get; set; } - } -``` - -设置解析器 - -```csharp -var tmqBuilder = new ConsumerBuilder(cfg); -tmqBuilder.SetValueDeserializer(new ReferenceDeserializer()); -var consumer = tmqBuilder.Build(); -``` - -也可实现自定义解析器,实现 `IDeserializer` 接口并通过`ConsumerBuilder.SetValueDeserializer`方法传入。 - -```csharp - public interface IDeserializer - { - T Deserialize(ITMQRows data, bool isNull, SerializationContext context); - } -``` - -#### 订阅消费数据 - -```csharp -consumer.Subscribe(new List() { "topic_meters" }); -while (true) -{ - using (var cr = consumer.Consume(500)) - { - if (cr == null) continue; - foreach (var message in cr.Message) - { - Console.WriteLine( - $"message {{{((DateTime)message.Value["ts"]).ToString("yyyy-MM-dd HH:mm:ss.fff")}, " + - $"{message.Value["current"]}, {message.Value["voltage"]}, {message.Value["phase"]}}}"); - } - } -} -``` - -#### 指定订阅 Offset - -```csharp -consumer.Assignment.ForEach(a => -{ - Console.WriteLine($"{a}, seek to 0"); - consumer.Seek(new TopicPartitionOffset(a.Topic, a.Partition, 0)); - Thread.Sleep(TimeSpan.FromSeconds(1)); -}); -``` - -#### 提交 Offset - -```csharp -public void Commit(ConsumeResult consumerResult) -public List Commit() -public void Commit(IEnumerable offsets) -``` - -#### 关闭订阅 - -```csharp -consumer.Unsubscribe(); -consumer.Close(); -``` - -#### 完整示例 - - - - -```csharp -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using TDengine.Driver; -using TDengine.Driver.Client; -using TDengine.TMQ; - -namespace NativeSubscription -{ - internal class Program - { - public static void Main(string[] args) - { - var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) - { - try - { - client.Exec("CREATE DATABASE power"); - client.Exec("USE power"); - client.Exec( - "CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); - client.Exec("CREATE TOPIC topic_meters as SELECT * from power.meters"); - var cfg = new Dictionary() - { - { "group.id", "group1" }, - { "auto.offset.reset", "latest" }, - { "td.connect.ip", "127.0.0.1" }, - { "td.connect.user", "root" }, - { "td.connect.pass", "taosdata" }, - { "td.connect.port", "6030" }, - { "client.id", "tmq_example" }, - { "enable.auto.commit", "true" }, - { "msg.with.table.name", "false" }, - }; - var consumer = new ConsumerBuilder>(cfg).Build(); - consumer.Subscribe(new List() { "topic_meters" }); - Task.Run(InsertData); - while (true) - { - using (var cr = consumer.Consume(500)) - { - if (cr == null) continue; - foreach (var message in cr.Message) - { - Console.WriteLine( - $"message {{{((DateTime)message.Value["ts"]).ToString("yyyy-MM-dd HH:mm:ss.fff")}, " + - $"{message.Value["current"]}, {message.Value["voltage"]}, {message.Value["phase"]}}}"); - } - consumer.Commit(); - } - } - } - catch (Exception e) - { - Console.WriteLine(e.ToString()); - throw; - } - } - } - - static void InsertData() - { - var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) - { - while (true) - { - client.Exec("INSERT into power.d1001 using power.meters tags(2,'California.SanFrancisco') values(now,11.5,219,0.30)"); - Task.Delay(1000).Wait(); - } - } - } - } -} -``` - - - - -```csharp -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using TDengine.Driver; -using TDengine.Driver.Client; -using TDengine.TMQ; - -namespace WSSubscription -{ - internal class Program - { - public static void Main(string[] args) - { - var builder = new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) - { - try - { - client.Exec("CREATE DATABASE power"); - client.Exec("USE power"); - client.Exec( - "CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"); - client.Exec("CREATE TOPIC topic_meters as SELECT * from power.meters"); - var cfg = new Dictionary() - { - { "td.connect.type", "WebSocket" }, - { "group.id", "group1" }, - { "auto.offset.reset", "latest" }, - { "td.connect.ip", "localhost" }, - { "td.connect.port", "6041" }, - { "useSSL", "false" }, - { "td.connect.user", "root" }, - { "td.connect.pass", "taosdata" }, - { "client.id", "tmq_example" }, - { "enable.auto.commit", "true" }, - { "msg.with.table.name", "false" }, - }; - var consumer = new ConsumerBuilder>(cfg).Build(); - consumer.Subscribe(new List() { "topic_meters" }); - Task.Run(InsertData); - while (true) - { - using (var cr = consumer.Consume(500)) - { - if (cr == null) continue; - foreach (var message in cr.Message) - { - Console.WriteLine( - $"message {{{((DateTime)message.Value["ts"]).ToString("yyyy-MM-dd HH:mm:ss.fff")}, " + - $"{message.Value["current"]}, {message.Value["voltage"]}, {message.Value["phase"]}}}"); - } - consumer.Commit(); - } - } - } - catch (Exception e) - { - Console.WriteLine(e.ToString()); - throw; - } - } - } - - static void InsertData() - { - var builder = new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata"); - using (var client = DbDriver.Open(builder)) - { - while (true) - { - client.Exec("INSERT into power.d1001 using power.meters tags(2,'California.SanFrancisco') values(now,11.5,219,0.30)"); - Task.Delay(1000).Wait(); - } - } - } - } -} -``` - - - - -### ADO.NET - -C# 连接器支持 ADO.NET 接口,可以通过 ADO.NET 接口连接 TDengine 运行实例,进行数据写入、查询等操作。 - - - - -```csharp -using System; -using TDengine.Data.Client; - -namespace NativeADO -{ - internal class Program - { - public static void Main(string[] args) - { - const string connectionString = "host=localhost;port=6030;username=root;password=taosdata"; - using (var connection = new TDengineConnection(connectionString)) - { - try - { - connection.Open(); - using (var command = new TDengineCommand(connection)) - { - command.CommandText = "create database power"; - command.ExecuteNonQuery(); - connection.ChangeDatabase("power"); - command.CommandText = - "CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"; - command.ExecuteNonQuery(); - command.CommandText = "INSERT INTO " + - "power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " + - "VALUES " + - "(?,?,?,?)"; - var parameters = command.Parameters; - parameters.Add(new TDengineParameter("@0", new DateTime(2023,10,03,14,38,05,000))); - parameters.Add(new TDengineParameter("@1", (float)10.30000)); - parameters.Add(new TDengineParameter("@2", (int)219)); - parameters.Add(new TDengineParameter("@3", (float)0.31000)); - command.ExecuteNonQuery(); - command.Parameters.Clear(); - command.CommandText = "SELECT * FROM meters"; - using (var reader = command.ExecuteReader()) - { - while (reader.Read()) - { - Console.WriteLine( - $"{((DateTime) reader.GetValue(0)):yyyy-MM-dd HH:mm:ss.fff}, {reader.GetValue(1)}, {reader.GetValue(2)}, {reader.GetValue(3)}, {reader.GetValue(4)}, {System.Text.Encoding.UTF8.GetString((byte[]) reader.GetValue(5))}"); - } - } - } - } - catch (Exception e) - { - Console.WriteLine(e); - throw; - } - } - } - } -} -``` - - - - -```csharp -using System; -using TDengine.Data.Client; - -namespace WSADO -{ - internal class Program - { - public static void Main(string[] args) - { - const string connectionString = "protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata"; - using (var connection = new TDengineConnection(connectionString)) - { - try - { - connection.Open(); - using (var command = new TDengineCommand(connection)) - { - command.CommandText = "create database power"; - command.ExecuteNonQuery(); - connection.ChangeDatabase("power"); - command.CommandText = - "CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))"; - command.ExecuteNonQuery(); - command.CommandText = "INSERT INTO " + - "power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " + - "VALUES " + - "(?,?,?,?)"; - var parameters = command.Parameters; - parameters.Add(new TDengineParameter("@0", new DateTime(2023,10,03,14,38,05,000))); - parameters.Add(new TDengineParameter("@1", (float)10.30000)); - parameters.Add(new TDengineParameter("@2", (int)219)); - parameters.Add(new TDengineParameter("@3", (float)0.31000)); - command.ExecuteNonQuery(); - command.Parameters.Clear(); - command.CommandText = "SELECT * FROM meters"; - using (var reader = command.ExecuteReader()) - { - while (reader.Read()) - { - Console.WriteLine( - $"{((DateTime) reader.GetValue(0)):yyyy-MM-dd HH:mm:ss.fff}, {reader.GetValue(1)}, {reader.GetValue(2)}, {reader.GetValue(3)}, {reader.GetValue(4)}, {System.Text.Encoding.UTF8.GetString((byte[]) reader.GetValue(5))}"); - } - } - } - } - catch (Exception e) - { - Console.WriteLine(e); - throw; - } - } - } - } -} -``` - - - - -* 连接参数与[建立连接](#建立连接)中的连接参数一致。 -* TDengineParameter 的 name 需要以 @ 开头,如 @0、@1、@2 等,value 需要 C# 列类型与 TDengine 列类型一一对应,具体对应关系请参考 [TDengine DataType 和 C# DataType](#tdengine-datatype-和-c-datatype)。 - -### 更多示例程序 - -[示例程序](https://github.com/taosdata/taos-connector-dotnet/tree/3.0/examples) - ## API 参考 ### ADO.NET 驱动 @@ -1781,14 +643,14 @@ C# 驱动提供了符合 ADO.NET 标准的 `DbDataReader` 接口,提供了用 创建消费者支持属性列表: -- `useSSL`:是否使用 SSL 连接,默认为 false -- `token`:连接 TDengine cloud 的 token -- `ws.message.enableCompression`:是否启用 WebSocket 压缩,默认为 false -- `ws.autoReconnect`:是否自动重连,默认为 false -- `ws.reconnect.retry.count`:重连次数,默认为 3 -- `ws.reconnect.interval.ms`:重连间隔毫秒时间,默认为 2000 +- `useSSL`:是否使用 SSL 连接,默认为 false。 +- `token`:连接 TDengine cloud 的 token。 +- `ws.message.enableCompression`:是否启用 WebSocket 压缩,默认为 false。 +- `ws.autoReconnect`:是否自动重连,默认为 false。 +- `ws.reconnect.retry.count`:重连次数,默认为 3。 +- `ws.reconnect.interval.ms`:重连间隔毫秒时间,默认为 2000。 -其他参数请参考:[Consumer 参数列表](../../develop/tmq/#数据订阅相关参数), 注意TDengine服务端自 3.2.0.0 版本开始消息订阅中的 auto.offset.reset 默认值发生变化。 +其他参数请参考:[Consumer 参数列表](../../../develop/tmq/#创建参数), 注意TDengine服务端自 3.2.0.0 版本开始消息订阅中的 auto.offset.reset 默认值发生变化。 - `public IConsumer Build()` - **接口说明**:构建消费者。 @@ -1944,4 +806,8 @@ ReferenceDeserializer 用来将消费到的一条记录反序列化为一个对 DictionaryDeserializer 则会将消费到的一行数据反序列化为一个 `Dictionary` 对象,其 key 为列名,值为对象。 -ReferenceDeserializer 和 DictionaryDeserializer 的接口不会被用户直接调用,请参考使用样例。 \ No newline at end of file +ReferenceDeserializer 和 DictionaryDeserializer 的接口不会被用户直接调用,请参考使用样例。 + +## 附录 + +[更多示例程序](https://github.com/taosdata/taos-connector-dotnet/tree/3.0/examples)。 \ No newline at end of file