Merge branch 'docs/wade-3.0' of github.com:taosdata/TDengine into docs/wade-3.0-shibin

This commit is contained in:
menshibin 2024-08-02 15:14:43 +08:00
commit 8bb7cf5926
85 changed files with 5040 additions and 2303 deletions

View File

@ -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
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>

View File

@ -0,0 +1,76 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// TAOS standard API example. The same syntax as MySQL, but only a subset
// to compile: gcc -o CCreateDBDemo CCreateDBDemo.c -ltaos
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "taos.h"
static int DemoCreateDB() {
// ANCHOR: create_db_and_table
int ret_code = -1;
const char *ip = "localhost";
const char *user = "root";
const char *password = "taosdata";
// connect
TAOS *taos = taos_connect(ip, user, password, NULL, 0);
if (taos == NULL) {
printf("failed to connect to server, reason: %s\n", taos_errstr(NULL));
goto end;
}
// create database
TAOS_RES *result = taos_query(taos, "CREATE DATABASE IF NOT EXISTS power");
int code = taos_errno(result);
if (code != 0) {
printf("failed to create database, reason: %s\n", taos_errstr(result));
goto end;
}
taos_free_result(result);
printf("success to create database\n");
// use database
result = taos_query(taos, "USE power");
taos_free_result(result);
// create table
const char* sql = "CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))";
result = taos_query(taos, sql);
code = taos_errno(result);
if (code != 0) {
printf("failed to create table, reason: %s\n", taos_errstr(result));
goto end;
}
taos_free_result(result);
printf("success to create table\n");
ret_code = 0;
end:
// close & clean
taos_close(taos);
taos_cleanup();
return ret_code;
// ANCHOR_END: create_db_and_table
}
int main(int argc, char *argv[]) {
return DemoCreateDB();
}

View File

@ -0,0 +1,76 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// TAOS standard API example. The same syntax as MySQL, but only a subset
// to compile: gcc -o CInsertDataDemo CInsertDataDemo.c -ltaos
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "taos.h"
static int DemoInsertData() {
// ANCHOR: insert_data
int ret_code = -1;
const char *ip = "localhost";
const char *user = "root";
const char *password = "taosdata";
// connect
TAOS *taos = taos_connect(ip, user, password, NULL, 0);
if (taos == NULL) {
printf("failed to connect to server, reason: %s\n", taos_errstr(NULL));
goto end;
}
// use database
TAOS_RES *result = taos_query(taos, "USE power");
taos_free_result(result);
// insert data, please make sure the database and table are already created
const char* sql = "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) ";
result = taos_query(taos, sql);
int code = taos_errno(result);
if (code != 0) {
printf("failed to insert rows, reason: %s\n", taos_errstr(result));
goto end;
}
taos_free_result(result);
// you can check affectedRows here
int rows = taos_affected_rows(result);
printf("success to insert %d rows\n", rows);
ret_code = 0;
end:
// close & clean
taos_close(taos);
taos_cleanup();
return ret_code;
// ANCHOR_END: insert_data
}
int main(int argc, char *argv[]) {
return DemoInsertData();
}

View File

@ -0,0 +1,82 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// TAOS standard API example. The same syntax as MySQL, but only a subset
// to compile: gcc -o CQueryDataDemo CQueryDataDemo.c -ltaos
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "taos.h"
static int DemoQueryData() {
// ANCHOR: query_data
int ret_code = -1;
const char *ip = "localhost";
const char *user = "root";
const char *password = "taosdata";
// connect
TAOS *taos = taos_connect(ip, user, password, NULL, 0);
if (taos == NULL) {
printf("failed to connect to server, reason: %s\n", taos_errstr(NULL));
goto end;
}
// use database
TAOS_RES *result = taos_query(taos, "USE power");
taos_free_result(result);
// query data, please make sure the database and table are already created
const char* sql = "SELECT * FROM power.meters";
result = taos_query(taos, sql);
int code = taos_errno(result);
if (code != 0) {
printf("failed to select, reason: %s\n", taos_errstr(result));
goto end;
}
TAOS_ROW row = NULL;
int rows = 0;
int num_fields = taos_field_count(result);
TAOS_FIELD *fields = taos_fetch_fields(result);
printf("fields: %d\n", num_fields);
printf("sql: %s, result:\n", sql);
// fetch the records row by row
while ((row = taos_fetch_row(result))) {
char temp[1024] = {0};
rows++;
taos_print_row(temp, row, fields, num_fields);
printf("%s\n", temp);
}
printf("total rows: %d\n", rows);
taos_free_result(result);
ret_code = 0;
end:
// close & clean
taos_close(taos);
taos_cleanup();
return ret_code;
// ANCHOR_END: query_data
}
int main(int argc, char *argv[]) {
return DemoQueryData();
}

View File

@ -0,0 +1,93 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// TAOS standard API example. The same syntax as MySQL, but only a subset
// to compile: gcc -o CWithReqIdDemo CWithReqIdDemo.c -ltaos
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "taos.h"
static int DemoWithReqId() {
// ANCHOR: with_reqid
int ret_code = -1;
const char *ip = "localhost";
const char *user = "root";
const char *password = "taosdata";
// connect
TAOS *taos = taos_connect(ip, user, password, NULL, 0);
if (taos == NULL) {
printf("failed to connect to server, reason: %s\n", taos_errstr(NULL));
goto end;
}
// create database
TAOS_RES *result = taos_query_with_reqid(taos, "CREATE DATABASE IF NOT EXISTS power", 1L);
int code = taos_errno(result);
if (code != 0) {
printf("failed to create database, reason: %s\n", taos_errstr(result));
taos_free_result(result);
goto end;
}
taos_free_result(result);
printf("success to create database\n");
// use database
result = taos_query_with_reqid(taos, "USE power", 2L);
taos_free_result(result);
// query data
const char* sql = "SELECT * FROM power.meters";
result = taos_query_with_reqid(taos, sql, 3L);
code = taos_errno(result);
if (code != 0) {
printf("failed to select, reason: %s\n", taos_errstr(result));
goto end;
}
TAOS_ROW row = NULL;
int rows = 0;
int num_fields = taos_field_count(result);
TAOS_FIELD *fields = taos_fetch_fields(result);
printf("fields: %d\n", num_fields);
printf("sql: %s, result:\n", sql);
// fetch the records row by row
while ((row = taos_fetch_row(result))) {
char temp[1024] = {0};
rows++;
taos_print_row(temp, row, fields, num_fields);
printf("%s\n", temp);
}
printf("total rows: %d\n", rows);
taos_free_result(result);
ret_code = 0;
end:
// close & clean
taos_close(taos);
taos_cleanup();
return ret_code;
// ANCHOR_END: with_reqid
}
int main(int argc, char *argv[]) {
return DemoWithReqId();
}

View File

@ -3,16 +3,34 @@ using TDengine.Driver.Client;
namespace TDengineExample
{
internal class ConnectExample
{
// ANCHOR: main
static void Main(String[] args)
{
try
{
// 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
}
}

View File

@ -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

View File

@ -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
}
}

View File

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="TDengine.Connector" Version="3.1.*" />
</ItemGroup>
</Project>

View File

@ -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"
}
}
}
}
}

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">/root/.nuget/packages/</NuGetPackageRoot>
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">/root/.nuget/packages/</NuGetPackageFolders>
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.8.0</NuGetToolVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<SourceRoot Include="/root/.nuget/packages/" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />

View File

@ -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"
}
}
}
}

View File

@ -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": []
}

View File

@ -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"}}

View File

@ -0,0 +1 @@
17225691407520754

View File

@ -0,0 +1 @@
17225689181017775

View File

@ -6,23 +6,52 @@ namespace TDengineExample
internal class OptsJsonExample
{
public static void Main(string[] args)
{
// 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
{
var builder =
new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata");
new ConnectionStringBuilder(
$"protocol=WebSocket;host={host};port=6041;username=root;password=taosdata");
using (var client = DbDriver.Open(builder))
{
client.Exec("CREATE DATABASE test WAL_RETENTION_PERIOD 3600");
client.Exec("use test");
string[] lines =
{
"[{\"metric\": \"meters.current\", \"timestamp\": 1648432611249, \"value\": 10.3, \"tags\": {\"location\": \"California.SanFrancisco\", \"groupid\": 2}}," +
" {\"metric\": \"meters.voltage\", \"timestamp\": 1648432611249, \"value\": 219, \"tags\": {\"location\": \"California.LosAngeles\", \"groupid\": 1}}, " +
"{\"metric\": \"meters.current\", \"timestamp\": 1648432611250, \"value\": 12.6, \"tags\": {\"location\": \"California.SanFrancisco\", \"groupid\": 2}}," +
" {\"metric\": \"meters.voltage\", \"timestamp\": 1648432611250, \"value\": 221, \"tags\": {\"location\": \"California.LosAngeles\", \"groupid\": 1}}]"
};
client.SchemalessInsert(lines, TDengineSchemalessProtocol.TSDB_SML_JSON_PROTOCOL,
// 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
}
}
}

View File

@ -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())

View File

@ -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
{
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);
var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata");
using (var client = DbDriver.Open(builder))
{
CreateDatabaseAndTable(client);
InsertData(client);
QueryData(client);
}
}
catch (TDengineError e)
{
// handle TDengine error
Console.WriteLine(e.Message);
throw;
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
// 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
}
}
}

View File

@ -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
{
client.Exec($"create database power");
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");
// 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 (TDengineError e)
{
// handle TDengine error
Console.WriteLine(e.Message);
throw;
}
catch (Exception e)
{
Console.WriteLine(e);
// handle other exceptions
Console.WriteLine(e.Message);
throw;
}
}
}
// ANCHOR_END: main
}
}

View File

@ -1,5 +1,4 @@

using TDengine.Driver;
using TDengine.Driver;
using TDengine.Driver.Client;
using TDengine.TMQ;
@ -8,39 +7,115 @@ namespace TMQExample
internal class SubscribeDemo
{
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");
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 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");
"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("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)");
Task.Delay(1000).Wait();
}
}
}
static IConsumer<Dictionary<string, object>> CreateConsumer()
{
// ANCHOR: create_consumer
// consumer config
var cfg = new Dictionary<string, string>()
{
{ "group.id", "group1" },
{ "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" },
{ "td.connect.port", "6030" },
{ "client.id", "tmq_example" },
{ "enable.auto.commit", "true" },
{ "msg.with.table.name", "false" },
};
var consumer = new ConsumerBuilder<Dictionary<string, object>>(cfg).Build();
consumer.Subscribe(new List<string>() { "topic_meters" });
Task.Run(InsertData);
while (true)
IConsumer<Dictionary<string, object>> consumer = null!;
try
{
using (var cr = consumer.Consume(500))
// create consumer
consumer = new ConsumerBuilder<Dictionary<string, object>>(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<Dictionary<string, object>> consumer)
{
// ANCHOR: subscribe
try
{
// subscribe
consumer.Subscribe(new List<string>() { "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"]}}}");
@ -48,26 +123,106 @@ namespace TMQExample
}
}
}
catch (TDengineError e)
{
// handle TDengine error
Console.WriteLine(e.Message);
throw;
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
// handle other exceptions
Console.WriteLine(e.Message);
throw;
}
// ANCHOR_END: subscribe
}
static void Seek(IConsumer<Dictionary<string, object>> 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<Dictionary<string, object>> 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<TopicPartitionOffset>
{
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 InsertData()
static void Close(IConsumer<Dictionary<string, object>> consumer)
{
var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata");
using (var client = DbDriver.Open(builder))
// ANCHOR: close
try
{
while (true)
// unsubscribe
consumer.Unsubscribe();
// close consumer
consumer.Close();
}
catch (TDengineError e)
{
client.Exec("INSERT into power.d1001 using power.meters tags(2,'California.SanFrancisco') values(now,11.5,219,0.30)");
Task.Delay(1000).Wait();
// handle TDengine error
Console.WriteLine(e.Message);
throw;
}
catch (Exception e)
{
// handle other exceptions
Console.WriteLine(e.Message);
throw;
}
// ANCHOR_END: close
}
}
}
}
}

View File

@ -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");
try
{
// 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
}
}

View File

@ -1,4 +1,5 @@
using System;
using System.Text;
using TDengine.Driver;
using TDengine.Driver.Client;
@ -7,40 +8,160 @@ namespace Examples
public class WSInsertExample
{
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))");
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);
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))
{
CreateDatabaseAndTable(client);
InsertData(client);
QueryData(client);
QueryWithReqId(client);
}
}
catch (TDengineError e)
{
// handle TDengine error
Console.WriteLine(e.Message);
throw;
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
// 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
}
}
}

View File

@ -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())

View File

@ -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
{
client.Exec($"create database power");
var builder = new ConnectionStringBuilder($"protocol=WebSocket;host={host};port=6041;useSSL=false;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");
// 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 (TDengineError e)
{
// handle TDengine error
Console.WriteLine(e.Message);
throw;
}
catch (Exception e)
{
Console.WriteLine(e);
// handle other exceptions
Console.WriteLine(e.Message);
throw;
}
}
}
// ANCHOR_END: main
}
}

View File

@ -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
}
}

View File

@ -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"
}
}
}
}

View File

@ -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": []
}

View File

@ -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"}}

View File

@ -0,0 +1 @@
17225691310239873

View File

@ -0,0 +1 @@
17225689180359712

View File

@ -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"
}
}
}
}
}

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">/root/.nuget/packages/</NuGetPackageRoot>
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">/root/.nuget/packages/</NuGetPackageFolders>
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.8.0</NuGetToolVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<SourceRoot Include="/root/.nuget/packages/" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />

View File

@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="TDengine.Connector" Version="3.1.*" />
</ItemGroup>
</Project>

View File

@ -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<Dictionary<string, object>> CreateConsumer()
{
// ANCHOR: create_consumer
// consumer config
var cfg = new Dictionary<string, string>()
{
{"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<Dictionary<string, object>> consumer = null!;
try
{
// create consumer
consumer = new ConsumerBuilder<Dictionary<string, object>>(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<Dictionary<string, object>> consumer)
{
// ANCHOR: subscribe
try
{
// subscribe
consumer.Subscribe(new List<string>() { "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<Dictionary<string, object>> 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<Dictionary<string, object>> 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<TopicPartitionOffset>
{
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<Dictionary<string, object>> 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
}
}
}

View File

@ -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"
}
}
}
}

View File

@ -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": []
}

View File

@ -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"}}

View File

@ -0,0 +1 @@
17225691490262111

View File

@ -0,0 +1 @@
17225689180408669

View File

@ -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"
}
}
}
}
}

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">/root/.nuget/packages/</NuGetPackageRoot>
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">/root/.nuget/packages/</NuGetPackageFolders>
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.8.0</NuGetToolVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<SourceRoot Include="/root/.nuget/packages/" />
</ItemGroup>
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<PkgTDengine_Connector Condition=" '$(PkgTDengine_Connector)' == '' ">/root/.nuget/packages/tdengine.connector/3.1.3</PkgTDengine_Connector>
</PropertyGroup>
</Project>

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />

View File

@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="TDengine.Connector" Version="3.1.*" GeneratePathProperty="true" />
</ItemGroup>
</Project>

View File

@ -13,6 +13,6 @@ func main() {
if err != nil {
log.Fatalln("failed to connect, err:", err)
} else {
fmt.Println("connected")
fmt.Println("Connected")
}
}

View File

@ -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".

View File

@ -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
}

View File

@ -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".

View File

@ -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()
}

View File

@ -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
)

View File

@ -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=

View File

@ -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, &current, &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)
}
}

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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, &current, &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
}

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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{}{}
}()
}

View File

@ -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{}{}
}()
}

View File

@ -3,7 +3,7 @@ use taos::*;
#[tokio::main]
async fn main() -> Result<(), Error> {
#[allow(unused_variables)]
let taos = TaosBuilder::from_dsn("taos://")?.build()?;
println!("Connected");
let taos = TaosBuilder::from_dsn("taos://localhost:6030")?.build()?;
println!("Connected to localhost with native connection successfully.");
Ok(())
}

View File

@ -7,48 +7,50 @@ async fn main() -> anyhow::Result<()> {
let taos = builder.build()?;
// ANCHOR: create_db_and_table
let db = "power";
// create database
taos.exec_many([
format!("DROP DATABASE IF EXISTS `{db}`"),
format!("CREATE DATABASE `{db}`"),
// ANCHOR: create_db_and_table
let db = "power";
// create database
taos.exec_many([
format!("CREATE DATABASE IF NOT EXISTS `{db}`"),
format!("USE `{db}`"),
])
.await?;
])
.await?;
println!("Create database power successfully.");
// create table
taos.exec_many([
// create super table
// create super table
taos.exec_many([
"CREATE TABLE `meters` (`ts` TIMESTAMP, `current` FLOAT, `voltage` INT, `phase` FLOAT) \
TAGS (`groupid` INT, `location` BINARY(24))",
]).await?;
// ANCHOR_END: create_db_and_table
]).await?;
println!("Create stable meters successfully.");
// ANCHOR: insert_data
let inserted = taos.exec("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) ").await?;
// ANCHOR_END: create_db_and_table
println!("inserted: {} rows", inserted);
// ANCHOR_END: insert_data
// ANCHOR: insert_data
let inserted = taos.exec("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) ").await?;
// ANCHOR: query_data
let mut result = taos.query("SELECT * FROM power.meters").await?;
println!("inserted: {} rows to power.meters successfully.", inserted);
// ANCHOR_END: insert_data
for field in result.fields() {
// ANCHOR: query_data
// query data, make sure the database and table are created before
let mut result = taos.query("SELECT ts, current, location FROM power.meters limit 100").await?;
for field in result.fields() {
println!("got field: {}", field.name());
}
}
let mut rows = result.rows();
let mut nrows = 0;
while let Some(row) = rows.try_next().await? {
let mut rows = result.rows();
let mut nrows = 0;
while let Some(row) = rows.try_next().await? {
for (col, (name, value)) in row.enumerate() {
println!(
"[{}] got value in col {} (named `{:>8}`): {}",
@ -56,11 +58,11 @@ async fn main() -> anyhow::Result<()> {
);
}
nrows += 1;
}
// ANCHOR_END: query_data
}
// ANCHOR_END: query_data
// ANCHOR: query_with_req_id
let result = taos.query_with_req_id("SELECT * FROM power.meters", 0).await?;
// ANCHOR_END: query_with_req_id
// ANCHOR: query_with_req_id
let result = taos.query_with_req_id("SELECT ts, current, location FROM power.meters limit 1", 1).await?;
// ANCHOR_END: query_with_req_id
}

View File

@ -17,8 +17,6 @@ async fn put() -> anyhow::Result<()> {
let db = "power";
client.exec(format!("drop database if exists {db}")).await?;
client
.exec(format!("create database if not exists {db}"))
.await?;
@ -44,7 +42,7 @@ async fn put() -> anyhow::Result<()> {
// SchemalessProtocol::Telnet
let data = [
"meters.current 1648432611249 10.3 location=California.SanFrancisco group=2",
"metric_telnet 1648432611249 10.3 location=California.SanFrancisco group=2",
]
.map(String::from)
.to_vec();
@ -60,7 +58,7 @@ async fn put() -> anyhow::Result<()> {
// SchemalessProtocol::Json
let data = [
r#"[{"metric": "meters.current", "timestamp": 1681345954000, "value": 10.3, "tags": {"location": "California.SanFrancisco", "groupid": 2}}, {"metric": "meters.voltage", "timestamp": 1648432611249, "value": 219, "tags": {"location": "California.LosAngeles", "groupid": 1}}, {"metric": "meters.current", "timestamp": 1648432611250, "value": 12.6, "tags": {"location": "California.SanFrancisco", "groupid": 2}}, {"metric": "meters.voltage", "timestamp": 1648432611250, "value": 221, "tags": {"location": "California.LosAngeles", "groupid": 1}}]"#
r#"[{"metric": "metric_json", "timestamp": 1681345954000, "value": 10.3, "tags": {"location": "California.SanFrancisco", "groupid": 2}}, {"metric": "meters.voltage", "timestamp": 1648432611249, "value": 219, "tags": {"location": "California.LosAngeles", "groupid": 1}}, {"metric": "meters.current", "timestamp": 1648432611250, "value": 12.6, "tags": {"location": "California.SanFrancisco", "groupid": 2}}, {"metric": "meters.voltage", "timestamp": 1648432611250, "value": 221, "tags": {"location": "California.LosAngeles", "groupid": 1}}]"#
]
.map(String::from)
.to_vec();
@ -74,7 +72,5 @@ async fn put() -> anyhow::Result<()> {
.build()?;
assert_eq!(client.put(&sml_data).await?, ());
client.exec(format!("drop database if exists {db}")).await?;
Ok(())
}

View File

@ -17,6 +17,8 @@ async fn main() -> anyhow::Result<()> {
for i in 0..NUM_TABLES {
let table_name = format!("d{}", i);
let tags = vec![Value::VarChar("California.SanFransico".into()), Value::Int(2)];
// set table name and tags for the prepared statement.
stmt.set_tbname_tags(&table_name, &tags).await?;
for j in 0..NUM_ROWS {
let values = vec![
@ -25,13 +27,16 @@ async fn main() -> anyhow::Result<()> {
ColumnView::from_ints(vec![219 + j as i32]),
ColumnView::from_floats(vec![0.31 + j as f32]),
];
// bind values to the prepared statement.
stmt.bind(&values).await?;
}
stmt.add_batch().await?;
}
// execute.
let rows = stmt.execute().await?;
assert_eq!(rows, NUM_TABLES * NUM_ROWS);
Ok(())
}

View File

@ -3,7 +3,7 @@ use taos::*;
#[tokio::main]
async fn main() -> Result<(), Error> {
#[allow(unused_variables)]
let taos = TaosBuilder::from_dsn("taos://")?.build()?;
println!("Connected");
let taos = TaosBuilder::from_dsn("taos+ws://localhost:6041")?.build()?;
println!("Connected to localhost with websocket connection successfully.");
Ok(())
}

View File

@ -0,0 +1,76 @@
use taos_query::common::SchemalessPrecision;
use taos_query::common::SchemalessProtocol;
use taos_query::common::SmlDataBuilder;
use crate::AsyncQueryable;
use crate::AsyncTBuilder;
use crate::TaosBuilder;
async fn put() -> anyhow::Result<()> {
std::env::set_var("RUST_LOG", "taos=debug");
pretty_env_logger::init();
let dsn =
std::env::var("TDENGINE_ClOUD_DSN").unwrap_or("https://localhost:6041".to_string());
log::debug!("dsn: {:?}", &dsn);
let client = TaosBuilder::from_dsn(dsn)?.build().await?;
let db = "power";
client
.exec(format!("create database if not exists {db}"))
.await?;
// should specify database before insert
client.exec(format!("use {db}")).await?;
// SchemalessProtocol::Line
let data = [
"meters,groupid=2,location=California.SanFrancisco current=10.3000002f64,voltage=219i32,phase=0.31f64 1626006833639000000",
]
.map(String::from)
.to_vec();
let sml_data = SmlDataBuilder::default()
.protocol(SchemalessProtocol::Line)
.precision(SchemalessPrecision::Millisecond)
.data(data.clone())
.ttl(1000)
.req_id(100u64)
.build()?;
assert_eq!(client.put(&sml_data).await?, ());
// SchemalessProtocol::Telnet
let data = [
"metric_telnet 1648432611249 10.3 location=California.SanFrancisco group=2",
]
.map(String::from)
.to_vec();
let sml_data = SmlDataBuilder::default()
.protocol(SchemalessProtocol::Telnet)
.precision(SchemalessPrecision::Millisecond)
.data(data.clone())
.ttl(1000)
.req_id(200u64)
.build()?;
assert_eq!(client.put(&sml_data).await?, ());
// SchemalessProtocol::Json
let data = [
r#"[{"metric": "metric_json", "timestamp": 1681345954000, "value": 10.3, "tags": {"location": "California.SanFrancisco", "groupid": 2}}, {"metric": "meters.voltage", "timestamp": 1648432611249, "value": 219, "tags": {"location": "California.LosAngeles", "groupid": 1}}, {"metric": "meters.current", "timestamp": 1648432611250, "value": 12.6, "tags": {"location": "California.SanFrancisco", "groupid": 2}}, {"metric": "meters.voltage", "timestamp": 1648432611250, "value": 221, "tags": {"location": "California.LosAngeles", "groupid": 1}}]"#
]
.map(String::from)
.to_vec();
let sml_data = SmlDataBuilder::default()
.protocol(SchemalessProtocol::Json)
.precision(SchemalessPrecision::Millisecond)
.data(data.clone())
.ttl(1000)
.req_id(300u64)
.build()?;
assert_eq!(client.put(&sml_data).await?, ());
Ok(())
}

View File

@ -0,0 +1,42 @@
use taos::*;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let taos = TaosBuilder::from_dsn("ws://")?.build().await?;
taos.exec("DROP DATABASE IF EXISTS power").await?;
taos.create_database("power").await?;
taos.use_database("power").await?;
taos.exec("CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)").await?;
let mut stmt = Stmt::init(&taos).await?;
stmt.prepare("INSERT INTO ? USING meters TAGS(?, ?) VALUES(?, ?, ?, ?)").await?;
const NUM_TABLES: usize = 10;
const NUM_ROWS: usize = 10;
for i in 0..NUM_TABLES {
let table_name = format!("d{}", i);
let tags = vec![Value::VarChar("California.SanFransico".into()), Value::Int(2)];
// set table name and tags for the prepared statement.
stmt.set_tbname_tags(&table_name, &tags).await?;
for j in 0..NUM_ROWS {
let values = vec![
ColumnView::from_millis_timestamp(vec![1648432611249 + j as i64]),
ColumnView::from_floats(vec![10.3 + j as f32]),
ColumnView::from_ints(vec![219 + j as i32]),
ColumnView::from_floats(vec![0.31 + j as f32]),
];
// bind values to the prepared statement.
stmt.bind(&values).await?;
}
stmt.add_batch().await?;
}
// execute.
let rows = stmt.execute().await?;
assert_eq!(rows, NUM_TABLES * NUM_ROWS);
Ok(())
}

View File

@ -0,0 +1,163 @@
use std::time::Duration;
use std::str::FromStr;
use taos::*;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
pretty_env_logger::formatted_timed_builder()
.filter_level(log::LevelFilter::Info)
.init();
use taos_query::prelude::*;
let dsn = "ws://localhost:6041".to_string();
log::info!("dsn: {}", dsn);
let mut dsn = Dsn::from_str(&dsn)?;
let taos = TaosBuilder::from_dsn(&dsn)?.build().await?;
// prepare database and table
taos.exec_many([
"drop topic if exists topic_meters",
"drop database if exists power",
"create database if not exists power WAL_RETENTION_PERIOD 86400",
"use power",
"CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))",
"create table if not exists power.d001 using power.meters tags(1,'location')",
])
.await?;
taos.exec_many([
"drop database if exists db2",
"create database if not exists db2 wal_retention_period 3600",
"use db2",
])
.await?;
// ANCHOR: create_topic
taos.exec_many([
"CREATE TOPIC IF NOT EXISTS topic_meters AS SELECT ts, current, voltage, phase, groupid, location FROM power.meters",
])
.await?;
// ANCHOR_END: create_topic
// ANCHOR: create_consumer
dsn.params.insert("group.id".to_string(), "abc".to_string());
dsn.params.insert("auto.offset.reset".to_string(), "earliest".to_string());
let builder = TmqBuilder::from_dsn(&dsn)?;
let mut consumer = builder.build().await?;
// ANCHOR_END: create_consumer
// ANCHOR: subscribe
consumer.subscribe(["topic_meters"]).await?;
// ANCHOR_END: subscribe
// ANCHOR: consume
{
let mut stream = consumer.stream_with_timeout(Timeout::from_secs(1));
while let Some((offset, message)) = stream.try_next().await? {
let topic: &str = offset.topic();
let database = offset.database();
let vgroup_id = offset.vgroup_id();
log::debug!(
"topic: {}, database: {}, vgroup_id: {}",
topic,
database,
vgroup_id
);
match message {
MessageSet::Meta(meta) => {
log::info!("Meta");
let raw = meta.as_raw_meta().await?;
taos.write_raw_meta(&raw).await?;
let json = meta.as_json_meta().await?;
let sql = json.to_string();
if let Err(err) = taos.exec(sql).await {
println!("maybe error: {}", err);
}
}
MessageSet::Data(data) => {
log::info!("Data");
while let Some(data) = data.fetch_raw_block().await? {
log::debug!("data: {:?}", data);
}
}
MessageSet::MetaData(meta, data) => {
log::info!("MetaData");
let raw = meta.as_raw_meta().await?;
taos.write_raw_meta(&raw).await?;
let json = meta.as_json_meta().await?;
let sql = json.to_string();
if let Err(err) = taos.exec(sql).await {
println!("maybe error: {}", err);
}
while let Some(data) = data.fetch_raw_block().await? {
log::debug!("data: {:?}", data);
}
}
}
consumer.commit(offset).await?;
}
}
// ANCHOR_END: consume
// ANCHOR: assignments
let assignments = consumer.assignments().await.unwrap();
log::info!("assignments: {:?}", assignments);
// ANCHOR_END: assignments
// seek offset
for topic_vec_assignment in assignments {
let topic = &topic_vec_assignment.0;
let vec_assignment = topic_vec_assignment.1;
for assignment in vec_assignment {
let vgroup_id = assignment.vgroup_id();
let current = assignment.current_offset();
let begin = assignment.begin();
let end = assignment.end();
log::debug!(
"topic: {}, vgroup_id: {}, current offset: {} begin {}, end: {}",
topic,
vgroup_id,
current,
begin,
end
);
// ANCHOR: seek_offset
let res = consumer.offset_seek(topic, vgroup_id, end).await;
if res.is_err() {
log::error!("seek offset error: {:?}", res);
let a = consumer.assignments().await.unwrap();
log::error!("assignments: {:?}", a);
}
// ANCHOR_END: seek_offset
}
let topic_assignment = consumer.topic_assignment(topic).await;
log::debug!("topic assignment: {:?}", topic_assignment);
}
// after seek offset
let assignments = consumer.assignments().await.unwrap();
log::info!("after seek offset assignments: {:?}", assignments);
// ANCHOR: unsubscribe
consumer.unsubscribe().await;
// ANCHOR_END: unsubscribe
tokio::time::sleep(Duration::from_secs(1)).await;
taos.exec_many([
"drop database db2",
"drop topic topic_meters",
"drop database power",
])
.await?;
Ok(())
}

View File

@ -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
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
@ -321,20 +321,120 @@ Java 连接器建立连接的参数有 URL 和 Properties。
TDengine 的 JDBC URL 规范格式为:
`jdbc:[TAOS|TAOS-RS]://[host_name]:[port]/[database_name]?[user={user}|&password={password}|&charset={charset}|&cfgdir={config_dir}|&locale={locale}|&timezone={timezone}]`
URL 和 Properties 的详细参数说明和如何使用详见 [API 说明](../../reference/connector/java/#url-规范)
URL 和 Properties 的详细参数说明和如何使用详见 [url 规范](../../reference/connector/java/#url-规范)
</TabItem>
<TabItem label="Python" value="python">
</TabItem>
<TabItem label="Go" value="go">
数据源名称具有通用格式,例如 [PEAR DB](http://pear.php.net/manual/en/package.database.db.intro-dsn.php),但没有类型前缀(方括号表示可选):
``` text
[username[:password]@][protocol[(address)]]/[dbname][?param1=value1&...&paramN=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` 读取数据的缓存区大小默认为 4K4096当查询结果数据量多时可以适当调大该值。
- `token` 连接云服务时使用的 token。
- `skipVerify` 是否跳过证书验证,默认为 false 不跳过证书验证,如果连接的是不安全的服务设置为 true。
WebSocket 连接:
- `enableCompression` 是否发送压缩数据,默认为 false 不发送压缩数据,如果传输数据使用压缩设置为 true。
- `readTimeout` 读取数据的超时时间,默认为 5m。
- `writeTimeout` 写入数据的超时时间,默认为 10s。
</TabItem>
<TabItem label="Rust" value="rust">
Rust 连接器使用 DSN 来创建连接, DSN 描述字符串基本结构如下:
```text
<driver>[+<protocol>]://[[<username>:<password>@]<host>:<port>][/<database>][?<p1>=<v1>[&<p2>=<v2>]]
|------|------------|---|-----------|-----------|------|------|------------|-----------------------|
|driver| protocol | | username | password | host | port | database | params |
```
DSN 的详细说明和如何使用详见 [连接功能](../../reference/connector/rust/#连接功能)
</TabItem>
<TabItem label="C#" value="csharp">
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。
</TabItem>
<TabItem label="R" value="r">
</TabItem>
<TabItem label="C" value="c">
使用客户端驱动访问 TDengine 集群的基本过程为:建立连接、查询和写入、关闭连接、清除资源。
下面为建立连接的示例代码,其中省略了查询和写入部分,展示了如何建立连接、关闭连接以及清除资源。
```c
TAOS *taos = taos_connect("localhost:6030", "root", "taosdata", NULL, 0);
if (taos == NULL) {
printf("failed to connect to server, reason:%s\n", "null taos" /*taos_errstr(taos)*/);
exit(1);
}
/* put your code here for read and write */
taos_close(taos);
taos_cleanup();
```
在上面的示例代码中, `taos_connect()` 建立到客户端程序所在主机的 6030 端口的连接,`taos_close()`关闭当前连接,`taos_cleanup()`清除客户端驱动所申请和使用的资源。
:::note
- 如未特别说明,当 API 的返回值是整数时_0_ 代表成功,其它是代表失败原因的错误码,当返回值是指针时, _NULL_ 表示失败。
- 所有的错误码以及对应的原因描述在 `taoserror.h` 文件中。
:::
</TabItem>
<TabItem label="PHP" value="php">
</TabItem>
@ -345,7 +445,7 @@ URL 和 Properties 的详细参数说明和如何使用详见 [API 说明](../..
下面是各语言连接器建立 Websocket 连接代码样例。演示了如何使用 Websocket 连接方式连接到 TDengine 数据库,并对连接设定一些参数。整个过程主要涉及到数据库连接的建立和异常处理。
<Tabs defaultValue="java" groupId="lang">
<TabItem label="Java" value="java">
<TabItem label="Java" value="java">
```java
{{#include docs/examples/java/src/main/java/com/taos/example/WSConnectExample.java:main}}
```
@ -356,10 +456,14 @@ URL 和 Properties 的详细参数说明和如何使用详见 [API 说明](../..
```
</TabItem>
<TabItem label="Go" value="go">
<ConnGo />
```go
{{#include docs/examples/go/connect/wsexample/main.go}}
```
</TabItem>
<TabItem label="Rust" value="rust">
<ConnRust />
```rust
{{#include docs/examples/rust/restexample/examples/connect.rs}}
```
</TabItem>
<TabItem label="Node.js" value="node">
```js
@ -367,7 +471,9 @@ URL 和 Properties 的详细参数说明和如何使用详见 [API 说明](../..
```
</TabItem>
<TabItem label="C#" value="csharp">
<ConnCSNative />
```csharp
{{#include docs/examples/csharp/wsConnect/Program.cs:main}}
```
</TabItem>
<TabItem label="R" value="r">
<ConnR/>
@ -388,33 +494,39 @@ URL 和 Properties 的详细参数说明和如何使用详见 [API 说明](../..
```java
{{#include docs/examples/java/src/main/java/com/taos/example/JNIConnectExample.java:main}}
```
</TabItem>
<TabItem label="Python" value="python">
</TabItem>
<TabItem label="Python" value="python">
<ConnPythonNative />
</TabItem>
<TabItem label="Go" value="go">
<ConnGo />
</TabItem>
<TabItem label="Rust" value="rust">
<ConnRust />
</TabItem>
<TabItem label="C#" value="csharp">
<ConnCSNative />
</TabItem>
<TabItem label="R" value="r">
</TabItem>
<TabItem label="Go" value="go">
```go
{{#include docs/examples/go/connect/cgoexample/main.go}}
```
</TabItem>
<TabItem label="Rust" value="rust">
```rust
{{#include docs/examples/rust/nativeexample/examples/connect.rs}}
```
</TabItem>
<TabItem label="C#" value="csharp">
```csharp title="WebSocket 连接"
{{#include docs/examples/csharp/connect/Program.cs:main}}
```
</TabItem>
<TabItem label="R" value="r">
<ConnR/>
</TabItem>
<TabItem label="C" value="c">
</TabItem>
<TabItem label="C" value="c">
<ConnC />
</TabItem>
<TabItem label="PHP" value="php">
</TabItem>
<TabItem label="PHP" value="php">
<ConnPHP />
</TabItem>
</TabItem>
</Tabs>
### REST 连接
下面是各语言连接器建立 RESt 连接代码样例。演示了如何使用 REST 连接方式连接到 TDengine 数据库。整个过程主要涉及到数据库连接的建立和异常处理。
下面是各语言连接器建立 REST 连接代码样例。演示了如何使用 REST 连接方式连接到 TDengine 数据库。整个过程主要涉及到数据库连接的建立和异常处理。
<Tabs defaultValue="java" groupId="lang">
<TabItem label="Java" value="java">
@ -428,13 +540,15 @@ URL 和 Properties 的详细参数说明和如何使用详见 [API 说明](../..
```
</TabItem>
<TabItem label="Go" value="go">
<ConnGo />
```go
{{#include docs/examples/go/connect/restexample/main.go}}
```
</TabItem>
<TabItem label="Rust" value="rust">
<ConnRust />
不支持
</TabItem>
<TabItem label="C#" value="csharp">
<ConnCSNative />
C# 只支持 WebSocket 连接与原生连接
</TabItem>
<TabItem label="R" value="r">
<ConnR/>
@ -488,13 +602,45 @@ URL 和 Properties 的详细参数说明和如何使用详见 [API 说明](../..
<ConnPythonNative />
</TabItem>
<TabItem label="Go" value="go">
<ConnGo />
使用 `sql.Open` 创建出来的连接已经实现了连接池,可以通过 API 设置连接池参数,样例如下
```go
{{#include docs/examples/go/connect/connpool/main.go:pool}}
```
</TabItem>
<TabItem label="Rust" value="rust">
<ConnRust />
在复杂应用中,建议启用连接池。[taos] 的连接池默认(异步模式)使用 [deadpool] 实现。
如下,可以生成一个默认参数的连接池。
```rust
let pool: Pool<TaosBuilder> = TaosBuilder::from_dsn("taos:///")
.unwrap()
.pool()
.unwrap();
```
同样可以使用连接池的构造器,对连接池参数进行设置:
```rust
let pool: Pool<TaosBuilder> = Pool::builder(Manager::from_dsn(self.dsn.clone()).unwrap().0)
.max_size(88) // 最大连接数
.build()
.unwrap();
```
在应用代码中,使用 `pool.get()?` 来获取一个连接对象 [Taos]。
```rust
let taos = pool.get()?;
```
</TabItem>
<TabItem label="C#" value="csharp">
<ConnCSNative />
不支持
</TabItem>
<TabItem label="R" value="r">
<ConnR/>

View File

@ -11,6 +11,15 @@ TDengine 对 SQL 语言提供了全面的支持,允许用户以熟悉的 SQL
下面介绍使用各语言连接器通过执行 SQL 完成建库、建表、写入数据和查询数据。
:::note
REST 连接:各编程语言的连接器封装使用 `HTTP` 请求的连接,支持数据写入和查询操作。
REST API通过 `curl` 命令进行数据写入和查询操作。
:::
## 建库和表
下面以智能电表为例,展示使用各语言连接器如何执行 SQL 命令创建一个名为 `power` 的数据库,然后使用 `power` 数据库为默认数据库。
接着创建一个名为 `meters` 的超级表STABLE其表结构包含时间戳、电流、电压、相位等列以及分组 ID 和位置作为标签。
@ -21,7 +30,6 @@ TDengine 对 SQL 语言提供了全面的支持,允许用户以熟悉的 SQL
```java
{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/JdbcCreatDBDemo.java:create_db_and_table}}
```
> **注意**:如果不使用 `USE power` 指定数据库,则后续对表的操作都需要增加数据库名称作为前缀,如 power.meters。
</TabItem>
<TabItem label="Python" value="python">
@ -39,8 +47,16 @@ TDengine 对 SQL 语言提供了全面的支持,允许用户以熟悉的 SQL
```
</TabItem>
<TabItem label="Go" value="go">
```go
{{#include docs/examples/go/queryreqid/main.go:query_id}}
```
</TabItem>
<TabItem label="Rust" value="rust">
```rust
{{#include docs/examples/rust/nativeexample/examples/query.rs:create_db_and_table}}
```
</TabItem>
<TabItem label="Node.js" value="node.js">
```js
@ -48,14 +64,39 @@ TDengine 对 SQL 语言提供了全面的支持,允许用户以熟悉的 SQL
```
</TabItem>
<TabItem label="C#" value="csharp">
```csharp
{{#include docs/examples/csharp/wsInsert/Program.cs:create_db_and_table}}
```
</TabItem>
<TabItem label="R" value="r">
</TabItem>
<TabItem label="C" value="c">
```c
{{#include docs/examples/c/CCreateDBDemo.c:create_db_and_table}}
```
> **注意**:如果不使用 `USE power` 指定数据库,则后续对表的操作都需要增加数据库名称作为前缀,如 power.meters。
</TabItem>
<TabItem label="PHP" value="php">
</TabItem>
<TabItem label="REST API" value="rest">
创建数据库
```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))'
```
</TabItem>
</Tabs>
> **注意**:如果不使用 `USE power` 指定数据库,则后续对表的操作都需要增加数据库名称作为前缀,如 `power.meters`
## 插入数据
下面以智能电表为例,展示如何使用连接器执行 SQL 来插入数据到 `power` 数据库的 `meters` 超级表。样例使用 TDengine 自动建表 SQL 语法,写入 d1001 子表中 3 条数据,写入 d1002 子表中 1 条数据,然后打印出实际插入数据条数。
@ -87,8 +128,16 @@ NOW 为系统内部函数,默认为客户端所在计算机当前时间。 NOW
</TabItem>
<TabItem label="Go" value="go">
```go
{{#include docs/examples/go/sqlquery/main.go:create_db_and_table}}
```
</TabItem>
<TabItem label="Rust" value="rust">
```rust
{{#include docs/examples/rust/nativeexample/examples/query.rs:insert_data}}
```
</TabItem>
<TabItem label="Node.js" value="node.js">
```js
@ -96,12 +145,31 @@ NOW 为系统内部函数,默认为客户端所在计算机当前时间。 NOW
```
</TabItem>
<TabItem label="C#" value="csharp">
```csharp
{{#include docs/examples/csharp/wsInsert/Program.cs:insert_data}}
```
</TabItem>
<TabItem label="R" value="r">
</TabItem>
<TabItem label="C" value="c">
```c
{{#include docs/examples/c/CInsertDataDemo.c:insert_data}}
```
**Note**
NOW 为系统内部函数,默认为客户端所在计算机当前时间。 NOW + 1s 代表客户端当前时间往后加 1 秒数字后面代表时间单位a毫秒smh小时dwny
</TabItem>
<TabItem label="PHP" value="php">
</TabItem>
<TabItem label="REST API" value="rest">
写入数据
```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)'
```
</TabItem>
</Tabs>
@ -133,8 +201,16 @@ NOW 为系统内部函数,默认为客户端所在计算机当前时间。 NOW
```
</TabItem>
<TabItem label="Go" value="go">
```go
{{#include docs/examples/go/sqlquery/main.go:insert_data}}
```
</TabItem>
<TabItem label="Rust" value="rust">
```rust
{{#include docs/examples/rust/nativeexample/examples/query.rs:query_data}}
```
</TabItem>
<TabItem label="Node.js" value="node.js">
```js
@ -142,12 +218,28 @@ NOW 为系统内部函数,默认为客户端所在计算机当前时间。 NOW
```
</TabItem>
<TabItem label="C#" value="csharp">
```csharp
{{#include docs/examples/csharp/wsInsert/Program.cs:select_data}}
```
</TabItem>
<TabItem label="R" value="r">
</TabItem>
<TabItem label="C" value="c">
```c
{{#include docs/examples/c/CQueryDataDemo.c:query_data}}
```
</TabItem>
<TabItem label="PHP" value="php">
</TabItem>
<TabItem label="REST API" value="rest">
查询数据
```bash
curl --location -uroot:taosdata 'http://127.0.0.1:6041/rest/sql' \
--data 'SELECT ts, current, location FROM power.meters limit 100'
```
</TabItem>
</Tabs>
@ -175,8 +267,16 @@ reqId 可用于请求链路追踪reqId 就像分布式系统中的 traceId
<TabItem label="Python" value="python">
</TabItem>
<TabItem label="Go" value="go">
```go
{{#include docs/examples/go/sqlquery/main.go:select_data}}
```
</TabItem>
<TabItem label="Rust" value="rust">
```rust
{{#include docs/examples/rust/nativeexample/examples/query.rs:query_with_req_id}}
```
</TabItem>
<TabItem label="Node.js" value="node.js">
```js
@ -184,11 +284,27 @@ reqId 可用于请求链路追踪reqId 就像分布式系统中的 traceId
```
</TabItem>
<TabItem label="C#" value="csharp">
```csharp
{{#include docs/examples/csharp/wsInsert/Program.cs:query_id}}
```
</TabItem>
<TabItem label="R" value="r">
</TabItem>
<TabItem label="C" value="c">
```c
{{#include docs/examples/c/CWithReqIdDemo.c:with_reqid}}
```
</TabItem>
<TabItem label="PHP" value="php">
</TabItem>
<TabItem label="REST API" value="rest">
查询数据,指定 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'
```
</TabItem>
</Tabs>

View File

@ -161,7 +161,7 @@ st,t1=3,t2=4,t3=t3 c1=3i64,c6="passit" 1626006833640000000
### Websocket 连接
<Tabs defaultValue="java" groupId="schemaless">
<Tabs defaultValue="java" groupId="lang">
<TabItem value="java" label="Java">
```java
@ -179,8 +179,16 @@ writer.write(lineDemo, SchemalessProtocolType.LINE, SchemalessTimestampType.NANO
<TabItem label="Python" value="python">
</TabItem>
<TabItem label="Go" value="go">
```go
{{#include docs/examples/go/schemaless/ws/main.go}}
```
</TabItem>
<TabItem label="Rust" value="rust">
```rust
{{#include docs/examples/rust/restexample/examples/schemaless.rs}}
```
</TabItem>
<TabItem label="Node.js" value="node.js">
```js
@ -188,6 +196,9 @@ writer.write(lineDemo, SchemalessProtocolType.LINE, SchemalessTimestampType.NANO
```
</TabItem>
<TabItem label="C#" value="csharp">
```csharp
{{#include docs/examples/csharp/wssml/Program.cs:main}}
```
</TabItem>
<TabItem label="R" value="r">
</TabItem>
@ -210,21 +221,25 @@ writer.write(lineDemo, SchemalessProtocolType.LINE, SchemalessTimestampType.NANO
writer.write(lineDemo, SchemalessProtocolType.LINE, SchemalessTimestampType.NANO_SECONDS, 1L);
```
</TabItem>
<TabItem label="Python" value="python">
</TabItem>
<TabItem label="Go" value="go">
</TabItem>
<TabItem label="Rust" value="rust">
</TabItem>
<TabItem label="C#" value="csharp">
</TabItem>
<TabItem label="R" value="r">
</TabItem>
<TabItem label="C" value="c">
</TabItem>
<TabItem label="PHP" value="php">
</TabItem>
</TabItem>
<TabItem label="Python" value="python">
</TabItem>
<TabItem label="Go" value="go">
</TabItem>
<TabItem label="Rust" value="rust">
除 DSN 不同,其余同 Websocket 代码示例。
</TabItem>
<TabItem label="C#" value="csharp">
```csharp
{{#include docs/examples/csharp/nativesml/Program.cs:main}}
```
</TabItem>
<TabItem label="R" value="r">
</TabItem>
<TabItem label="C" value="c">
</TabItem>
<TabItem label="PHP" value="php">
</TabItem>
</Tabs>
@ -237,10 +252,15 @@ writer.write(lineDemo, SchemalessProtocolType.LINE, SchemalessTimestampType.NANO
<TabItem label="Python" value="python">
</TabItem>
<TabItem label="Go" value="go">
```go
{{#include docs/examples/go/schemaless/native/main.go}}
```
</TabItem>
<TabItem label="Rust" value="rust">
不支持
</TabItem>
<TabItem label="C#" value="csharp">
不支持
</TabItem>
<TabItem label="R" value="r">
</TabItem>

View File

@ -39,10 +39,16 @@ import TabItem from "@theme/TabItem";
```
</TabItem>
<TabItem label="Go" value="go">
```go
{{#include docs/examples/go/stmt/ws/main.go}}
```
</TabItem>
<TabItem label="Rust" value="rust">
```rust
{{#include docs/examples/rust/restexample/examples/stmt.rs}}
```
</TabItem>
<TabItem label="Node.js" value="node">
@ -51,7 +57,9 @@ import TabItem from "@theme/TabItem";
```
</TabItem>
<TabItem label="C#" value="csharp">
```csharp
{{#include docs/examples/csharp/wsStmt/Program.cs:main}}
```
</TabItem>
<TabItem label="R" value="r">
@ -79,13 +87,17 @@ import TabItem from "@theme/TabItem";
</TabItem>
<TabItem label="Go" value="go">
```go
{{#include docs/examples/go/stmt/native/main.go}}
```
</TabItem>
<TabItem label="Rust" value="rust">
除 DSN 不同,其余同 Websocket 代码示例。
</TabItem>
<TabItem label="C#" value="csharp">
```csharp
{{#include docs/examples/csharp/stmtInsert/Program.cs:main}}
```
</TabItem>
<TabItem label="R" value="r">

View File

@ -46,7 +46,7 @@ TDengine 消费者的概念跟 Kafka 类似,消费者通过订阅主题来接
下面是各语言连接器创建参数:
<Tabs defaultValue="java" groupId="lang">
<TabItem value="java" label="Java">
Java 连接器创建消费者的参数为 Properties 可以设置的参数列表请参考 [API 说明](../../reference/connector/java/#消费者)
Java 连接器创建消费者的参数为 Properties 可以设置的参数列表请参考 [消费者参数](../../reference/connector/java/#消费者)
其他参数请参考上文通用基础配置项。
@ -56,14 +56,39 @@ Java 连接器创建消费者的参数为 Properties 可以设置的参数列
</TabItem>
<TabItem label="Go" value="go">
创建消费者支持属性列表:
- `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。
其他参数见上表。
</TabItem>
<TabItem label="Rust" value="rust">
Rust 连接器创建消费者的参数为 DSN 可以设置的参数列表请参考 [DSN](../../reference/connector/rust/#dsn)
其他参数请参考上文通用基础配置项。
</TabItem>
<TabItem label="Node.js" value="node">
</TabItem>
<TabItem label="C#" value="csharp">
创建消费者支持属性列表:
- `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。
其他参数见上表。
</TabItem>
<TabItem label="R" value="r">
@ -85,7 +110,7 @@ Java 连接器创建消费者的参数为 Properties 可以设置的参数列
```java
{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsWsConsumerLoop.java:create_consumer}}
{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WsConsumerLoopFull.java:create_consumer}}
```
</TabItem>
@ -97,11 +122,18 @@ Java 连接器创建消费者的参数为 Properties 可以设置的参数列
</TabItem>
<TabItem label="Go" value="go">
```go
{{#include docs/examples/go/tmq/ws/main.go:create_consumer}}
```
</TabItem>
<TabItem label="Rust" value="rust">
```rust
{{#include docs/examples/rust/nativeexample/examples/tmq.rs:create_consumer}}
```
</TabItem>
<TabItem label="Node.js" value="node">
@ -112,7 +144,9 @@ Java 连接器创建消费者的参数为 Properties 可以设置的参数列
</TabItem>
<TabItem label="C#" value="csharp">
```csharp
{{#include docs/examples/csharp/wssubscribe/Program.cs:create_consumer}}
```
</TabItem>
<TabItem label="R" value="r">
@ -138,7 +172,7 @@ Java 连接器创建消费者的参数为 Properties 可以设置的参数列
```java
{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoop.java:create_consumer}}
{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ConsumerLoopFull.java:create_consumer}}
```
@ -152,7 +186,9 @@ Java 连接器创建消费者的参数为 Properties 可以设置的参数列
</TabItem>
<TabItem label="Go" value="go">
```go
{{#include docs/examples/go/tmq/native/main.go:create_consumer}}
```
</TabItem>
<TabItem label="Rust" value="rust">
@ -160,7 +196,9 @@ Java 连接器创建消费者的参数为 Properties 可以设置的参数列
</TabItem>
<TabItem label="C#" value="csharp">
```csharp
{{#include docs/examples/csharp/subscribe/Program.cs:create_consumer}}
```
</TabItem>
<TabItem label="R" value="r">
@ -183,7 +221,7 @@ Java 连接器创建消费者的参数为 Properties 可以设置的参数列
<TabItem value="java" label="Java">
```java
{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoop.java:poll_data_code_piece}}
{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WsConsumerLoopFull.java:poll_data_code_piece}}
```
- `subscribe` 方法的参数含义为:订阅的主题列表(即名称),支持同时订阅多个主题。
@ -200,7 +238,9 @@ Java 连接器创建消费者的参数为 Properties 可以设置的参数列
</TabItem>
<TabItem label="Go" value="go">
```go
{{#include docs/examples/go/tmq/ws/main.go:subscribe}}
```
</TabItem>
<TabItem label="Rust" value="rust">
@ -212,7 +252,9 @@ Java 连接器创建消费者的参数为 Properties 可以设置的参数列
</TabItem>
<TabItem label="C#" value="csharp">
```csharp
{{#include docs/examples/csharp/wssubscribe/Program.cs:subscribe}}
```
</TabItem>
<TabItem label="R" value="r">
@ -244,7 +286,9 @@ Java 连接器创建消费者的参数为 Properties 可以设置的参数列
</TabItem>
<TabItem label="Go" value="go">
```go
{{#include docs/examples/go/tmq/native/main.go:subscribe}}
```
</TabItem>
<TabItem label="Rust" value="rust">
@ -252,7 +296,9 @@ Java 连接器创建消费者的参数为 Properties 可以设置的参数列
</TabItem>
<TabItem label="C#" value="csharp">
```csharp
{{#include docs/examples/csharp/subscribe/Program.cs:subscribe}}
```
</TabItem>
<TabItem label="R" value="r">
@ -276,33 +322,7 @@ Java 连接器创建消费者的参数为 Properties 可以设置的参数列
<TabItem value="java" label="Java">
```java
// 获取当前消费者分配的 TopicPartition 集合
Set<TopicPartition> assignment() throws SQLException;
// 获取指定分区的当前偏移量
long position(TopicPartition partition) throws SQLException;
// 获取指定主题的所有分区的当前偏移量
Map<TopicPartition, Long> position(String topic) throws SQLException;
// 获取指定主题的所有分区的起始偏移量
Map<TopicPartition, Long> beginningOffsets(String topic) throws SQLException;
// 获取指定主题的所有分区的最新偏移量
Map<TopicPartition, Long> endOffsets(String topic) throws SQLException;
// 获取指定分区集合中的已提交偏移量
Map<TopicPartition, OffsetAndMetadata> committed(Set<TopicPartition> partitions) throws SQLException;
// 设置指定分区的偏移量
void seek(TopicPartition partition, long offset) throws SQLException;
// 将指定分区集合的偏移量设置为最开始
void seekToBeginning(Collection<TopicPartition> partitions) throws SQLException;
// 将指定分区集合的偏移量设置为最新
void seekToEnd(Collection<TopicPartition> partitions) throws SQLException;
```
示例代码:
```java
{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ConsumerOffsetSeek.java:consumer_seek}}
{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WsConsumerLoopFull.java:consumer_seek}}
```
</TabItem>
@ -315,7 +335,9 @@ void seekToEnd(Collection<TopicPartition> partitions) throws SQLException;
</TabItem>
<TabItem label="Go" value="go">
```go
{{#include docs/examples/go/tmq/ws/main.go:seek}}
```
</TabItem>
<TabItem label="Rust" value="rust">
@ -327,7 +349,9 @@ void seekToEnd(Collection<TopicPartition> partitions) throws SQLException;
</TabItem>
<TabItem label="C#" value="csharp">
```csharp
{{#include docs/examples/csharp/wssubscribe/Program.cs:seek}}
```
</TabItem>
<TabItem label="R" value="r">
@ -347,7 +371,6 @@ void seekToEnd(Collection<TopicPartition> partitions) throws SQLException;
<Tabs groupId="lang">
<TabItem value="java" label="Java">
同 Websocket 代码样例。
</TabItem>
@ -360,7 +383,9 @@ void seekToEnd(Collection<TopicPartition> partitions) throws SQLException;
</TabItem>
<TabItem label="Go" value="go">
```go
{{#include docs/examples/go/tmq/native/main.go:seek}}
```
</TabItem>
<TabItem label="Rust" value="rust">
@ -368,7 +393,9 @@ void seekToEnd(Collection<TopicPartition> partitions) throws SQLException;
</TabItem>
<TabItem label="C#" value="csharp">
```csharp
{{#include docs/examples/csharp/subscribe/Program.cs:seek}}
```
</TabItem>
<TabItem label="R" value="r">
@ -392,22 +419,9 @@ void seekToEnd(Collection<TopicPartition> partitions) throws SQLException;
<Tabs defaultValue="java" groupId="lang">
<TabItem value="java" label="Java">
```java
// 同步提交当前消费者的偏移量
void commitSync() throws SQLException;
// 同步提交指定的偏移量
void commitSync(Map<TopicPartition, OffsetAndMetadata> offsets) throws SQLException;
// 异步提交仅在 native 连接下有效
// 异步提交当前消费者的偏移量,需要提供回调以处理可能的提交结果
void commitAsync(OffsetCommitCallback<V> callback) throws SQLException;
// 异步提交指定的偏移量,需要提供回调以处理可能的提交结果
void commitAsync(Map<TopicPartition, OffsetAndMetadata> offsets, OffsetCommitCallback<V> callback) throws SQLException;
```
```java
{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoop.java:commit_code_piece}}
{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WsConsumerLoopFull.java:commit_code_piece}}
```
</TabItem>
@ -420,7 +434,9 @@ void commitAsync(Map<TopicPartition, OffsetAndMetadata> offsets, OffsetCommitCal
</TabItem>
<TabItem label="Go" value="go">
```go
{{#include docs/examples/go/tmq/ws/main.go:commit_offset}}
```
</TabItem>
<TabItem label="Rust" value="rust">
@ -432,7 +448,9 @@ void commitAsync(Map<TopicPartition, OffsetAndMetadata> offsets, OffsetCommitCal
</TabItem>
<TabItem label="C#" value="csharp">
```csharp
{{#include docs/examples/csharp/wssubscribe/Program.cs:commit_offset}}
```
</TabItem>
<TabItem label="R" value="r">
@ -466,7 +484,9 @@ void commitAsync(Map<TopicPartition, OffsetAndMetadata> offsets, OffsetCommitCal
</TabItem>
<TabItem label="Go" value="go">
```go
{{#include docs/examples/go/tmq/native/main.go:commit_offset}}
```
</TabItem>
<TabItem label="Rust" value="rust">
@ -478,7 +498,9 @@ void commitAsync(Map<TopicPartition, OffsetAndMetadata> offsets, OffsetCommitCal
</TabItem>
<TabItem label="C#" value="csharp">
```csharp
{{#include docs/examples/csharp/subscribe/Program.cs:commit_offset}}
```
</TabItem>
<TabItem label="R" value="r">
@ -504,7 +526,7 @@ void commitAsync(Map<TopicPartition, OffsetAndMetadata> offsets, OffsetCommitCal
<TabItem value="java" label="Java">
```java
{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoop.java:unsubscribe_data_code_piece}}
{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WsConsumerLoopFull.java:unsubscribe_data_code_piece}}
```
</TabItem>
@ -517,7 +539,9 @@ void commitAsync(Map<TopicPartition, OffsetAndMetadata> offsets, OffsetCommitCal
</TabItem>
<TabItem label="Go" value="go">
```go
{{#include docs/examples/go/tmq/ws/main.go:close}}
```
</TabItem>
<TabItem label="Rust" value="rust">
@ -529,7 +553,9 @@ void commitAsync(Map<TopicPartition, OffsetAndMetadata> offsets, OffsetCommitCal
</TabItem>
<TabItem label="C#" value="csharp">
```csharp
{{#include docs/examples/csharp/wssubscribe/Program.cs:close}}
```
</TabItem>
<TabItem label="R" value="r">
@ -547,7 +573,7 @@ void commitAsync(Map<TopicPartition, OffsetAndMetadata> offsets, OffsetCommitCal
</Tabs>
### 原生连接
<Tabs groupId="lang">
<Tabs defaultValue="java" groupId="lang">
<TabItem value="java" label="Java">
同 Websocket 代码样例。
@ -562,7 +588,9 @@ void commitAsync(Map<TopicPartition, OffsetAndMetadata> offsets, OffsetCommitCal
</TabItem>
<TabItem label="Go" value="go">
```go
{{#include docs/examples/go/tmq/native/main.go:close}}
```
</TabItem>
<TabItem label="Rust" value="rust">
@ -574,7 +602,9 @@ void commitAsync(Map<TopicPartition, OffsetAndMetadata> offsets, OffsetCommitCal
</TabItem>
<TabItem label="C#" value="csharp">
```csharp
{{#include docs/examples/csharp/subscribe/Program.cs:close}}
```
</TabItem>
<TabItem label="R" value="r">
@ -596,12 +626,14 @@ void commitAsync(Map<TopicPartition, OffsetAndMetadata> offsets, OffsetCommitCal
### Websocket 连接
<Tabs defaultValue="java" groupId="lang">
<TabItem value="java" label="Java">
<details>
<summary>完整 Websocket 连接代码示例</summary>
```java
{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsWsConsumerLoop.java:consumer_demo}}
{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WsConsumerLoopFull.java:consumer_demo}}
```
**注意**:这里的 value.deserializer 配置参数值应该根据测试环境的包路径做相应的调整。
其余代码请参考: [JDBC example](https://github.com/taosdata/TDengine/tree/3.0/examples/JDBC/JDBCDemo)
</details>
</TabItem>
<TabItem label="Python" value="python">
@ -612,7 +644,9 @@ void commitAsync(Map<TopicPartition, OffsetAndMetadata> offsets, OffsetCommitCal
</TabItem>
<TabItem label="Go" value="go">
```go
{{#include docs/examples/go/tmq/ws/main.go}}
```
</TabItem>
<TabItem label="Rust" value="rust">
@ -624,7 +658,9 @@ void commitAsync(Map<TopicPartition, OffsetAndMetadata> offsets, OffsetCommitCal
</TabItem>
<TabItem label="C#" value="csharp">
```csharp
{{#include docs/examples/csharp/wssubscribe/Program.cs}}
```
</TabItem>
<TabItem label="R" value="r">
@ -644,12 +680,16 @@ void commitAsync(Map<TopicPartition, OffsetAndMetadata> offsets, OffsetCommitCal
### 原生连接
<Tabs groupId="lang">
<TabItem value="java" label="Java">
<details>
<summary>完整原生连接代码示例</summary>
```java
{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/AbsConsumerLoopFull.java:consumer_demo}}
{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/ConsumerLoopFull.java:consumer_demo}}
```
**注意**:这里的 value.deserializer 配置参数值应该根据测试环境的包路径做相应的调整。
其余代码请参考: [JDBC example](https://github.com/taosdata/TDengine/tree/3.0/examples/JDBC/JDBCDemo)
</details>
</TabItem>
@ -661,7 +701,9 @@ void commitAsync(Map<TopicPartition, OffsetAndMetadata> offsets, OffsetCommitCal
</TabItem>
<TabItem label="Go" value="go">
```go
{{#include docs/examples/go/tmq/native/main.go}}
```
</TabItem>
<TabItem label="Rust" value="rust">
@ -673,7 +715,9 @@ void commitAsync(Map<TopicPartition, OffsetAndMetadata> offsets, OffsetCommitCal
</TabItem>
<TabItem label="C#" value="csharp">
```csharp
{{#include docs/examples/csharp/subscribe/Program.cs}}
```
</TabItem>
<TabItem label="R" value="r">

View File

@ -224,131 +224,161 @@ int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields)
基础 API 用于完成创建数据库连接等工作,为其它 API 的执行提供运行时环境。
- `int taos_init()`
初始化运行环境。如果没有主动调用该 API那么调用 `taos_connect()` 时驱动将自动调用该 API故程序一般无需手动调用
- **接口说明**:初始化运行环境。如果没有主动调用该 API那么调用 `taos_connect()` 时驱动将自动调用该 API故程序一般无需手动调用。
- **返回值**:待补充,未找到相关资料
- `void taos_cleanup()`
清理运行环境,应用退出前应调用。
- **接口说明**:清理运行环境,应用退出前应调用。
- `int taos_options(TSDB_OPTION option, const void * arg, ...)`
设置客户端选项,目前支持区域设置(`TSDB_OPTION_LOCALE`)、字符集设置(`TSDB_OPTION_CHARSET`)、时区设置(`TSDB_OPTION_TIMEZONE`)、配置文件路径设置(`TSDB_OPTION_CONFIGDIR`)。区域设置、字符集、时区默认为操作系统当前设置。
- **接口说明**:设置客户端选项,目前支持区域设置(`TSDB_OPTION_LOCALE`)、字符集设置(`TSDB_OPTION_CHARSET`)、时区设置(`TSDB_OPTION_TIMEZONE`)、配置文件路径设置(`TSDB_OPTION_CONFIGDIR`)。区域设置、字符集、时区默认为操作系统当前设置。
- **参数说明**
- `option`[入参] 设置项类型。
- `arg`[入参] 设置项值。
- **返回值**`0`:成功,`-1`:失败。
- `char *taos_get_client_info()`
- **接口说明**:获取客户端版本信息。
- **返回值**:返回客户端版本信息。
获取客户端版本信息。
- `TAOS *taos_connect(const char *host, const char *user, const char *pass, const char *db, int port)`
创建数据库连接,初始化连接上下文。其中需要用户提供的参数包含:
- hostTDengine 集群中任一节点的 FQDN
- user用户名
- pass密码
- db 数据库名字,如果用户没有提供,也可以正常连接,用户可以通过该连接创建新的数据库,如果用户提供了数据库名字,则说明该数据库用户已经创建好,缺省使用该数据库
- porttaosd 程序监听的端口
返回值为空表示失败。应用程序需要保存返回的参数,以便后续使用。
- `TAOS *taos_connect(const char *ip, const char *user, const char *pass, const char *db, uint16_t port);`
- **接口说明**:创建数据库连接,初始化连接上下文。
- **参数说明**
- ip[入参] TDengine 集群中任一节点的 FQDN。
- user[入参] 用户名。
- pass[入参] 密码。
- db[入参] 数据库名字,如果用户没有提供,也可以正常连接,用户可以通过该连接创建新的数据库,如果用户提供了数据库名字,则说明该数据库用户已经创建好,缺省使用该数据库。
- port[入参] taosd 程序监听的端口。
- **返回值**:返回数据库连接,返回值为空表示失败。应用程序需要保存返回的参数,以便后续使用。
:::info
同一进程可以根据不同的 host/port 连接多个 TDengine 集群
:::
- `TAOS *taos_connect_auth(const char *host, const char *user, const char *auth, const char *db, uint16_t port)`
功能同 taos_connect。除 pass 参数替换为 auth 外,其他参数同 taos_connect。
- auth: 原始密码取 32 位小写 md5
- **接口说明**:功能同 taos_connect。除 pass 参数替换为 auth 外,其他参数同 taos_connect。
- **参数说明**
- ip[入参] TDengine 集群中任一节点的 FQDN。
- user[入参] 用户名。
- auth: [入参] 原始密码取 32 位小写 md5。
- db[入参] 数据库名称,如果用户没有提供,也可以正常连接,用户可以通过该连接创建新的数据库,如果用户提供了数据库名字,则说明该数据库用户已经创建好,缺省使用该数据库。
- port[入参] taosd 程序监听的端口。
- **返回值**:返回数据库连接,返回值为空表示失败。应用程序需要保存返回的参数,以便后续使用。
- `char *taos_get_server_info(TAOS *taos)`
获取服务端版本信息。
- **接口说明**:获取服务端版本信息。
- **参数说明**
- taos[入参] 数据库连接。
- **返回值**:返回获取服务端版本信息。
- `int taos_select_db(TAOS *taos, const char *db)`
将当前的缺省数据库设置为 `db`。
- **接口说明**:将当前的缺省数据库设置为 `db`。
- **参数说明**
- taos[入参] 数据库连接。
- db[入参] 数据库名称。
- **返回值**`0`:成功,`非0`:失败,详情请参考错误码。待补充。
- `int taos_get_current_db(TAOS *taos, char *database, int len, int *required)`
- databaselen为用户在外面申请的空间内部会把当前db赋值到database里。
- 只要是没有正常把db名赋值到database中包括截断返回错误返回值为-1然后用户可以通过 taos_errstr(NULL) 来获取错误提示。
- 如果database == NULL 或者 len\<=0 返回错误required里保存存储db需要的空间包含最后的'\0'
- 如果len 小于 存储db需要的空间包含最后的'\0'返回错误database里赋值截断的数据以'\0'结尾。
- 如果len 大于等于 存储db需要的空间包含最后的'\0'返回正常0database里赋值以'\0结尾的db名。
- **接口说明**:获取当前数据库名称。
- **参数说明**
- taos[入参] 数据库连接。
- database[出参] 存储当前数据库名称。
- len[入参] database 的空间大小。
- required[出参] 存储当前数据库名称所需的空间(包含最后的'\0')。
- **返回值**`0`:成功,`-1`:失败,详情请调用 taos_errstr(NULL) 函数来获取错误提示。
- 如果database == NULL 或者 len\<=0 返回失败。
- 如果len 小于 存储数据库名称所需的空间(包含最后的'\0'返回失败database 里赋值截断的数据,以'\0'结尾。
- 如果len 大于等于 存储数据库名称所需的空间(包含最后的'\0'返回成功database 里赋值以'\0结尾数据库名称。
- `int taos_set_notify_cb(TAOS *taos, __taos_notify_fn_t fp, void *param, int type)`
设置事件回调函数。
- fp 事件回调函数指针。函数声明typedef void (*__taos_notify_fn_t)(void *param, void *ext, int type);其中, param 为用户自定义参数ext 为扩展参数(依赖事件类型,针对 TAOS_NOTIFY_PASSVER 返回用户密码版本)type 为事件类型
- param 用户自定义参数
- type 事件类型。取值范围1TAOS_NOTIFY_PASSVER 用户密码改变
- **接口说明**:设置事件回调函数。
- **参数说明**
- taos[入参] 数据库连接。
- fp[入参] 事件回调函数指针。函数声明typedef void (*__taos_notify_fn_t)(void *param, void *ext, int type);其中, param 为用户自定义参数ext 为扩展参数(依赖事件类型,针对 TAOS_NOTIFY_PASSVER 返回用户密码版本)type 为事件类型。
- param[入参] 用户自定义参数。
- type[入参] 事件类型。取值范围1TAOS_NOTIFY_PASSVER 用户密码改变。
- **返回值**`0`:成功,`-1`:失败,详情请调用 taos_errstr(NULL) 函数来获取错误提示。
- `void taos_close(TAOS *taos)`
关闭连接,其中`taos`是 `taos_connect()` 返回的句柄。
- **接口说明**:关闭连接。
- **参数说明**
- taos[入参] 数据库连接。
### 同步查询 API
本小节介绍 API 均属于同步接口。应用调用后,会阻塞等待响应,直到获得返回结果或错误信息。
- `TAOS_RES* taos_query(TAOS *taos, const char *sql)`
执行 SQL 语句,可以是 DQL、DML 或 DDL 语句。 其中的 `taos` 参数是通过 `taos_connect()` 获得的句柄。不能通过返回值是否是 `NULL` 来判断执行结果是否失败,而是需要用 `taos_errno()` 函数解析结果集中的错误代码来进行判断。
- **接口说明**:执行 SQL 语句,可以是 DQL、DML 或 DDL 语句。
- **参数说明**
- taos[入参] 数据库连接。
- sql[入参] 需要执行 SQL 语句。
- **返回值**:不能通过返回值是否是 `NULL` 来判断执行结果是否失败,而是需要调用 `taos_errno()` 函数解析结果集中的错误代码来进行判断。
- taos_errno 返回值:`0`:成功,`-1`:失败,详情请调用 taos_errstr 函数来获取错误提示。
- `int taos_result_precision(TAOS_RES *res)`
返回结果集时间戳字段的精度,`0` 代表毫秒,`1` 代表微秒,`2` 代表纳秒。
- **接口说明**:返回结果集时间戳字段的精度类别。
- **参数说明**
- res[入参] 结果集。
- **返回值**`0`:毫秒,`1`:微秒,`2`:纳秒。
- `TAOS_ROW taos_fetch_row(TAOS_RES *res)`
按行获取查询结果集中的数据。
- **接口说明**:按行获取查询结果集中的数据。
- **参数说明**
- res[入参] 查询结果集。
- **返回值**`非NULL`:成功,`NULL`:失败,详情请调用 taos_errstr(NULL) 函数来获取错误提示。
- `int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows)`
批量获取查询结果集中的数据,返回值为获取到的数据的行数。
- **接口说明**:批量获取查询结果集中的数据。
- **参数说明**
- res[入参] 查询结果集。
- rows[出参] 用于存储从结果集中获取的行。
- **返回值**:返回值为获取到的数据的行数,如果没有更多的行则返回 0。
- `int taos_num_fields(TAOS_RES *res)` 和 `int taos_field_count(TAOS_RES *res)`
这两个 API 等价,用于获取查询结果集中的列数。
- **接口说明**:这两个 API 等价,用于获取查询结果集中的列数。
- **参数说明**
- res[入参] 查询结果集。
- **返回值**:返回值为结果集中列的数量。
- `int* taos_fetch_lengths(TAOS_RES *res)`
获取结果集中每个字段的长度。返回值是一个数组,其长度为结果集的列数。
- **接口说明**:获取结果集中每个字段的长度。
- **参数说明**
- res[入参] 结果集。
- **返回值**:返回值是一个数组,其长度为结果集的列数。
- `int taos_affected_rows(TAOS_RES *res)`
获取被所执行的 SQL 语句影响的行数。
- **接口说明**:获取被所执行的 SQL 语句影响的行数。
- **参数说明**
- res[入参] 结果集。
- **返回值**:返回值表示受影响的行数。
- `TAOS_FIELD *taos_fetch_fields(TAOS_RES *res)`
获取查询结果集每列数据的属性(列的名称、列的数据类型、列的长度),与 `taos_num_fields()` 配合使用,可用来解析 `taos_fetch_row()` 返回的一个元组(一行)的数据。 `TAOS_FIELD` 的结构如下:
```c
typedef struct taosField {
char name[65]; // column name
uint8_t type; // data type
int16_t bytes; // length, in bytes
} TAOS_FIELD;
```
- **接口说明**:获取查询结果集每列数据的属性(列的名称、列的数据类型、列的长度),与 `taos_num_fields()` 配合使用,可用来解析 `taos_fetch_row()` 返回的一个元组(一行)的数据。
- **参数说明**
- res[入参] 查询结果集。
- **返回值**`非NULL`:成功,返回一个指向 TAOS_FIELD 结构体的指针,每个元素代表一列的元数据。`NULL`:失败。
- `void taos_stop_query(TAOS_RES *res)`
停止当前查询的执行。
- **接口说明**:停止当前查询的执行。
- **参数说明**
- res[入参] 查询结果集。
- `void taos_free_result(TAOS_RES *res)`
释放查询结果集以及相关的资源。查询完成后,务必调用该 API 释放资源,否则可能导致应用内存泄露。但也需注意,释放资源后,如果再调用 `taos_consume()` 等获取查询结果的函数,将导致应用崩溃。
- **接口说明**:释放查询结果集以及相关的资源。查询完成后,务必调用该 API 释放资源,否则可能导致应用内存泄露。但也需注意,释放资源后,如果再调用 `taos_consume()` 等获取查询结果的函数,将导致应用崩溃。
- **参数说明**
- res[入参] 查询结果集。
- `char *taos_errstr(TAOS_RES *res)`
获取最近一次 API 调用失败的原因,返回值为字符串标识的错误提示信息。
- **接口说明**:获取最近一次 API 调用失败的原因,返回值为字符串标识的错误提示信息。
- **参数说明**
- res[入参] 结果集。
- **返回值**:字符串标识的错误提示信息。
- `int taos_errno(TAOS_RES *res)`
获取最近一次 API 调用失败的原因,返回值为错误代码。
- **接口说明**:获取最近一次 API 调用失败的原因,返回值为错误代码。
- **参数说明**
- res[入参] 结果集。
- **返回值**:字符串标识的错误提示信息。
:::note
2.0 及以上版本 TDengine 推荐数据库应用的每个线程都建立一个独立的连接,或基于线程建立连接池。而不推荐在应用中将该连接 (TAOS\*) 结构体传递到不同的线程共享使用。基于 TAOS 结构体发出的查询、写入等操作具有多线程安全性,但 “USE statement” 等状态量有可能在线程之间相互干扰。此外C 语言的连接器可以按照需求动态建立面向数据库的新连接(该过程对用户不可见),同时建议只有在程序最后退出的时候才调用 `taos_close()` 关闭连接。
@ -365,19 +395,17 @@ TDengine 还提供性能更高的异步 API 处理数据插入、查询操作。
异步 API 对于使用者的要求相对较高,用户可根据具体应用场景选择性使用。下面是两个重要的异步 API
- `void taos_query_a(TAOS *taos, const char *sql, void (*fp)(void *param, TAOS_RES *, int code), void *param);`
异步执行 SQL 语句。
- taos调用 `taos_connect()` 返回的数据库连接
- sql需要执行的 SQL 语句
- fp用户定义的回调函数其第三个参数 `code` 用于指示操作是否成功,`0` 表示成功,负数表示失败(调用 `taos_errstr()` 可获取失败原因)。应用在定义回调函数的时候,主要处理第二个参数 `TAOS_RES *`,该参数是查询返回的结果集
- param应用提供一个用于回调的参数
- **接口说明**:异步执行 SQL 语句。
- **参数说明**
- taos[入参] 数据库连接。
- sql: [入参] 需要执行的 SQL 语句。
- fp用户定义的回调函数其第三个参数 `code` 用于指示操作是否成功,`0` 表示成功,负数表示失败(调用 `taos_errstr()` 可获取失败原因)。应用在定义回调函数的时候,主要处理第二个参数 `TAOS_RES *`,该参数是查询返回的结果集。
- param应用提供的用于回调的参数。
- `void taos_fetch_rows_a(TAOS_RES *res, void (*fp)(void *param, TAOS_RES *, int numOfRows), void *param);`
批量获取异步查询的结果集,只能与 `taos_query_a()` 配合使用。其中:
- res`taos_query_a()` 回调时返回的结果集
- **接口说明** 批量获取异步查询的结果集,只能与 `taos_query_a()` 配合使用。
- **参数说明**
- res`taos_query_a()` 回调时返回的结果集。
- fp回调函数。其参数 `param` 是用户可定义的传递给回调函数的参数结构体;`numOfRows` 是获取到的数据的行数(不是整个查询结果集的函数)。 在回调函数中,应用可以通过调用 `taos_fetch_row()` 前向迭代获取批量记录中每一行记录。读完一块内的所有记录后,应用需要在回调函数中继续调用 `taos_fetch_rows_a()` 获取下一批记录进行处理,直到返回的记录数 `numOfRows` 为零(结果返回完成)或记录数为负值(查询出错)。
TDengine 的异步 API 均采用非阻塞调用模式。应用程序可以用多线程同时打开多张表,并可以同时对每张打开的表进行查询或者插入操作。需要指出的是,**客户端应用必须确保对同一张表的操作完全串行化**,即对同一个表的插入或查询操作未完成时(未返回时),不能够执行第二个插入或查询操作。

View File

@ -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&...&paramN=valueN]
```
完整形式的 DSN
```text
username:password@protocol(address)/dbname?param=value
```
<Tabs defaultValue="rest" groupId="connect">
<TabItem value="native" label="原生连接">
_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
}
}
```
</TabItem>
<TabItem value="rest" label="REST 连接">
_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` 读取数据的缓存区大小默认为 4K4096当查询结果数据量多时可以适当调大该值。
示例:
```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
}
}
```
</TabItem>
<TabItem value="WebSocket" label="WebSocket 连接">
_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
}
}
```
</TabItem>
</Tabs>
### 指定 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
<RequestId />
```go
{{#include docs/examples/go/demo/query/main.go:with_reqid}}
```
### 通过参数绑定写入数据
<Tabs defaultValue="native" groupId="connect">
<TabItem value="native" label="原生连接">
```go
{{#include docs/examples/go/demo/stmt/main.go}}
```
</TabItem>
<TabItem value="WebSocket" label="WebSocket 连接">
```go
{{#include docs/examples/go/demo/stmtws/main.go}}
```
</TabItem>
</Tabs>
### 无模式写入
<Tabs defaultValue="native" groupId="connect">
<TabItem value="native" label="原生连接">
```go
{{#include docs/examples/go/demo/sml/main.go}}
```
</TabItem>
<TabItem value="WebSocket" label="WebSocket 连接">
```go
{{#include docs/examples/go/demo/smlws/main.go}}
```
</TabItem>
</Tabs>
### 执行带有 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}}
```
#### 完整示例
<Tabs defaultValue="native" groupId="connect">
<TabItem value="native" label="原生连接">
```go
{{#include docs/examples/go/demo/consumer/main.go}}
```
</TabItem>
<TabItem value="WebSocket" label="WebSocket 连接">
```go
{{#include docs/examples/go/demo/consumerws/main.go}}
```
</TabItem>
</Tabs>
### 更多示例程序
* [示例程序](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)。

View File

@ -168,7 +168,7 @@ DSN 描述字符串基本结构如下:
各部分意义见下表:
- **driver**: 必须指定驱动名以便连接器选择何种方式创建连接,支持如下驱动名:
- **taos**: 表使用 TDengine 连接器驱动。
- **taos**: 表使用 TDengine 连接器驱动。
- **tmq**: 使用 TMQ 订阅数据。
- **http/ws**: 使用 Websocket 创建连接。
- **https/wss**: 在 Websocket 连接方式下显示启用 SSL/TLS 连接。
@ -607,12 +607,435 @@ stmt.execute()?;
一个可运行的示例请见 [GitHub 上的示例](https://github.com/taosdata/taos-connector-rust/blob/main/examples/bind.rs)。
其他相关结构体 API 使用说明请移步 Rust 文档托管网页:\<https://docs.rs/taos>。
## API 参考
[taos]: https://github.com/taosdata/rust-connector-taos
[deadpool]: https://crates.io/crates/deadpool
[r2d2]: https://crates.io/crates/r2d2
[TaosBuilder]: https://docs.rs/taos/latest/taos/struct.TaosBuilder.html
[TaosCfg]: https://docs.rs/taos/latest/taos/struct.TaosCfg.html
[struct.Taos]: https://docs.rs/taos/latest/taos/struct.Taos.html
[Stmt]: https://docs.rs/taos/latest/taos/struct.Stmt.html
Rust 连接器的接口分为同步接口和异步接口,一般同步接口是由异步接口实现,方法签名除 async 关键字外基本相同。对于同步接口和异步接口功能一样的接口,本文档只提供同步接口的说明。
对于 WebSocket 连接和原生连接两种方式,除了建立连接的 DSN 不同,其余接口调用没有区别。
### 连接功能
#### DSN
TaosBuilder 通过 DSN 连接描述字符串创建一个连接构造器。
DSN 描述字符串基本结构如下:
```text
<driver>[+<protocol>]://[[<username>:<password>@]<host>:<port>][/<database>][?<p1>=<v1>[&<p2>=<v2>]]
|------|------------|---|-----------|-----------|------|------|------------|-----------------------|
|driver| protocol | | username | password | host | port | database | params |
```
各部分意义见下表:
- **driver**: 必须指定驱动名以便连接器选择何种方式创建连接,支持如下驱动名:
- **taos**: 表名使用 TDengine 连接器驱动。
- **tmq**: 使用 TMQ 订阅数据。
- **http/ws**: 使用 Websocket 创建连接。
- **https/wss**: 在 Websocket 连接方式下显示启用 SSL/TLS 连接。
- **protocol**: 显示指定以何种方式建立连接,例如:`taos+ws://localhost:6041` 指定以 Websocket 方式建立连接。
- **username/password**: 用于创建连接的用户名及密码。
- **host/port**: 指定创建连接的服务器及端口,当不指定服务器地址及端口时(`taos://`),原生连接默认为 `localhost:6030`Websocket 连接默认为 `localhost:6041` 。
- **database**: 指定默认连接的数据库名,可选参数。
- **params**:其他可选参数。
一个完整的 DSN 描述字符串示例如下:`taos+ws://localhost:6041/test` 表示使用 Websocket`ws`)方式通过 `6041` 端口连接服务器 `localhost`,并指定默认数据库为 `test`。
#### TaosBuilder
TaosBuilder 结构体主要提供了根据 DSN 构建 Taos 对象的方法,还提供了检查连接,以及获取客户端版本号等功能。
- `fn available_params() -> &'static [&'static str]`
- **接口说明**:获取 DSN 中可用的参数列表。
- **返回值**:返回静态字符串切片的引用,包含可用的参数名称。
- `fn from_dsn<D: IntoDsn>(dsn: D) -> RawResult<Self>`
- **接口说明**:使用 DSN 字符串创建连接,不检查连接。
- **参数说明**
- `dsn`DSN 字符串或可转换为 DSN 的类型。
- **返回值**:成功时返回自身类型的 `RawResult`,失败时返回错误。
- `fn client_version() -> &'static str`
- **接口说明**:获取客户端版本。
- **返回值**:返回客户端版本的静态字符串。
- `fn ping(&self, _: &mut Self::Target) -> RawResult<()>`
- **接口说明**:检查连接是否仍然存活。
- **参数说明**
- `_`:目标连接的可变引用。
- **返回值**:成功时返回空的 `RawResult`,失败时返回错误。
- `fn ready(&self) -> bool`
- **接口说明**:检查是否准备好连接。
- **返回值**:大多数情况下返回 `true`,表示地址准备好连接。
- `fn build(&self) -> RawResult<Self::Target>`
- **接口说明**:从此结构创建新的 Taos 对象。
- **返回值**:成功时返回目标连接类型的 `RawResult`,失败时返回错误。
### 执行 SQL
执行 SQL 主要使用 Taos 结构体,获取结果集以及元数据需要使用下节介绍的 ResultSet 结构体 和列信息 Field 结构体。
#### Taos
Taos 结构体提供了多个数据库操作的 API包括执行 SQL无模式写入以及一些常用数据库查询的封装如创建数据库获取
- `pub fn is_native(&self) -> bool`
- **接口说明**:判断连接是否使用本地协议。
- **返回值**:如果使用本地协议,则返回 `true`,否则返回 `false`。
- `pub fn is_ws(&self) -> bool`
- **接口说明**判断连接是否使用websocket协议。
- **返回值**如果使用websocket协议则返回 `true`,否则返回 `false`。
- `fn query<T: AsRef<str>>(&self, sql: T) -> RawResult<Self::ResultSet>`
- **接口说明**:执行 SQL 查询。
- **参数说明**
- `sql`:要执行的 SQL 语句。
- **返回值**:成功时返回结果集 `ResultSet` 的 `RawResult`,失败时返回错误。
- `fn query_with_req_id<T: AsRef<str>>(&self, sql: T, req_id: u64) -> RawResult<Self::ResultSet>`
- **接口说明**:带请求 ID 执行 SQL 查询。
- **参数说明**
- `sql`:要执行的 SQL 语句。
- `req_id`:请求 ID。
- **返回值**:成功时返回结果集 `ResultSet` 的 `RawResult`,失败时返回错误。
- `fn exec<T: AsRef<str>>(&self, sql: T) -> RawResult<usize>`
- **接口说明**:执行 SQL 语句。
- **参数说明**
- `sql`:要执行的 SQL 语句。
- **返回值**:成功时返回受影响的行数,失败时返回错误。
- `fn exec_many<T: AsRef<str>, I: IntoIterator<Item = T>>(&self, input: I) -> RawResult<usize>`
- **接口说明**:批量执行 SQL 语句。
- **参数说明**
- `input`:要执行的 SQL 语句集合。
- **返回值**:成功时返回总共受影响的行数,失败时返回错误。
- `fn query_one<T: AsRef<str>, O: DeserializeOwned>(&self, sql: T) -> RawResult<Option<O>>`
- **接口说明**:执行 SQL 查询并返回单个结果。
- **参数说明**
- `sql`:要执行的 SQL 语句。
- **返回值**:成功时返回可选的结果对象,失败时返回错误。
- `fn server_version(&self) -> RawResult<Cow<str>>`
- **接口说明**:获取服务器版本。
- **返回值**:成功时返回服务器版本字符串的 `RawResult`,失败时返回错误。
- `fn create_topic(&self, name: impl AsRef<str>, sql: impl AsRef<str>) -> RawResult<()>`
- **接口说明**:创建主题。
- **参数说明**
- `name`:主题名称。
- `sql`:关联的 SQ L语句。
- **返回值**:成功时返回空的 `RawResult`,失败时返回错误。
- `fn databases(&self) -> RawResult<Vec<ShowDatabase>>`
- **接口说明**:获取数据库列表。
- **返回值**:成功时返回数据库列表的 `RawResult`,失败时返回错误。
- `fn topics(&self) -> RawResult<Vec<Topic>>`
- **接口说明**:获取主题信息。
- **返回值**:成功时返回主题列表的 `RawResult`,失败时返回错误。
- `fn describe(&self, table: &str) -> RawResult<Describe>`
- **接口说明**:描述表结构。
- **参数说明**
- `table`:表名称。
- **返回值**:成功时返回表结构描述的 `RawResult`,失败时返回错误。
- `fn database_exists(&self, name: &str) -> RawResult<bool>`
- **接口说明**:检查数据库是否存在。
- **参数说明**
- `name`:数据库名称。
- **返回值**:成功时返回布尔值的 `RawResult`,指示数据库是否存在,失败时返回错误。
- `fn put(&self, data: &SmlData) -> RawResult<()>`
- **接口说明**写入无模式数据SmlData 结构介绍见下文。
- **参数说明**
- `data`:无模式数据。
- **返回值**:成功时返回空的 `RawResult`,失败时返回错误。
### SmlData
SmlData 结构体提供了无模式写入的数据结构,以及获取属性的方法。
- `pub struct SmlData`
- **结构体说明**`SmlData` 结构体用于存储无模式数据及其相关信息。
- **字段说明**
- `protocol`:无模式协议,支持 `Line`, `Telnet`, `Json`, 三种。
- `precision`:时间戳精度,支持 `Hours`, `Minutes`, `Seconds`, `Millisecond`(默认), `Microsecond`, `Nanosecond`。
- `data`:数据列表。
- `ttl`:数据存活时间,单位为秒。
- `req_id`:请求 ID。
- `pub fn protocol(&self) -> SchemalessProtocol`
- **接口说明**:获取无模式协议。
- **返回值**:无模式协议类型,支持 `Line`, `Telnet`, `Json`, 三种。
- `pub fn precision(&self) -> SchemalessPrecision`
- **接口说明**:获取时间戳精度。
- **返回值**:时间戳精度类型,支持 `Hours`, `Minutes`, `Seconds`, `Millisecond`(默认), `Microsecond`, `Nanosecond`。
- `pub fn data(&self) -> &Vec<String>`
- **接口说明**:获取数据列表。
- **返回值**:数据列表的引用。
- `pub fn ttl(&self) -> Option<i32>`
- **接口说明**:获取数据存活时间。
- **返回值**:数据存活时间(可选),单位为秒。
- `pub fn req_id(&self) -> Option<u64>`
- **接口说明**:获取请求 ID。
- **返回值**:请求 ID可选
### 结果获取
#### ResultSet
ResultSet 结构体提供了结果集的一些方法,可以用来获取结果集的数据和元数据。
- `fn affected_rows(&self) -> i32`
- **接口说明**:获取受影响的行数。
- **返回值**:受影响的行数,类型为 `i32`。
- `fn precision(&self) -> Precision`
- **接口说明**:获取精度信息。
- **返回值**:精度信息,类型为 `Precision`。
- `fn fields(&self) -> &[Field]`
- **接口说明**:获取字段信息。见下文 Feild 结构体描述。
- **返回值**:字段信息数组的引用。
- `fn summary(&self) -> (usize, usize)`
- **接口说明**:获取摘要信息。
- **返回值**:包含两个 `usize` 类型的元组,分别表示某些统计信息。
- `fn num_of_fields(&self) -> usize`
- **接口说明**:获取字段数量。
- **返回值**:字段数量,类型为 `usize`。
- `fn blocks(&mut self) -> IBlockIter<'_, Self>`
- **接口说明**:获取原始数据块的迭代器。
- **返回值**:原始数据块的迭代器,类型为 `IBlockIter<'_, Self>`。
- `fn rows(&mut self) -> IRowsIter<'_, Self>`
- **接口说明**:获取按行查询的迭代器。
- **返回值**:按行查询的迭代器,类型为 `IRowsIter<'_, Self>`。
- `fn deserialize<T>(&mut self) -> Map<IRowsIter<'_, Self>, fn(_: Result<RowView<'_>, Error>) -> Result<T, Error>>`
- **接口说明**:反序列化行数据。
- **泛型参数**
- `T`:目标类型,需实现 `DeserializeOwned`。
- **返回值**:反序列化结果的映射,类型为 `Map<IRowsIter<'_, Self>, fn(_: Result<RowView<'_>, Error>) -> Result<T, Error>>`。
- `fn to_rows_vec(&mut self) -> Result<Vec<Vec<Value>>, Error>`
- **接口说明**:将结果集转换为值的二维向量。
- **返回值**:成功时返回值的二维向量,失败时返回错误,类型为 `Result<Vec<Vec<Value>>, Error>`。
#### Feild
Feild 结构体提供了字段信息的一些方法。
- `pub const fn empty() -> Field`
- **接口说明**:创建一个空的 `Field` 实例。
- **返回值**:返回一个空的 `Field` 实例。
- `pub fn new(name: impl Into<String>, ty: Ty, bytes: u32) -> Field`
- **接口说明**:创建一个新的 `Field` 实例。
- **参数说明**
- `name`:字段名称。
- `ty`:字段类型。
- `bytes`:字段数据长度。
- **返回值**:返回一个新的 `Field` 实例。
- `pub fn name(&self) -> &str`
- **接口说明**:获取字段名称。
- **返回值**:返回字段的名称。
- `pub fn escaped_name(&self) -> String`
- **接口说明**:获取转义后的字段名称。
- **返回值**:返回转义后的字段名称。
- `pub const fn ty(&self) -> Ty`
- **接口说明**:获取字段类型。
- **返回值**:返回字段的类型。
- `pub const fn bytes(&self) -> u32`
- **接口说明**:获取字段的预设长度。
- **返回值**:对于变长数据类型,返回其预设长度;对于其他类型,返回其字节宽度。
- `pub fn to_c_field(&self) -> c_field_t`
- **接口说明**:将 `Field` 实例转换为 C 语言结构体。
- **返回值**:返回 C 语言结构体表示的字段。
- `pub fn sql_repr(&self) -> String`
- **接口说明**:表示字段在 SQL 中的数据类型。
- **返回值**:例如:"INT", "VARCHAR(100)" 等 SQL 数据类型表示。
### 参数绑定
参数绑定功能主要由 Stmt 结构体支持。
#### Stmt
Stmt 结构体提供了参数绑定相关功能,用于实现高效写入。
- `fn init(taos: &Q) -> RawResult<Self>`
- **接口说明**:初始化参数绑定实例。
- **参数说明**
- `taos`:数据库连接实例。
- **返回值**:成功时返回初始化的实例,失败时返回错误。
- `fn init_with_req_id(taos: &Q, req_id: u64) -> RawResult<Self>`
- **接口说明**:使用请求 ID 初始化参数绑定实例。
- **参数说明**
- `taos`:数据库连接实例。
- `req_id`:请求 ID。
- **返回值**:成功时返回初始化的实例,失败时返回错误。
- `fn prepare<S: AsRef<str>>(&mut self, sql: S) -> RawResult<&mut Self>`
- **接口说明**:准备要绑定的 SQL 语句。
- **参数说明**
- `sql`:要准备的 SQL 语句。
- **返回值**:成功时返回自身的可变引用,失败时返回错误。
- `fn set_tbname<S: AsRef<str>>(&mut self, name: S) -> RawResult<&mut Self>`
- **接口说明**:设置表名称。
- **参数说明**
- `name`:表名称。
- **返回值**:成功时返回自身的可变引用,失败时返回错误。
- `fn set_tags(&mut self, tags: &[Value]) -> RawResult<&mut Self>`
- **接口说明**:设置标签。
- **参数说明**
- `tags`:标签数组。
- **返回值**:成功时返回自身的可变引用,失败时返回错误。
- `fn set_tbname_tags<S: AsRef<str>>(&mut self, name: S, tags: &[Value]) -> RawResult<&mut Self>`
- **接口说明**:设置表名称和标签。
- **参数说明**
- `name`:表名称。
- `tags`:标签数组。
- **返回值**:成功时返回自身的可变引用,失败时返回错误。
- `fn bind(&mut self, params: &[ColumnView]) -> RawResult<&mut Self>`
- **接口说明**:绑定参数。
- **参数说明**
- `params`:参数数组。
- **返回值**:成功时返回自身的可变引用,失败时返回错误。
- `fn add_batch(&mut self) -> RawResult<&mut Self>`
- **接口说明**:添加批处理。
- **返回值**:成功时返回自身的可变引用,失败时返回错误。
- `fn execute(&mut self) -> RawResult<usize>`
- **接口说明**:执行语句。
- **返回值**:成功时返回受影响的行数,失败时返回错误。
- `fn affected_rows(&self) -> usize`
- **接口说明**:获取受影响的行数。
- **返回值**:受影响的行数。
### 数据订阅
数据订阅主要涉及三个结构体,提供连接建立的 TmqBuilder 消费数据和提交偏移量的 Consumer以及偏移量 Offset。
#### TmqBuilder
同 TaosBuilder 类似TmqBuilder 提供了创建消费者对象的功能。
- `fn available_params() -> &'static [&'static str]`
- **接口说明**:获取 DSN 中可用的参数列表。
- **返回值**:返回静态字符串切片的引用,包含可用的参数名称。
- `fn from_dsn<D: IntoDsn>(dsn: D) -> RawResult<Self>`
- **接口说明**:使用 DSN 字符串创建连接,不检查连接。
- **参数说明**
- `dsn`DSN 字符串或可转换为DSN的类型。
- **返回值**:成功时返回自身类型的 `RawResult`,失败时返回错误。
- `fn client_version() -> &'static str`
- **接口说明**:获取客户端版本。
- **返回值**:返回客户端版本的静态字符串。
- `fn ping(&self, conn: &mut Self::Target) -> RawResult<()>`
- **接口说明**:检查连接是否仍然存活。
- **参数说明**
- `conn`:目标连接的可变引用。
- **返回值**:成功时返回空的 `RawResult`,失败时返回错误。
- `fn ready(&self) -> bool`
- **接口说明**:检查是否准备好连接。
- **返回值**:大多数情况下返回 `true`,表示地址准备好连接。
- `fn build(&self) -> RawResult<Self::Target>`
- **接口说明**:从此结构创建新的连接。
- **返回值**:成功时返回目标连接类型的 `RawResult`,失败时返回错误。
#### Consumer
Consumer 结构体提供了订阅相关的功能,包括订阅,获取消息,提交偏移量,设置偏移量等。
- `fn subscribe<T: Into<String>, I: IntoIterator<Item = T> + Send>(&mut self, topics: I) -> RawResult<()>`
- **接口说明**:订阅一系列主题。
- **参数说明**
- `topics`:要订阅的主题列表。
- **返回值**:成功时返回空的 `RawResult`,失败时返回错误。
- `fn recv_timeout(&self, timeout: Timeout) -> RawResult<Option<(Self::Offset, MessageSet<Self::Meta, Self::Data>)>>`
- **接口说明**:在指定超时时间内接收消息。
- **参数说明**
- `timeout`:超时时间。
- **返回值**:成功时返回消息,失败时返回错误。
- `fn commit(&self, offset: Self::Offset) -> RawResult<()>`
- **接口说明**:提交给定的偏移量。
- **参数说明**
- `offset`:要提交的偏移量,见下文 Offset 结构体。
- **返回值**:成功时返回空的 `RawResult`,失败时返回错误。
- `fn commit_offset(&self, topic_name: &str, vgroup_id: VGroupId, offset: i64) -> RawResult<()>`
- **接口说明**:为特定主题和分区提交偏移量。
- **参数说明**
- `topic_name`:主题名称。
- `vgroup_id`:分区 ID。
- `offset`:要提交的偏移量。
- **返回值**:成功时返回空的 `RawResult`,失败时返回错误。
- `fn list_topics(&self) -> RawResult<Vec<String>>`
- **接口说明**:列出所有可用主题。
- **返回值**:成功时返回主题列表,失败时返回错误。
- `fn assignments(&self) -> Option<Vec<(String, Vec<Assignment>)>>`
- **接口说明**:获取当前分配的主题和分区。
- **返回值**:成功时返回分配信息,失败时返回 `None`。
- `fn offset_seek(&mut self, topic: &str, vg_id: VGroupId, offset: i64) -> RawResult<()>`
- **接口说明**:为特定主题和分区设置偏移量。
- **参数说明**
- `topic`:主题名称。
- `vg_id`:分区 ID。
- `offset`:要设置的偏移量。
- **返回值**:成功时返回空的 `RawResult`,失败时返回错误。
- `fn committed(&self, topic: &str, vgroup_id: VGroupId) -> RawResult<i64>`
- **接口说明**:获取特定主题和分区的已提交偏移量。
- **参数说明**
- `topic`:主题名称。
- `vgroup_id`:分区 ID。
- **返回值**:成功时返回偏移量,失败时返回错误。
- `fn position(&self, topic: &str, vgroup_id: VGroupId) -> RawResult<i64>`
- **接口说明**:获取特定主题和分区的当前位置。
- **参数说明**
- `topic`:主题名称。
- `vgroup_id`:分区 ID。
- **返回值**:成功时返回当前位置,失败时返回错误。
#### Offset
Offset 结构体提供了获取当前消息所属的数据库,主题和分区信息。
- `fn database(&self) -> &str`
- **接口说明**:获取当前消息的数据库名称。
- **返回值**:数据库名称的引用。
- `fn topic(&self) -> &str`
- **接口说明**:获取当前消息的主题名称。
- **返回值**:主题名称的引用。
- `fn vgroup_id(&self) -> VGroupId`
- **接口说明**:获取当前消息的分区 ID。
- **返回值**:分区 ID。
## 附录
- Rust 连接器文档https://docs.rs/taos
- Rust 连接器项目地址: https://github.com/taosdata/rust-connector-taos
- deadpool 连接池: https://crates.io/crates/deadpool
- r2d2 连接池: https://crates.io/crates/r2d2

File diff suppressed because it is too large Load Diff

View File

@ -32,7 +32,7 @@ config.setProperty("msg.with.table.name", "true");
config.setProperty("enable.auto.commit", "true");
config.setProperty("auto.commit.interval.ms", "1000");
config.setProperty("group.id", "group1");
config.setProperty("client.id", "1");
config.setProperty("client.id", "client1");
config.setProperty("value.deserializer", "com.taosdata.example.AbsConsumerLoop$ResultDeserializer");
config.setProperty("value.deserializer.encoding", "UTF-8");
try {

View File

@ -1,142 +0,0 @@
package com.taosdata.example;
import com.taosdata.jdbc.tmq.ConsumerRecord;
import com.taosdata.jdbc.tmq.ConsumerRecords;
import com.taosdata.jdbc.tmq.ReferenceDeserializer;
import com.taosdata.jdbc.tmq.TaosConsumer;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.time.Duration;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;
// ANCHOR: consumer_demo
public abstract class AbsConsumerLoopFull {
private final TaosConsumer<ResultBean> consumer;
private final List<String> topics;
private final AtomicBoolean shutdown;
private final CountDownLatch shutdownLatch;
public AbsConsumerLoopFull() throws SQLException {
Properties config = new Properties();
config.setProperty("td.connect.type", "jni");
config.setProperty("bootstrap.servers", "localhost:6030");
config.setProperty("auto.offset.reset", "latest");
config.setProperty("msg.with.table.name", "true");
config.setProperty("enable.auto.commit", "true");
config.setProperty("auto.commit.interval.ms", "1000");
config.setProperty("group.id", "group1");
config.setProperty("client.id", "1");
config.setProperty("value.deserializer", "com.taosdata.example.AbsConsumerLoop$ResultDeserializer");
config.setProperty("value.deserializer.encoding", "UTF-8");
try {
this.consumer = new TaosConsumer<>(config);
} catch (SQLException ex) {
// handle any errors, please refer to the JDBC specifications for detailed exceptions info
System.out.println("Failed to create jni consumer, host : " + config.getProperty("bootstrap.servers") + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw new SQLException("Failed to create consumer", ex);
}
this.topics = Collections.singletonList("topic_meters");
this.shutdown = new AtomicBoolean(false);
this.shutdownLatch = new CountDownLatch(1);
}
public abstract void process(ResultBean result);
public void pollData() throws SQLException {
try {
// subscribe to the topics
consumer.subscribe(topics);
while (!shutdown.get()) {
// poll data
ConsumerRecords<ResultBean> records = consumer.poll(Duration.ofMillis(100));
for (ConsumerRecord<ResultBean> record : records) {
ResultBean bean = record.value();
// process the data here
process(bean);
}
}
// unsubscribe the topics
consumer.unsubscribe();
} finally {
// close the consumer
consumer.close();
shutdownLatch.countDown();
}
}
public void shutdown() throws InterruptedException {
shutdown.set(true);
shutdownLatch.await();
}
public static class ResultDeserializer extends ReferenceDeserializer<ResultBean> {
}
// use this class to define the data structure of the result record
public static class ResultBean {
private Timestamp ts;
private double current;
private int voltage;
private double phase;
private int groupid;
private String location;
public Timestamp getTs() {
return ts;
}
public void setTs(Timestamp ts) {
this.ts = ts;
}
public double getCurrent() {
return current;
}
public void setCurrent(double current) {
this.current = current;
}
public int getVoltage() {
return voltage;
}
public void setVoltage(int voltage) {
this.voltage = voltage;
}
public double getPhase() {
return phase;
}
public void setPhase(double phase) {
this.phase = phase;
}
public int getGroupid() {
return groupid;
}
public void setGroupid(int groupid) {
this.groupid = groupid;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
}
}
// ANCHOR_END: consumer_demo

View File

@ -1,144 +0,0 @@
package com.taosdata.example;
import com.taosdata.jdbc.tmq.ConsumerRecord;
import com.taosdata.jdbc.tmq.ConsumerRecords;
import com.taosdata.jdbc.tmq.ReferenceDeserializer;
import com.taosdata.jdbc.tmq.TaosConsumer;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.time.Duration;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;
// ANCHOR: consumer_demo
public abstract class AbsWsConsumerLoop {
private final TaosConsumer<ResultBean> consumer;
private final List<String> topics;
private final AtomicBoolean shutdown;
private final CountDownLatch shutdownLatch;
public AbsWsConsumerLoop() throws SQLException {
// ANCHOR: create_consumer
Properties config = new Properties();
config.setProperty("td.connect.type", "ws");
config.setProperty("bootstrap.servers", "localhost:6041");
config.setProperty("auto.offset.reset", "latest");
config.setProperty("msg.with.table.name", "true");
config.setProperty("enable.auto.commit", "true");
config.setProperty("auto.commit.interval.ms", "1000");
config.setProperty("group.id", "group1");
config.setProperty("client.id", "client1");
config.setProperty("value.deserializer", "com.taosdata.example.AbsConsumerLoopWs$ResultDeserializer");
config.setProperty("value.deserializer.encoding", "UTF-8");
try {
this.consumer = new TaosConsumer<>(config);
} catch (SQLException ex) {
// handle any errors, please refer to the JDBC specifications for detailed exceptions info
System.out.println("Failed to create ws consumer with " + config.getProperty("bootstrap.servers") + " ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw new SQLException("Failed to create consumer", ex);
}
// ANCHOR_END: create_consumer
this.topics = Collections.singletonList("topic_meters");
this.shutdown = new AtomicBoolean(false);
this.shutdownLatch = new CountDownLatch(1);
}
public abstract void process(ResultBean result);
public void pollData() throws SQLException {
try {
// Subscribe to the topic
consumer.subscribe(topics);
while (!shutdown.get()) {
// poll data
ConsumerRecords<ResultBean> records = consumer.poll(Duration.ofMillis(100));
for (ConsumerRecord<ResultBean> record : records) {
ResultBean bean = record.value();
// process data here
process(bean);
}
}
// unsubscribe the topics
consumer.unsubscribe();
} finally {
// close the consumer
consumer.close();
shutdownLatch.countDown();
}
}
public void shutdown() throws InterruptedException {
shutdown.set(true);
shutdownLatch.await();
}
public static class ResultDeserializer extends ReferenceDeserializer<ResultBean> {
}
// use this class to define the data structure of the result record
public static class ResultBean {
private Timestamp ts;
private double current;
private int voltage;
private double phase;
private int groupid;
private String location;
public Timestamp getTs() {
return ts;
}
public void setTs(Timestamp ts) {
this.ts = ts;
}
public double getCurrent() {
return current;
}
public void setCurrent(double current) {
this.current = current;
}
public int getVoltage() {
return voltage;
}
public void setVoltage(int voltage) {
this.voltage = voltage;
}
public double getPhase() {
return phase;
}
public void setPhase(double phase) {
this.phase = phase;
}
public int getGroupid() {
return groupid;
}
public void setGroupid(int groupid) {
this.groupid = groupid;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
}
}
// ANCHOR_END: consumer_demo

View File

@ -0,0 +1,357 @@
package com.taosdata.example;
import com.alibaba.fastjson.JSON;
import com.taosdata.jdbc.TSDBDriver;
import com.taosdata.jdbc.tmq.*;
import java.sql.*;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
// ANCHOR: consumer_demo
public class ConsumerLoopFull {
static private Connection connection;
static private Statement statement;
public static TaosConsumer<ResultBean> getConsumer() throws SQLException{
// ANCHOR: create_consumer
Properties config = new Properties();
config.setProperty("td.connect.type", "jni");
config.setProperty("bootstrap.servers", "localhost:6030");
config.setProperty("auto.offset.reset", "latest");
config.setProperty("msg.with.table.name", "true");
config.setProperty("enable.auto.commit", "true");
config.setProperty("auto.commit.interval.ms", "1000");
config.setProperty("group.id", "group1");
config.setProperty("client.id", "1");
config.setProperty("td.connect.user", "root");
config.setProperty("td.connect.pass", "taosdata");
config.setProperty("value.deserializer", "com.taosdata.example.ConsumerLoopFull$ResultDeserializer");
config.setProperty("value.deserializer.encoding", "UTF-8");
try {
return new TaosConsumer<>(config);
} catch (SQLException ex) {
// handle any errors, please refer to the JDBC specifications for detailed exceptions info
System.out.println("Failed to create jni consumer, host : " + config.getProperty("bootstrap.servers") + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw new SQLException("Failed to create consumer", ex);
} catch (Exception e) {
e.printStackTrace();
throw new SQLException("Failed to create consumer", e);
}
// ANCHOR_END: create_consumer
}
public static void pollDataExample() throws SQLException {
try (TaosConsumer<ResultBean> consumer = getConsumer()){
// subscribe to the topics
List<String> topics = Collections.singletonList("topic_meters");
consumer.subscribe(topics);
System.out.println("subscribe topics successfully");
for (int i = 0; i < 50; i++) {
// poll data
ConsumerRecords<ResultBean> records = consumer.poll(Duration.ofMillis(100));
for (ConsumerRecord<ResultBean> record : records) {
ResultBean bean = record.value();
// process the data here
System.out.println("data: " + JSON.toJSONString(bean));
}
}
// unsubscribe the topics
consumer.unsubscribe();
System.out.println("unsubscribed topics successfully");
} catch (SQLException ex) {
// handle any errors, please refer to the JDBC specifications for detailed exceptions info
System.out.println("Failed to poll data from topic_meters, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw new SQLException("Failed to poll data from topic_meters", ex);
}
}
public static void pollExample() throws SQLException {
// ANCHOR: poll_data_code_piece
try (TaosConsumer<ResultBean> consumer = getConsumer()){
List<String> topics = Collections.singletonList("topic_meters");
// subscribe to the topics
consumer.subscribe(topics);
System.out.println("subscribe topics successfully");
for (int i = 0; i < 50; i++) {
// poll data
ConsumerRecords<ResultBean> records = consumer.poll(Duration.ofMillis(100));
for (ConsumerRecord<ResultBean> record : records) {
ResultBean bean = record.value();
// process the data here
System.out.println("data: " + JSON.toJSONString(bean));
}
}
} catch (SQLException ex) {
// handle any errors, please refer to the JDBC specifications for detailed exceptions info
System.out.println("Failed to poll data; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw new SQLException("Failed to poll data", ex);
}
// ANCHOR_END: poll_data_code_piece
}
public static void seekExample() throws SQLException {
// ANCHOR: consumer_seek
try (TaosConsumer<ResultBean> consumer = getConsumer()){
List<String> topics = Collections.singletonList("topic_meters");
// subscribe to the topics
consumer.subscribe(topics);
System.out.println("subscribe topics successfully");
ConsumerRecords<ResultBean> records = ConsumerRecords.emptyRecord();
// make sure we have got some data
while (records.isEmpty()){
records = consumer.poll(Duration.ofMillis(100));
}
for (ConsumerRecord<ResultBean> record : records) {
System.out.println("first data polled: " + JSON.toJSONString(record.value()));
Set<TopicPartition> assignment = consumer.assignment();
// seek to the beginning of the all partitions
consumer.seekToBeginning(assignment);
System.out.println("assignment seek to beginning successfully");
break;
}
// poll data agagin
records = consumer.poll(Duration.ofMillis(100));
for (ConsumerRecord<ResultBean> record : records) {
// process the data here
System.out.println("second data polled: " + JSON.toJSONString(record.value()));
break;
}
} catch (SQLException ex) {
// handle any errors, please refer to the JDBC specifications for detailed exceptions info
System.out.println("seek example failed; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw new SQLException("seek example failed", ex);
}
// ANCHOR_END: consumer_seek
}
public static void commitExample() throws SQLException {
// ANCHOR: commit_code_piece
try (TaosConsumer<ResultBean> consumer = getConsumer()){
List<String> topics = Collections.singletonList("topic_meters");
consumer.subscribe(topics);
for (int i = 0; i < 50; i++) {
ConsumerRecords<ResultBean> records = consumer.poll(Duration.ofMillis(100));
for (ConsumerRecord<ResultBean> record : records) {
ResultBean bean = record.value();
// process your data here
System.out.println("data: " + JSON.toJSONString(bean));
}
if (!records.isEmpty()) {
// after processing the data, commit the offset manually
consumer.commitSync();
}
}
} catch (SQLException ex){
// handle any errors, please refer to the JDBC specifications for detailed exceptions info
System.out.println("Failed to execute consumer functions. ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw new SQLException("Failed to execute consumer functions", ex);
}
// ANCHOR_END: commit_code_piece
}
public static void unsubscribeExample() throws SQLException {
TaosConsumer<ResultBean> consumer = getConsumer();
List<String> topics = Collections.singletonList("topic_meters");
consumer.subscribe(topics);
// ANCHOR: unsubscribe_data_code_piece
try {
consumer.unsubscribe();
} catch (SQLException ex){
// handle any errors, please refer to the JDBC specifications for detailed exceptions info
System.out.println("Failed to unsubscribe consumer. ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw new SQLException("Failed to unsubscribe consumer", ex);
} finally {
consumer.close();
}
// ANCHOR_END: unsubscribe_data_code_piece
}
public static class ResultDeserializer extends ReferenceDeserializer<ResultBean> {
}
// use this class to define the data structure of the result record
public static class ResultBean {
private Timestamp ts;
private double current;
private int voltage;
private double phase;
private int groupid;
private String location;
public Timestamp getTs() {
return ts;
}
public void setTs(Timestamp ts) {
this.ts = ts;
}
public double getCurrent() {
return current;
}
public void setCurrent(double current) {
this.current = current;
}
public int getVoltage() {
return voltage;
}
public void setVoltage(int voltage) {
this.voltage = voltage;
}
public double getPhase() {
return phase;
}
public void setPhase(double phase) {
this.phase = phase;
}
public int getGroupid() {
return groupid;
}
public void setGroupid(int groupid) {
this.groupid = groupid;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
}
public static void prepareData() throws SQLException{
StringBuilder insertQuery = new StringBuilder();
insertQuery.append("INSERT INTO " +
"power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " +
"VALUES ");
for (int i = 0; i < 10000; i++){
insertQuery.append("(NOW + ").append(i).append("a, 10.30000, 219, 0.31000) ");
}
try {
int affectedRows = statement.executeUpdate(insertQuery.toString());
assert affectedRows == 10000;
} catch (SQLException ex) {
System.out.println("Failed to insert data to power.meters, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw new SQLException("Failed to insert data to power.meters", ex);
}
}
public static void prepareMeta() throws SQLException{
try {
statement.executeUpdate("CREATE DATABASE IF NOT EXISTS power");
statement.executeUpdate("USE power");
statement.executeUpdate("CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))");
statement.executeUpdate("CREATE TOPIC IF NOT EXISTS topic_meters AS SELECT ts, current, voltage, phase, groupid, location FROM meters");
} catch (SQLException ex) {
System.out.println("Failed to create db and table, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw new SQLException("Failed to create db and table", ex);
}
}
public static void initConnection() throws SQLException {
String url = "jdbc:TAOS://localhost:6030?user=root&password=taosdata";
Properties properties = new Properties();
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "C");
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
try {
connection = DriverManager.getConnection(url, properties);
} catch (SQLException ex) {
System.out.println("Failed to create connection, url:" + url + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw new SQLException("Failed to create connection", ex);
}
try {
statement = connection.createStatement();
} catch (SQLException ex) {
System.out.println("Failed to create statement, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw new SQLException("Failed to create statement", ex);
}
System.out.println("Connection created successfully.");
}
public static void closeConnection() throws SQLException {
try {
if (statement != null) {
statement.close();
}
} catch (SQLException ex) {
System.out.println("Failed to close statement, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw new SQLException("Failed to close statement", ex);
}
try {
if (connection != null) {
connection.close();
}
} catch (SQLException ex) {
System.out.println("Failed to close connection, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw new SQLException("Failed to close connection", ex);
}
System.out.println("Connection closed Successfully.");
}
public static void main(String[] args) throws SQLException {
initConnection();
prepareMeta();
// create a single thread executor
ExecutorService executor = Executors.newSingleThreadExecutor();
// submit a task
executor.submit(() -> {
try {
// please use one example at a time
pollDataExample();
// seekExample();
// pollExample();
// commitExample();
unsubscribeExample();
} catch (SQLException ex) {
System.out.println("Failed to poll data from topic_meters, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
}
System.out.println("pollDataExample executed successfully");
});
prepareData();
closeConnection();
System.out.println("Data prepared successfully");
// 关闭线程池不再接收新任务
executor.shutdown();
try {
// 等待直到所有任务完成
boolean result = executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
assert result;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (Exception e){
e.printStackTrace();
System.out.println("Wait executor termination failed.");
}
System.out.println("program end.");
}
}
// ANCHOR_END: consumer_demo

View File

@ -2,7 +2,10 @@ package com.taosdata.example;
import com.taosdata.jdbc.TSDBPreparedStatement;
import java.sql.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Random;
@ -24,6 +27,7 @@ public class ParameterBindingBasicDemo {
String sql = "INSERT INTO ? USING meters TAGS(?,?) VALUES (?,?,?,?)";
try (TSDBPreparedStatement pstmt = conn.prepareStatement(sql).unwrap(TSDBPreparedStatement.class)) {
for (int i = 1; i <= numOfSubTable; i++) {
// set table name
pstmt.setTableName("d_bind_" + i);
@ -32,19 +36,35 @@ public class ParameterBindingBasicDemo {
pstmt.setTagInt(0, i);
pstmt.setTagString(1, "location_" + i);
// set columns
// set column ts
ArrayList<Long> tsList = new ArrayList<>();
long current = System.currentTimeMillis();
for (int j = 0; j < numOfRow; j++) {
pstmt.setTimestamp(1, new Timestamp(current + j));
pstmt.setFloat(2, random.nextFloat() * 30);
pstmt.setInt(3, random.nextInt(300));
pstmt.setFloat(4, random.nextFloat());
pstmt.addBatch();
}
int [] exeResult = pstmt.executeBatch();
// you can check exeResult here
System.out.println("insert " + exeResult.length + " rows.");
for (int j = 0; j < numOfRow; j++)
tsList.add(current + j);
pstmt.setTimestamp(0, tsList);
// set column current
ArrayList<Float> currentList = new ArrayList<>();
for (int j = 0; j < numOfRow; j++)
currentList.add(random.nextFloat() * 30);
pstmt.setFloat(1, currentList);
// set column voltage
ArrayList<Integer> voltageList = new ArrayList<>();
for (int j = 0; j < numOfRow; j++)
voltageList.add(random.nextInt(300));
pstmt.setInt(2, voltageList);
// set column phase
ArrayList<Float> phaseList = new ArrayList<>();
for (int j = 0; j < numOfRow; j++)
phaseList.add(random.nextFloat());
pstmt.setFloat(3, phaseList);
// add column
pstmt.columnDataAddBatch();
}
// execute column
pstmt.columnDataExecuteBatch();
}
} catch (SQLException ex) {
// handle any errors, please refer to the JDBC specifications for detailed exceptions info

View File

@ -1,83 +0,0 @@
package com.taosdata.example;
import com.taosdata.jdbc.TSDBPreparedStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Random;
// ANCHOR: para_bind
public class ParameterBindingBatchDemo {
// modify host to your own
private static final String host = "127.0.0.1";
private static final Random random = new Random(System.currentTimeMillis());
private static final int numOfSubTable = 10, numOfRow = 10;
public static void main(String[] args) throws SQLException {
String jdbcUrl = "jdbc:TAOS://" + host + ":6030/";
try (Connection conn = DriverManager.getConnection(jdbcUrl, "root", "taosdata")) {
init(conn);
String sql = "INSERT INTO ? USING meters TAGS(?,?) VALUES (?,?,?,?)";
try (TSDBPreparedStatement pstmt = conn.prepareStatement(sql).unwrap(TSDBPreparedStatement.class)) {
for (int i = 1; i <= numOfSubTable; i++) {
// set table name
pstmt.setTableName("d_bind_" + i);
// set tags
pstmt.setTagInt(0, i);
pstmt.setTagString(1, "location_" + i);
// set column ts
ArrayList<Long> tsList = new ArrayList<>();
long current = System.currentTimeMillis();
for (int j = 0; j < numOfRow; j++)
tsList.add(current + j);
pstmt.setTimestamp(0, tsList);
// set column current
ArrayList<Float> f1List = new ArrayList<>();
for (int j = 0; j < numOfRow; j++)
f1List.add(random.nextFloat() * 30);
pstmt.setFloat(1, f1List);
// set column voltage
ArrayList<Integer> f2List = new ArrayList<>();
for (int j = 0; j < numOfRow; j++)
f2List.add(random.nextInt(300));
pstmt.setInt(2, f2List);
// set column phase
ArrayList<Float> f3List = new ArrayList<>();
for (int j = 0; j < numOfRow; j++)
f3List.add(random.nextFloat());
pstmt.setFloat(3, f3List);
// add column
pstmt.columnDataAddBatch();
}
// execute column
pstmt.columnDataExecuteBatch();
}
} catch (SQLException ex) {
// handle any errors, please refer to the JDBC specifications for detailed exceptions info
System.out.println("Failed to insert to table meters using stmt, url: " + jdbcUrl + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
}
}
private static void init(Connection conn) throws SQLException {
try (Statement stmt = conn.createStatement()) {
stmt.execute("CREATE DATABASE IF NOT EXISTS power");
stmt.execute("USE power");
stmt.execute("CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))");
}
}
}
// ANCHOR_END: para_bind

View File

@ -0,0 +1,358 @@
package com.taosdata.example;
import com.alibaba.fastjson.JSON;
import com.taosdata.jdbc.TSDBDriver;
import com.taosdata.jdbc.tmq.*;
import java.sql.*;
import java.time.Duration;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
// ANCHOR: consumer_demo
public class WsConsumerLoopFull {
static private Connection connection;
static private Statement statement;
public static TaosConsumer<ResultBean> getConsumer() throws SQLException{
// ANCHOR: create_consumer
Properties config = new Properties();
config.setProperty("td.connect.type", "ws");
config.setProperty("bootstrap.servers", "localhost:6041");
config.setProperty("auto.offset.reset", "latest");
config.setProperty("msg.with.table.name", "true");
config.setProperty("enable.auto.commit", "true");
config.setProperty("auto.commit.interval.ms", "1000");
config.setProperty("group.id", "group1");
config.setProperty("client.id", "client1");
config.setProperty("td.connect.user", "root");
config.setProperty("td.connect.pass", "taosdata");
config.setProperty("value.deserializer", "com.taosdata.example.WsConsumerLoopFull$ResultDeserializer");
config.setProperty("value.deserializer.encoding", "UTF-8");
try {
return new TaosConsumer<>(config);
} catch (SQLException ex) {
// handle any errors, please refer to the JDBC specifications for detailed exceptions info
System.out.println("Failed to create websocket consumer, host : " + config.getProperty("bootstrap.servers") + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw new SQLException("Failed to create consumer", ex);
} catch (Exception e) {
e.printStackTrace();
throw new SQLException("Failed to create consumer", e);
}
// ANCHOR_END: create_consumer
}
public static void pollDataExample() throws SQLException {
try (TaosConsumer<ResultBean> consumer = getConsumer()){
// subscribe to the topics
List<String> topics = Collections.singletonList("topic_meters");
consumer.subscribe(topics);
System.out.println("subscribe topics successfully");
for (int i = 0; i < 50; i++) {
// poll data
ConsumerRecords<ResultBean> records = consumer.poll(Duration.ofMillis(100));
for (ConsumerRecord<ResultBean> record : records) {
ResultBean bean = record.value();
// process the data here
System.out.println("data: " + JSON.toJSONString(bean));
}
}
// unsubscribe the topics
consumer.unsubscribe();
System.out.println("unsubscribed topics successfully");
} catch (SQLException ex) {
// handle any errors, please refer to the JDBC specifications for detailed exceptions info
System.out.println("Failed to poll data from topic_meters, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw new SQLException("Failed to poll data from topic_meters", ex);
}
}
public static void pollExample() throws SQLException {
// ANCHOR: poll_data_code_piece
try (TaosConsumer<ResultBean> consumer = getConsumer()){
List<String> topics = Collections.singletonList("topic_meters");
// subscribe to the topics
consumer.subscribe(topics);
System.out.println("subscribe topics successfully");
for (int i = 0; i < 50; i++) {
// poll data
ConsumerRecords<ResultBean> records = consumer.poll(Duration.ofMillis(100));
for (ConsumerRecord<ResultBean> record : records) {
ResultBean bean = record.value();
// process the data here
System.out.println("data: " + JSON.toJSONString(bean));
}
}
} catch (SQLException ex) {
// handle any errors, please refer to the JDBC specifications for detailed exceptions info
System.out.println("Failed to poll data; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw new SQLException("Failed to poll data", ex);
}
// ANCHOR_END: poll_data_code_piece
}
public static void seekExample() throws SQLException {
// ANCHOR: consumer_seek
try (TaosConsumer<ResultBean> consumer = getConsumer()){
List<String> topics = Collections.singletonList("topic_meters");
// subscribe to the topics
consumer.subscribe(topics);
System.out.println("subscribe topics successfully");
ConsumerRecords<ResultBean> records = ConsumerRecords.emptyRecord();
// make sure we have got some data
while (records.isEmpty()){
records = consumer.poll(Duration.ofMillis(100));
}
for (ConsumerRecord<ResultBean> record : records) {
System.out.println("first data polled: " + JSON.toJSONString(record.value()));
Set<TopicPartition> assignment = consumer.assignment();
// seek to the beginning of the all partitions
consumer.seekToBeginning(assignment);
System.out.println("assignment seek to beginning successfully");
break;
}
// poll data agagin
records = consumer.poll(Duration.ofMillis(100));
for (ConsumerRecord<ResultBean> record : records) {
// process the data here
System.out.println("second data polled: " + JSON.toJSONString(record.value()));
break;
}
} catch (SQLException ex) {
// handle any errors, please refer to the JDBC specifications for detailed exceptions info
System.out.println("seek example failed; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw new SQLException("seek example failed", ex);
}
// ANCHOR_END: consumer_seek
}
public static void commitExample() throws SQLException {
// ANCHOR: commit_code_piece
try (TaosConsumer<ResultBean> consumer = getConsumer()){
List<String> topics = Collections.singletonList("topic_meters");
consumer.subscribe(topics);
for (int i = 0; i < 50; i++) {
ConsumerRecords<ResultBean> records = consumer.poll(Duration.ofMillis(100));
for (ConsumerRecord<ResultBean> record : records) {
ResultBean bean = record.value();
// process your data here
System.out.println("data: " + JSON.toJSONString(bean));
}
if (!records.isEmpty()) {
// after processing the data, commit the offset manually
consumer.commitSync();
}
}
} catch (SQLException ex){
// handle any errors, please refer to the JDBC specifications for detailed exceptions info
System.out.println("Failed to execute consumer functions. ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw new SQLException("Failed to execute consumer functions", ex);
}
// ANCHOR_END: commit_code_piece
}
public static void unsubscribeExample() throws SQLException {
TaosConsumer<ResultBean> consumer = getConsumer();
List<String> topics = Collections.singletonList("topic_meters");
consumer.subscribe(topics);
// ANCHOR: unsubscribe_data_code_piece
try {
consumer.unsubscribe();
} catch (SQLException ex){
// handle any errors, please refer to the JDBC specifications for detailed exceptions info
System.out.println("Failed to unsubscribe consumer. ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw new SQLException("Failed to unsubscribe consumer", ex);
} finally {
consumer.close();
}
// ANCHOR_END: unsubscribe_data_code_piece
}
public static class ResultDeserializer extends ReferenceDeserializer<ResultBean> {
}
// use this class to define the data structure of the result record
public static class ResultBean {
private Timestamp ts;
private double current;
private int voltage;
private double phase;
private int groupid;
private String location;
public Timestamp getTs() {
return ts;
}
public void setTs(Timestamp ts) {
this.ts = ts;
}
public double getCurrent() {
return current;
}
public void setCurrent(double current) {
this.current = current;
}
public int getVoltage() {
return voltage;
}
public void setVoltage(int voltage) {
this.voltage = voltage;
}
public double getPhase() {
return phase;
}
public void setPhase(double phase) {
this.phase = phase;
}
public int getGroupid() {
return groupid;
}
public void setGroupid(int groupid) {
this.groupid = groupid;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
}
public static void prepareData() throws SQLException{
StringBuilder insertQuery = new StringBuilder();
insertQuery.append("INSERT INTO " +
"power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " +
"VALUES ");
for (int i = 0; i < 10000; i++){
insertQuery.append("(NOW + ").append(i).append("a, 10.30000, 219, 0.31000) ");
}
try {
int affectedRows = statement.executeUpdate(insertQuery.toString());
assert affectedRows == 10000;
} catch (SQLException ex) {
System.out.println("Failed to insert data to power.meters, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw new SQLException("Failed to insert data to power.meters", ex);
}
}
public static void prepareMeta() throws SQLException{
try {
statement.executeUpdate("CREATE DATABASE IF NOT EXISTS power");
statement.executeUpdate("USE power");
statement.executeUpdate("CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))");
statement.executeUpdate("CREATE TOPIC IF NOT EXISTS topic_meters AS SELECT ts, current, voltage, phase, groupid, location FROM meters");
} catch (SQLException ex) {
System.out.println("Failed to create db and table, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw new SQLException("Failed to create db and table", ex);
}
}
public static void initConnection() throws SQLException {
String url = "jdbc:TAOS://localhost:6030?user=root&password=taosdata";
Properties properties = new Properties();
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "C");
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
try {
connection = DriverManager.getConnection(url, properties);
} catch (SQLException ex) {
System.out.println("Failed to create connection, url:" + url + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw new SQLException("Failed to create connection", ex);
}
try {
statement = connection.createStatement();
} catch (SQLException ex) {
System.out.println("Failed to create statement, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw new SQLException("Failed to create statement", ex);
}
System.out.println("Connection created successfully.");
}
public static void closeConnection() throws SQLException {
try {
if (statement != null) {
statement.close();
}
} catch (SQLException ex) {
System.out.println("Failed to close statement, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw new SQLException("Failed to close statement", ex);
}
try {
if (connection != null) {
connection.close();
}
} catch (SQLException ex) {
System.out.println("Failed to close connection, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw new SQLException("Failed to close connection", ex);
}
System.out.println("Connection closed Successfully.");
}
public static void main(String[] args) throws SQLException {
initConnection();
prepareMeta();
// create a single thread executor
ExecutorService executor = Executors.newSingleThreadExecutor();
// submit a task
executor.submit(() -> {
try {
// please use one example at a time
pollDataExample();
// seekExample();
// pollExample();
// commitExample();
unsubscribeExample();
} catch (SQLException ex) {
System.out.println("Failed to poll data from topic_meters, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
}
System.out.println("pollDataExample executed successfully");
});
prepareData();
closeConnection();
System.out.println("Data prepared successfully");
// 关闭线程池不再接收新任务
executor.shutdown();
try {
// 等待直到所有任务完成
boolean result = executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
assert result;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (Exception e){
e.printStackTrace();
System.out.println("Wait executor termination failed.");
}
System.out.println("program end.");
}
}
// ANCHOR_END: consumer_demo