Merge branch 'docs/wade-3.0' of github.com:taosdata/TDengine into docs/wade-3.0-shibin
This commit is contained in:
commit
8bb7cf5926
|
@ -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>
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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>
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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>
|
|
@ -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" />
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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": []
|
||||
}
|
|
@ -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"}}
|
|
@ -0,0 +1 @@
|
|||
17225691407520754
|
|
@ -0,0 +1 @@
|
|||
17225689181017775
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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())
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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())
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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": []
|
||||
}
|
|
@ -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"}}
|
|
@ -0,0 +1 @@
|
|||
17225691310239873
|
|
@ -0,0 +1 @@
|
|||
17225689180359712
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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>
|
|
@ -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" />
|
|
@ -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>
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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": []
|
||||
}
|
|
@ -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"}}
|
|
@ -0,0 +1 @@
|
|||
17225691490262111
|
|
@ -0,0 +1 @@
|
|||
17225689180408669
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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>
|
|
@ -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" />
|
|
@ -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>
|
|
@ -13,6 +13,6 @@ func main() {
|
|||
if err != nil {
|
||||
log.Fatalln("failed to connect, err:", err)
|
||||
} else {
|
||||
fmt.Println("connected")
|
||||
fmt.Println("Connected")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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".
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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".
|
||||
|
|
|
@ -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()
|
||||
}
|
|
@ -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
|
||||
)
|
||||
|
|
|
@ -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=
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
_ "github.com/taosdata/driver-go/v3/taosSql"
|
||||
)
|
||||
|
||||
func main() {
|
||||
db, err := sql.Open("taosSql", "root:taosdata@tcp(localhost:6030)/")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer db.Close()
|
||||
initEnv(db)
|
||||
// ANCHOR: query_id
|
||||
// use context to set request id
|
||||
ctx := context.WithValue(context.Background(), "taos_req_id", int64(3))
|
||||
// execute query with context
|
||||
rows, err := db.QueryContext(ctx, "SELECT ts, current, location FROM power.meters limit 1")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for rows.Next() {
|
||||
var (
|
||||
ts time.Time
|
||||
current float32
|
||||
location string
|
||||
)
|
||||
err = rows.Scan(&ts, ¤t, &location)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Printf("ts: %s, current: %f, location: %s\n", ts, current, location)
|
||||
}
|
||||
// ANCHOR_END: query_id
|
||||
}
|
||||
|
||||
func initEnv(conn *sql.DB) {
|
||||
_, err := conn.Exec("CREATE DATABASE IF NOT EXISTS power")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = conn.Exec("CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = conn.Exec("INSERT INTO power.d1001 USING power.meters TAGS (2, 'California.SanFrancisco') VALUES (NOW , 10.2, 219, 0.32)")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
_ "github.com/taosdata/driver-go/v3/taosSql"
|
||||
)
|
||||
|
||||
func main() {
|
||||
db, err := sql.Open("taosSql", "root:taosdata@tcp(localhost:6030)/")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer db.Close()
|
||||
// ANCHOR: create_db_and_table
|
||||
// create database
|
||||
res, err := db.Exec("CREATE DATABASE IF NOT EXISTS power")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
affected, err := res.RowsAffected()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println("create database affected:", affected)
|
||||
// use database
|
||||
res, err = db.Exec("USE power")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
affected, err = res.RowsAffected()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println("use database affected:", affected)
|
||||
// create table
|
||||
res, err = db.Exec("CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))")
|
||||
affected, err = res.RowsAffected()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println("create table affected:", affected)
|
||||
// ANCHOR_END: create_db_and_table
|
||||
// ANCHOR: insert_data
|
||||
// insert data, please make sure the database and table are created before
|
||||
insertQuery := "INSERT INTO " +
|
||||
"power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " +
|
||||
"VALUES " +
|
||||
"(NOW + 1a, 10.30000, 219, 0.31000) " +
|
||||
"(NOW + 2a, 12.60000, 218, 0.33000) " +
|
||||
"(NOW + 3a, 12.30000, 221, 0.31000) " +
|
||||
"power.d1002 USING power.meters TAGS(3, 'California.SanFrancisco') " +
|
||||
"VALUES " +
|
||||
"(NOW + 1a, 10.30000, 218, 0.25000) "
|
||||
res, err = db.Exec(insertQuery)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
affected, err = res.RowsAffected()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// you can check affectedRows here
|
||||
fmt.Println("insert data affected:", affected)
|
||||
// ANCHOR_END: insert_data
|
||||
// ANCHOR: select_data
|
||||
// query data, make sure the database and table are created before
|
||||
rows, err := db.Query("SELECT ts, current, location FROM power.meters limit 100")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for rows.Next() {
|
||||
var (
|
||||
ts time.Time
|
||||
current float32
|
||||
location string
|
||||
)
|
||||
err = rows.Scan(&ts, ¤t, &location)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// you can check data here
|
||||
fmt.Printf("ts: %s, current: %f, location: %s\n", ts, current, location)
|
||||
}
|
||||
// ANCHOR_END: select_data
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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{}{}
|
||||
}()
|
||||
}
|
|
@ -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{}{}
|
||||
}()
|
||||
}
|
|
@ -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(())
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
}
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
|
|
|
@ -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(())
|
||||
}
|
|
@ -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(())
|
||||
}
|
|
@ -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(())
|
||||
}
|
|
@ -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&...¶mN=valueN]
|
||||
```
|
||||
|
||||
完整形式的 DSN:
|
||||
|
||||
```text
|
||||
username:password@protocol(address)/dbname?param=value
|
||||
```
|
||||
|
||||
支持的 DSN 参数如下
|
||||
|
||||
原生连接:
|
||||
|
||||
- `cfg` 指定 taos.cfg 目录
|
||||
- `cgoThread` 指定 cgo 同时执行的数量,默认为系统核数
|
||||
- `cgoAsyncHandlerPoolSize` 指定异步函数的 handle 大小,默认为 10000
|
||||
|
||||
REST 连接:
|
||||
|
||||
- `disableCompression` 是否接受压缩数据,默认为 true 不接受压缩数据,如果传输数据使用 gzip 压缩设置为 false。
|
||||
- `readBufferSize` 读取数据的缓存区大小默认为 4K(4096),当查询结果数据量多时可以适当调大该值。
|
||||
- `token` 连接云服务时使用的 token。
|
||||
- `skipVerify` 是否跳过证书验证,默认为 false 不跳过证书验证,如果连接的是不安全的服务设置为 true。
|
||||
|
||||
WebSocket 连接:
|
||||
|
||||
- `enableCompression` 是否发送压缩数据,默认为 false 不发送压缩数据,如果传输数据使用压缩设置为 true。
|
||||
- `readTimeout` 读取数据的超时时间,默认为 5m。
|
||||
- `writeTimeout` 写入数据的超时时间,默认为 10s。
|
||||
|
||||
</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/>
|
||||
|
|
|
@ -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(毫秒),s(秒),m(分),h(小时),d(天),w(周),n(月),y(年)。
|
||||
</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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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">
|
||||
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -224,131 +224,161 @@ int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields)
|
|||
基础 API 用于完成创建数据库连接等工作,为其它 API 的执行提供运行时环境。
|
||||
|
||||
- `int taos_init()`
|
||||
|
||||
初始化运行环境。如果没有主动调用该 API,那么调用 `taos_connect()` 时驱动将自动调用该 API,故程序一般无需手动调用。
|
||||
- **接口说明**:初始化运行环境。如果没有主动调用该 API,那么调用 `taos_connect()` 时驱动将自动调用该 API,故程序一般无需手动调用。
|
||||
- **返回值**:待补充,未找到相关资料。
|
||||
|
||||
- `void taos_cleanup()`
|
||||
|
||||
清理运行环境,应用退出前应调用。
|
||||
- **接口说明**:清理运行环境,应用退出前应调用。
|
||||
|
||||
- `int taos_options(TSDB_OPTION option, const void * arg, ...)`
|
||||
|
||||
设置客户端选项,目前支持区域设置(`TSDB_OPTION_LOCALE`)、字符集设置(`TSDB_OPTION_CHARSET`)、时区设置(`TSDB_OPTION_TIMEZONE`)、配置文件路径设置(`TSDB_OPTION_CONFIGDIR`)。区域设置、字符集、时区默认为操作系统当前设置。
|
||||
- **接口说明**:设置客户端选项,目前支持区域设置(`TSDB_OPTION_LOCALE`)、字符集设置(`TSDB_OPTION_CHARSET`)、时区设置(`TSDB_OPTION_TIMEZONE`)、配置文件路径设置(`TSDB_OPTION_CONFIGDIR`)。区域设置、字符集、时区默认为操作系统当前设置。
|
||||
- **参数说明**:
|
||||
- `option`:[入参] 设置项类型。
|
||||
- `arg`:[入参] 设置项值。
|
||||
- **返回值**:`0`:成功,`-1`:失败。
|
||||
|
||||
- `char *taos_get_client_info()`
|
||||
- **接口说明**:获取客户端版本信息。
|
||||
- **返回值**:返回客户端版本信息。
|
||||
|
||||
获取客户端版本信息。
|
||||
|
||||
- `TAOS *taos_connect(const char *host, const char *user, const char *pass, const char *db, int port)`
|
||||
|
||||
创建数据库连接,初始化连接上下文。其中需要用户提供的参数包含:
|
||||
|
||||
- host:TDengine 集群中任一节点的 FQDN
|
||||
- user:用户名
|
||||
- pass:密码
|
||||
- db: 数据库名字,如果用户没有提供,也可以正常连接,用户可以通过该连接创建新的数据库,如果用户提供了数据库名字,则说明该数据库用户已经创建好,缺省使用该数据库
|
||||
- port:taosd 程序监听的端口
|
||||
|
||||
返回值为空表示失败。应用程序需要保存返回的参数,以便后续使用。
|
||||
|
||||
- `TAOS *taos_connect(const char *ip, const char *user, const char *pass, const char *db, uint16_t port);`
|
||||
- **接口说明**:创建数据库连接,初始化连接上下文。
|
||||
- **参数说明**:
|
||||
- ip:[入参] TDengine 集群中任一节点的 FQDN。
|
||||
- user:[入参] 用户名。
|
||||
- pass:[入参] 密码。
|
||||
- db:[入参] 数据库名字,如果用户没有提供,也可以正常连接,用户可以通过该连接创建新的数据库,如果用户提供了数据库名字,则说明该数据库用户已经创建好,缺省使用该数据库。
|
||||
- port:[入参] taosd 程序监听的端口。
|
||||
- **返回值**:返回数据库连接,返回值为空表示失败。应用程序需要保存返回的参数,以便后续使用。
|
||||
:::info
|
||||
同一进程可以根据不同的 host/port 连接多个 TDengine 集群
|
||||
|
||||
:::
|
||||
|
||||
- `TAOS *taos_connect_auth(const char *host, const char *user, const char *auth, const char *db, uint16_t port)`
|
||||
|
||||
功能同 taos_connect。除 pass 参数替换为 auth 外,其他参数同 taos_connect。
|
||||
|
||||
- auth: 原始密码取 32 位小写 md5
|
||||
- **接口说明**:功能同 taos_connect。除 pass 参数替换为 auth 外,其他参数同 taos_connect。
|
||||
- **参数说明**:
|
||||
- ip:[入参] TDengine 集群中任一节点的 FQDN。
|
||||
- user:[入参] 用户名。
|
||||
- auth: [入参] 原始密码取 32 位小写 md5。
|
||||
- db:[入参] 数据库名称,如果用户没有提供,也可以正常连接,用户可以通过该连接创建新的数据库,如果用户提供了数据库名字,则说明该数据库用户已经创建好,缺省使用该数据库。
|
||||
- port:[入参] taosd 程序监听的端口。
|
||||
- **返回值**:返回数据库连接,返回值为空表示失败。应用程序需要保存返回的参数,以便后续使用。
|
||||
|
||||
- `char *taos_get_server_info(TAOS *taos)`
|
||||
|
||||
获取服务端版本信息。
|
||||
- **接口说明**:获取服务端版本信息。
|
||||
- **参数说明**:
|
||||
- taos:[入参] 数据库连接。
|
||||
- **返回值**:返回获取服务端版本信息。
|
||||
|
||||
- `int taos_select_db(TAOS *taos, const char *db)`
|
||||
|
||||
将当前的缺省数据库设置为 `db`。
|
||||
- **接口说明**:将当前的缺省数据库设置为 `db`。
|
||||
- **参数说明**:
|
||||
- taos:[入参] 数据库连接。
|
||||
- db:[入参] 数据库名称。
|
||||
- **返回值**:`0`:成功,`非0`:失败,详情请参考错误码。待补充。
|
||||
|
||||
- `int taos_get_current_db(TAOS *taos, char *database, int len, int *required)`
|
||||
|
||||
- database,len为用户在外面申请的空间,内部会把当前db赋值到database里。
|
||||
- 只要是没有正常把db名赋值到database中(包括截断),返回错误,返回值为-1,然后用户可以通过 taos_errstr(NULL) 来获取错误提示。
|
||||
- 如果,database == NULL 或者 len\<=0 返回错误,required里保存存储db需要的空间(包含最后的'\0')
|
||||
- 如果,len 小于 存储db需要的空间(包含最后的'\0'),返回错误,database里赋值截断的数据,以'\0'结尾。
|
||||
- 如果,len 大于等于 存储db需要的空间(包含最后的'\0'),返回正常0,database里赋值以'\0‘结尾的db名。
|
||||
- **接口说明**:获取当前数据库名称。
|
||||
- **参数说明**:
|
||||
- taos:[入参] 数据库连接。
|
||||
- database:[出参] 存储当前数据库名称。
|
||||
- len:[入参] database 的空间大小。
|
||||
- required:[出参] 存储当前数据库名称所需的空间(包含最后的'\0')。
|
||||
- **返回值**:`0`:成功,`-1`:失败,详情请调用 taos_errstr(NULL) 函数来获取错误提示。
|
||||
- 如果,database == NULL 或者 len\<=0 返回失败。
|
||||
- 如果,len 小于 存储数据库名称所需的空间(包含最后的'\0'),返回失败,database 里赋值截断的数据,以'\0'结尾。
|
||||
- 如果,len 大于等于 存储数据库名称所需的空间(包含最后的'\0'),返回成功,database 里赋值以'\0‘结尾数据库名称。
|
||||
|
||||
- `int taos_set_notify_cb(TAOS *taos, __taos_notify_fn_t fp, void *param, int type)`
|
||||
|
||||
设置事件回调函数。
|
||||
|
||||
- fp 事件回调函数指针。函数声明:typedef void (*__taos_notify_fn_t)(void *param, void *ext, int type);其中, param 为用户自定义参数,ext 为扩展参数(依赖事件类型,针对 TAOS_NOTIFY_PASSVER 返回用户密码版本),type 为事件类型
|
||||
- param 用户自定义参数
|
||||
- type 事件类型。取值范围:1)TAOS_NOTIFY_PASSVER: 用户密码改变
|
||||
- **接口说明**:设置事件回调函数。
|
||||
- **参数说明**:
|
||||
- taos:[入参] 数据库连接。
|
||||
- fp:[入参] 事件回调函数指针。函数声明:typedef void (*__taos_notify_fn_t)(void *param, void *ext, int type);其中, param 为用户自定义参数,ext 为扩展参数(依赖事件类型,针对 TAOS_NOTIFY_PASSVER 返回用户密码版本),type 为事件类型。
|
||||
- param:[入参] 用户自定义参数。
|
||||
- type:[入参] 事件类型。取值范围:1)TAOS_NOTIFY_PASSVER: 用户密码改变。
|
||||
- **返回值**:`0`:成功,`-1`:失败,详情请调用 taos_errstr(NULL) 函数来获取错误提示。
|
||||
|
||||
- `void taos_close(TAOS *taos)`
|
||||
|
||||
关闭连接,其中`taos`是 `taos_connect()` 返回的句柄。
|
||||
- **接口说明**:关闭连接。
|
||||
- **参数说明**:
|
||||
- taos:[入参] 数据库连接。
|
||||
|
||||
### 同步查询 API
|
||||
|
||||
本小节介绍 API 均属于同步接口。应用调用后,会阻塞等待响应,直到获得返回结果或错误信息。
|
||||
|
||||
- `TAOS_RES* taos_query(TAOS *taos, const char *sql)`
|
||||
|
||||
执行 SQL 语句,可以是 DQL、DML 或 DDL 语句。 其中的 `taos` 参数是通过 `taos_connect()` 获得的句柄。不能通过返回值是否是 `NULL` 来判断执行结果是否失败,而是需要用 `taos_errno()` 函数解析结果集中的错误代码来进行判断。
|
||||
- **接口说明**:执行 SQL 语句,可以是 DQL、DML 或 DDL 语句。
|
||||
- **参数说明**:
|
||||
- taos:[入参] 数据库连接。
|
||||
- sql:[入参] 需要执行 SQL 语句。
|
||||
- **返回值**:不能通过返回值是否是 `NULL` 来判断执行结果是否失败,而是需要调用 `taos_errno()` 函数解析结果集中的错误代码来进行判断。
|
||||
- taos_errno 返回值:`0`:成功,`-1`:失败,详情请调用 taos_errstr 函数来获取错误提示。
|
||||
|
||||
- `int taos_result_precision(TAOS_RES *res)`
|
||||
|
||||
返回结果集时间戳字段的精度,`0` 代表毫秒,`1` 代表微秒,`2` 代表纳秒。
|
||||
- **接口说明**:返回结果集时间戳字段的精度类别。
|
||||
- **参数说明**:
|
||||
- res:[入参] 结果集。
|
||||
- **返回值**:`0`:毫秒,`1`:微秒,`2`:纳秒。
|
||||
|
||||
- `TAOS_ROW taos_fetch_row(TAOS_RES *res)`
|
||||
|
||||
按行获取查询结果集中的数据。
|
||||
- **接口说明**:按行获取查询结果集中的数据。
|
||||
- **参数说明**:
|
||||
- res:[入参] 查询结果集。
|
||||
- **返回值**:`非NULL`:成功,`NULL`:失败,详情请调用 taos_errstr(NULL) 函数来获取错误提示。
|
||||
|
||||
- `int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows)`
|
||||
|
||||
批量获取查询结果集中的数据,返回值为获取到的数据的行数。
|
||||
- **接口说明**:批量获取查询结果集中的数据。
|
||||
- **参数说明**:
|
||||
- res:[入参] 查询结果集。
|
||||
- rows:[出参] 用于存储从结果集中获取的行。
|
||||
- **返回值**:返回值为获取到的数据的行数,如果没有更多的行则返回 0。
|
||||
|
||||
- `int taos_num_fields(TAOS_RES *res)` 和 `int taos_field_count(TAOS_RES *res)`
|
||||
|
||||
这两个 API 等价,用于获取查询结果集中的列数。
|
||||
- **接口说明**:这两个 API 等价,用于获取查询结果集中的列数。
|
||||
- **参数说明**:
|
||||
- res:[入参] 查询结果集。
|
||||
- **返回值**:返回值为结果集中列的数量。
|
||||
|
||||
- `int* taos_fetch_lengths(TAOS_RES *res)`
|
||||
|
||||
获取结果集中每个字段的长度。返回值是一个数组,其长度为结果集的列数。
|
||||
- **接口说明**:获取结果集中每个字段的长度。
|
||||
- **参数说明**:
|
||||
- res:[入参] 结果集。
|
||||
- **返回值**:返回值是一个数组,其长度为结果集的列数。
|
||||
|
||||
- `int taos_affected_rows(TAOS_RES *res)`
|
||||
|
||||
获取被所执行的 SQL 语句影响的行数。
|
||||
- **接口说明**:获取被所执行的 SQL 语句影响的行数。
|
||||
- **参数说明**:
|
||||
- res:[入参] 结果集。
|
||||
- **返回值**:返回值表示受影响的行数。
|
||||
|
||||
- `TAOS_FIELD *taos_fetch_fields(TAOS_RES *res)`
|
||||
|
||||
获取查询结果集每列数据的属性(列的名称、列的数据类型、列的长度),与 `taos_num_fields()` 配合使用,可用来解析 `taos_fetch_row()` 返回的一个元组(一行)的数据。 `TAOS_FIELD` 的结构如下:
|
||||
|
||||
```c
|
||||
typedef struct taosField {
|
||||
char name[65]; // column name
|
||||
uint8_t type; // data type
|
||||
int16_t bytes; // length, in bytes
|
||||
} TAOS_FIELD;
|
||||
```
|
||||
- **接口说明**:获取查询结果集每列数据的属性(列的名称、列的数据类型、列的长度),与 `taos_num_fields()` 配合使用,可用来解析 `taos_fetch_row()` 返回的一个元组(一行)的数据。
|
||||
- **参数说明**:
|
||||
- res:[入参] 查询结果集。
|
||||
- **返回值**:`非NULL`:成功,返回一个指向 TAOS_FIELD 结构体的指针,每个元素代表一列的元数据。`NULL`:失败。
|
||||
|
||||
- `void taos_stop_query(TAOS_RES *res)`
|
||||
|
||||
停止当前查询的执行。
|
||||
- **接口说明**:停止当前查询的执行。
|
||||
- **参数说明**:
|
||||
- res:[入参] 查询结果集。
|
||||
|
||||
- `void taos_free_result(TAOS_RES *res)`
|
||||
|
||||
释放查询结果集以及相关的资源。查询完成后,务必调用该 API 释放资源,否则可能导致应用内存泄露。但也需注意,释放资源后,如果再调用 `taos_consume()` 等获取查询结果的函数,将导致应用崩溃。
|
||||
- **接口说明**:释放查询结果集以及相关的资源。查询完成后,务必调用该 API 释放资源,否则可能导致应用内存泄露。但也需注意,释放资源后,如果再调用 `taos_consume()` 等获取查询结果的函数,将导致应用崩溃。
|
||||
- **参数说明**:
|
||||
- res:[入参] 查询结果集。
|
||||
|
||||
- `char *taos_errstr(TAOS_RES *res)`
|
||||
|
||||
获取最近一次 API 调用失败的原因,返回值为字符串标识的错误提示信息。
|
||||
- **接口说明**:获取最近一次 API 调用失败的原因,返回值为字符串标识的错误提示信息。
|
||||
- **参数说明**:
|
||||
- res:[入参] 结果集。
|
||||
- **返回值**:字符串标识的错误提示信息。
|
||||
|
||||
- `int taos_errno(TAOS_RES *res)`
|
||||
|
||||
获取最近一次 API 调用失败的原因,返回值为错误代码。
|
||||
- **接口说明**:获取最近一次 API 调用失败的原因,返回值为错误代码。
|
||||
- **参数说明**:
|
||||
- res:[入参] 结果集。
|
||||
- **返回值**:字符串标识的错误提示信息。
|
||||
|
||||
:::note
|
||||
2.0 及以上版本 TDengine 推荐数据库应用的每个线程都建立一个独立的连接,或基于线程建立连接池。而不推荐在应用中将该连接 (TAOS\*) 结构体传递到不同的线程共享使用。基于 TAOS 结构体发出的查询、写入等操作具有多线程安全性,但 “USE statement” 等状态量有可能在线程之间相互干扰。此外,C 语言的连接器可以按照需求动态建立面向数据库的新连接(该过程对用户不可见),同时建议只有在程序最后退出的时候才调用 `taos_close()` 关闭连接。
|
||||
|
@ -365,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 均采用非阻塞调用模式。应用程序可以用多线程同时打开多张表,并可以同时对每张打开的表进行查询或者插入操作。需要指出的是,**客户端应用必须确保对同一张表的操作完全串行化**,即对同一个表的插入或查询操作未完成时(未返回时),不能够执行第二个插入或查询操作。
|
||||
|
|
|
@ -12,16 +12,6 @@ import RequestId from "./_request_id.mdx";
|
|||
|
||||
`driver-go` 是 TDengine 的官方 Go 语言连接器,实现了 Go 语言 [database/sql](https://golang.org/pkg/database/sql/) 包的接口。Go 开发人员可以通过它开发存取 TDengine 集群数据的应用软件。
|
||||
|
||||
## 连接方式
|
||||
|
||||
`driver-go` 提供三种建立连接的方式。
|
||||
|
||||
* **原生连接**,通过 TDengine 客户端驱动程序(taosc)原生连接 TDengine 实例,支持数据写入、查询、数据订阅、schemaless 接口和参数绑定接口等功能。
|
||||
* **REST 连接**,通过 taosAdapter 提供的 HTTP 接口连接 TDengine 实例,不支持 schemaless 和数据订阅等特性。
|
||||
* **Websocket 连接**,通过 taosAdapter 提供的 Websocket 接口连接 TDengine 实例,WebSocket 连接实现的功能集合和原生连接有少量不同。
|
||||
|
||||
连接方式的详细介绍请参考:[连接器建立连接的方式](../../develop/connect/#连接器建立连接的方式)
|
||||
|
||||
## 兼容性
|
||||
|
||||
支持最低 Go 版本 1.14,建议使用最新 Go 版本
|
||||
|
@ -74,300 +64,6 @@ REST 连接支持所有能运行 Go 的平台。
|
|||
|
||||
**注意**:JSON 类型仅在 tag 中支持。
|
||||
|
||||
## 安装步骤
|
||||
|
||||
### 安装前准备
|
||||
|
||||
* 安装 Go 开发环境(Go 1.14 及以上,GCC 4.8.5 及以上)
|
||||
* 如果使用原生连接器,请安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../#安装客户端驱动)
|
||||
|
||||
配置好环境变量,检查命令:
|
||||
|
||||
* ```go env```
|
||||
* ```gcc -v```
|
||||
|
||||
### 安装连接器
|
||||
|
||||
1. 使用 `go mod` 命令初始化项目:
|
||||
|
||||
```text
|
||||
go mod init taos-demo
|
||||
```
|
||||
|
||||
2. 引入 taosSql :
|
||||
|
||||
```go
|
||||
import (
|
||||
"database/sql"
|
||||
_ "github.com/taosdata/driver-go/v3/taosSql"
|
||||
)
|
||||
```
|
||||
|
||||
3. 使用 `go mod tidy` 更新依赖包:
|
||||
|
||||
```text
|
||||
go mod tidy
|
||||
```
|
||||
|
||||
4. 使用 `go run taos-demo` 运行程序或使用 `go build` 命令编译出二进制文件。
|
||||
|
||||
```text
|
||||
go run taos-demo
|
||||
go build
|
||||
```
|
||||
|
||||
## 建立连接
|
||||
|
||||
数据源名称具有通用格式,例如 [PEAR DB](http://pear.php.net/manual/en/package.database.db.intro-dsn.php),但没有类型前缀(方括号表示可选):
|
||||
|
||||
``` text
|
||||
[username[:password]@][protocol[(address)]]/[dbname][?param1=value1&...¶mN=valueN]
|
||||
```
|
||||
|
||||
完整形式的 DSN:
|
||||
|
||||
```text
|
||||
username:password@protocol(address)/dbname?param=value
|
||||
```
|
||||
|
||||
<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` 读取数据的缓存区大小默认为 4K(4096),当查询结果数据量多时可以适当调大该值。
|
||||
|
||||
示例:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
|
||||
_ "github.com/taosdata/driver-go/v3/taosRestful"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var taosUri = "root:taosdata@http(localhost:6041)/"
|
||||
taos, err := sql.Open("taosRestful", taosUri)
|
||||
if err != nil {
|
||||
fmt.Println("failed to connect TDengine, err:", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</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)。
|
||||
|
|
|
@ -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
|
@ -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 {
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue