Merge remote-tracking branch 'origin/docs/wade-3.0' into docs/wade-3.0-pym

This commit is contained in:
Yaming Pei 2024-08-02 20:59:59 +08:00
commit 7bef4d5e3f
93 changed files with 4547 additions and 3434 deletions

View File

@ -172,7 +172,7 @@ npm install @tdengine/rest
Just need to add the reference to [TDengine.Connector](https://www.nuget.org/packages/TDengine.Connector/) in the project configuration file.
```xml title=csharp.csproj {12}
```xml title=csharp.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>

View File

@ -0,0 +1,122 @@
/*
* 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 CSmlInsertDemo CSmlInsertDemo.c -ltaos
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "taos.h"
static int DemoSmlInsert() {
// ANCHOR: schemaless
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));
taos_cleanup();
return -1;
}
// 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));
taos_close(taos);
taos_cleanup();
return -1;
}
taos_free_result(result);
printf("success to create database\n");
// use database
result = taos_query(taos, "USE power");
taos_free_result(result);
// schemaless demo data
char * line_demo = "meters,groupid=2,location=California.SanFrancisco current=10.3000002f64,voltage=219i32,phase=0.31f64 1626006833639";
char * telnet_demo = "metric_telnet 1707095283260 4 host=host0 interface=eth0";
char * json_demo = "{\"metric\": \"metric_json\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}";
// influxdb line protocol
char *lines[] = {line_demo};
result = taos_schemaless_insert(taos, lines, 1, TSDB_SML_LINE_PROTOCOL, TSDB_SML_TIMESTAMP_MILLI_SECONDS);
if (taos_errno(result) != 0) {
printf("failed to insert schemaless line data, reason: %s\n", taos_errstr(result));
taos_close(taos);
taos_cleanup();
return -1;
}
int rows = taos_affected_rows(result);
printf("success to insert %d rows of schemaless line data\n", rows);
taos_free_result(result);
// opentsdb telnet protocol
char *telnets[] = {telnet_demo};
result = taos_schemaless_insert(taos, telnets, 1, TSDB_SML_TELNET_PROTOCOL, TSDB_SML_TIMESTAMP_MILLI_SECONDS);
if (taos_errno(result) != 0) {
printf("failed to insert schemaless telnet data, reason: %s\n", taos_errstr(result));
taos_close(taos);
taos_cleanup();
return -1;
}
rows = taos_affected_rows(result);
printf("success to insert %d rows of schemaless telnet data\n", rows);
taos_free_result(result);
// opentsdb json protocol
char *jsons[1] = {0};
// allocate memory for json data. can not use static memory.
jsons[0] = malloc(1024);
if (jsons[0] == NULL) {
printf("failed to allocate memory\n");
taos_close(taos);
taos_cleanup();
return -1;
}
(void)strncpy(jsons[0], json_demo, 1023);
result = taos_schemaless_insert(taos, jsons, 1, TSDB_SML_JSON_PROTOCOL, TSDB_SML_TIMESTAMP_NOT_CONFIGURED);
if (taos_errno(result) != 0) {
free(jsons[0]);
printf("failed to insert schemaless json data, reason: %s\n", taos_errstr(result));
taos_close(taos);
taos_cleanup();
return -1;
}
free(jsons[0]);
rows = taos_affected_rows(result);
printf("success to insert %d rows of schemaless json data\n", rows);
taos_free_result(result);
// close & clean
taos_close(taos);
taos_cleanup();
return 0;
// ANCHOR_END: schemaless
}
int main(int argc, char *argv[]) {
return DemoSmlInsert();
}

View File

@ -0,0 +1,175 @@
/*
* 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 CStmtInsertDemo CStmtInsertDemo.c -ltaos
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include "taos.h"
/**
* @brief execute sql only.
*
* @param taos
* @param sql
*/
void executeSQL(TAOS *taos, const char *sql) {
TAOS_RES *res = taos_query(taos, sql);
int code = taos_errno(res);
if (code != 0) {
printf("%s\n", taos_errstr(res));
taos_free_result(res);
taos_close(taos);
exit(EXIT_FAILURE);
}
taos_free_result(res);
}
/**
* @brief check return status and exit program when error occur.
*
* @param stmt
* @param code
* @param msg
*/
void checkErrorCode(TAOS_STMT *stmt, int code, const char *msg) {
if (code != 0) {
printf("%s. code: %d, error: %s\n", msg,code,taos_stmt_errstr(stmt));
taos_stmt_close(stmt);
exit(EXIT_FAILURE);
}
}
typedef struct {
int64_t ts;
float current;
int voltage;
float phase;
} Row;
int num_of_sub_table = 10;
int num_of_row = 10;
/**
* @brief insert data using stmt API
*
* @param taos
*/
void insertData(TAOS *taos) {
// init
TAOS_STMT *stmt = taos_stmt_init(taos);
// prepare
const char *sql = "INSERT INTO ? USING meters TAGS(?,?) VALUES (?,?,?,?)";
int code = taos_stmt_prepare(stmt, sql, 0);
checkErrorCode(stmt, code, "failed to execute taos_stmt_prepare");
for (int i = 1; i <= num_of_sub_table; i++) {
char table_name[20];
sprintf(table_name, "d_bind_%d", i);
char location[20];
sprintf(location, "location_%d", i);
// set table name and tags
TAOS_MULTI_BIND tags[2];
// groupId
tags[0].buffer_type = TSDB_DATA_TYPE_INT;
tags[0].buffer_length = sizeof(int);
tags[0].length = (int32_t *)&tags[0].buffer_length;
tags[0].buffer = &i;
tags[0].is_null = NULL;
tags[0].num = 1;
// location
tags[1].buffer_type = TSDB_DATA_TYPE_BINARY;
tags[1].buffer_length = strlen(location);
tags[1].length =(int32_t *) &tags[1].buffer_length;
tags[1].buffer = location;
tags[1].is_null = NULL;
tags[1].num = 1;
code = taos_stmt_set_tbname_tags(stmt, table_name, tags);
checkErrorCode(stmt, code, "failed to set table name and tags\n");
// insert rows
TAOS_MULTI_BIND params[4];
// ts
params[0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP;
params[0].buffer_length = sizeof(int64_t);
params[0].length = (int32_t *)&params[0].buffer_length;
params[0].is_null = NULL;
params[0].num = 1;
// current
params[1].buffer_type = TSDB_DATA_TYPE_FLOAT;
params[1].buffer_length = sizeof(float);
params[1].length = (int32_t *)&params[1].buffer_length;
params[1].is_null = NULL;
params[1].num = 1;
// voltage
params[2].buffer_type = TSDB_DATA_TYPE_INT;
params[2].buffer_length = sizeof(int);
params[2].length = (int32_t *)&params[2].buffer_length;
params[2].is_null = NULL;
params[2].num = 1;
// phase
params[3].buffer_type = TSDB_DATA_TYPE_FLOAT;
params[3].buffer_length = sizeof(float);
params[3].length = (int32_t *)&params[3].buffer_length;
params[3].is_null = NULL;
params[3].num = 1;
for (int j = 0; j < num_of_row; j++) {
struct timeval tv;
gettimeofday(&tv, NULL);
long long milliseconds = tv.tv_sec * 1000LL + tv.tv_usec / 1000; // current timestamp in milliseconds
int64_t ts = milliseconds + j;
float current = (float)rand() / RAND_MAX * 30;
int voltage = rand() % 300;
float phase = (float)rand() / RAND_MAX;
params[0].buffer = &ts;
params[1].buffer = &current;
params[2].buffer = &voltage;
params[3].buffer = &phase;
// bind param
code = taos_stmt_bind_param(stmt, params);
checkErrorCode(stmt, code, "failed to bind param");
}
// add batch
code = taos_stmt_add_batch(stmt);
checkErrorCode(stmt, code, "failed to add batch");
// execute batch
code = taos_stmt_execute(stmt);
checkErrorCode(stmt, code, "failed to exec stmt");
// get affected rows
int affected = taos_stmt_affected_rows_once(stmt);
printf("table %s insert %d rows.\n", table_name, affected);
}
taos_stmt_close(stmt);
}
int main() {
TAOS *taos = taos_connect("localhost", "root", "taosdata", NULL, 6030);
if (taos == NULL) {
printf("failed to connect to server\n");
exit(EXIT_FAILURE);
}
// create database and table
executeSQL(taos, "CREATE DATABASE IF NOT EXISTS power");
executeSQL(taos, "USE power");
executeSQL(taos,
"CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS "
"(groupId INT, location BINARY(24))");
insertData(taos);
taos_close(taos);
taos_cleanup();
}

View File

@ -3,6 +3,7 @@
connect/bin
influxdbLine/bin
optsJSON/bin
nativesml/bin
optsTelnet/bin
query/bin
sqlInsert/bin
@ -11,9 +12,12 @@ subscribe/bin
wsConnect/bin
wsInsert/bin
wsQuery/bin
wssml/bin
wsStmt/bin
wssubscribe/bin
connect/obj
influxdbLine/obj
nativesml/obj
optsJSON/obj
optsTelnet/obj
query/obj
@ -23,4 +27,6 @@ subscribe/obj
wsConnect/obj
wsInsert/obj
wsQuery/obj
wsStmt/obj
wssml/obj
wsStmt/obj
wssubscribe/obj

View File

@ -3,16 +3,35 @@ using TDengine.Driver.Client;
namespace TDengineExample
{
internal class ConnectExample
{
// ANCHOR: main
static void Main(String[] args)
{
var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata");
using (var client = DbDriver.Open(builder))
var connectionString = "host=127.0.0.1;port=6030;username=root;password=taosdata";
try
{
Console.WriteLine("connected");
// Connect to TDengine server using Native
var builder = new ConnectionStringBuilder(connectionString);
// Open connection with using block, it will close the connection automatically
using (var client = DbDriver.Open(builder))
{
Console.WriteLine("Connected to " + connectionString + " successfully.");
}
}
catch (TDengineError e)
{
// handle TDengine error
Console.WriteLine("Failed to connect to " + connectionString + "; ErrCode:" + e.Code + "; ErrMessage: " + e.Error);
throw;
}
catch (Exception e)
{
// handle other exceptions
Console.WriteLine("Failed to connect to " + connectionString + "; Err:" + e.Message);
throw;
}
}
// ANCHOR_END: main
}
}
}

View File

@ -27,6 +27,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wsStmt", "wsStmt\wsStmt.csp
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "sqlinsert", "sqlInsert\sqlinsert.csproj", "{CD24BD12-8550-4627-A11D-707B446F48C3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nativesml", "nativesml\nativesml.csproj", "{18ADDBE8-B266-4A66-8CC5-CFF80B530EFD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wssml", "wssml\wssml.csproj", "{C3E62FDB-CCBC-4F72-ACF6-D3B2C39630E3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wssubscribe", "wssubscribe\wssubscribe.csproj", "{CB4BCBA5-C758-433F-8B90-7389F59E46BD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -84,5 +90,17 @@ Global
{CD24BD12-8550-4627-A11D-707B446F48C3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CD24BD12-8550-4627-A11D-707B446F48C3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CD24BD12-8550-4627-A11D-707B446F48C3}.Release|Any CPU.Build.0 = Release|Any CPU
{18ADDBE8-B266-4A66-8CC5-CFF80B530EFD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{18ADDBE8-B266-4A66-8CC5-CFF80B530EFD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{18ADDBE8-B266-4A66-8CC5-CFF80B530EFD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{18ADDBE8-B266-4A66-8CC5-CFF80B530EFD}.Release|Any CPU.Build.0 = Release|Any CPU
{C3E62FDB-CCBC-4F72-ACF6-D3B2C39630E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C3E62FDB-CCBC-4F72-ACF6-D3B2C39630E3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C3E62FDB-CCBC-4F72-ACF6-D3B2C39630E3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C3E62FDB-CCBC-4F72-ACF6-D3B2C39630E3}.Release|Any CPU.Build.0 = Release|Any CPU
{CB4BCBA5-C758-433F-8B90-7389F59E46BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CB4BCBA5-C758-433F-8B90-7389F59E46BD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CB4BCBA5-C758-433F-8B90-7389F59E46BD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CB4BCBA5-C758-433F-8B90-7389F59E46BD}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,57 @@
using TDengine.Driver;
using TDengine.Driver.Client;
namespace TDengineExample
{
internal class NativeSMLExample
{
// ANCHOR: main
public static void Main(string[] args)
{
var host = "127.0.0.1";
var lineDemo =
"meters,groupid=2,location=California.SanFrancisco current=10.3000002f64,voltage=219i32,phase=0.31f64 1626006833639";
var telnetDemo = "metric_telnet 1707095283260 4 host=host0 interface=eth0";
var jsonDemo =
"{\"metric\": \"metric_json\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}";
try
{
var builder =
new ConnectionStringBuilder(
$"host={host};port=6030;username=root;password=taosdata");
using (var client = DbDriver.Open(builder))
{
// create database
client.Exec("CREATE DATABASE IF NOT EXISTS power");
// use database
client.Exec("USE power");
// insert influx line protocol data
client.SchemalessInsert(new[]{lineDemo}, TDengineSchemalessProtocol.TSDB_SML_LINE_PROTOCOL,
TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS, 0, ReqId.GetReqId());
// insert opentsdb telnet protocol data
client.SchemalessInsert(new[]{telnetDemo}, TDengineSchemalessProtocol.TSDB_SML_TELNET_PROTOCOL,
TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS, 0, ReqId.GetReqId());
// insert json data
client.SchemalessInsert(new []{jsonDemo}, TDengineSchemalessProtocol.TSDB_SML_JSON_PROTOCOL,
TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_NOT_CONFIGURED, 0, ReqId.GetReqId());
}
}
catch (TDengineError e)
{
// handle TDengine error
Console.WriteLine("Failed to insert data with schemaless; ErrCode:" + e.Code + "; ErrMessage: " + e.Error);
throw;
}
catch (Exception e)
{
// handle other exceptions
Console.WriteLine("Failed to insert data with schemaless; Err:" + e.Message);
throw;
}
}
// ANCHOR_END: main
}
}

View File

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

View File

@ -7,22 +7,51 @@ namespace TDengineExample
{
public static void Main(string[] args)
{
var builder =
new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata");
using (var client = DbDriver.Open(builder))
// ANCHOR: main
var host = "127.0.0.1";
var lineDemo =
"meters,groupid=2,location=California.SanFrancisco current=10.3000002f64,voltage=219i32,phase=0.31f64 1626006833639";
var telnetDemo = "metric_telnet 1707095283260 4 host=host0 interface=eth0";
var jsonDemo =
"{\"metric\": \"metric_json\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}";
try
{
client.Exec("CREATE DATABASE test WAL_RETENTION_PERIOD 3600");
client.Exec("use test");
string[] lines =
var builder =
new ConnectionStringBuilder(
$"protocol=WebSocket;host={host};port=6041;username=root;password=taosdata");
using (var client = DbDriver.Open(builder))
{
"[{\"metric\": \"meters.current\", \"timestamp\": 1648432611249, \"value\": 10.3, \"tags\": {\"location\": \"California.SanFrancisco\", \"groupid\": 2}}," +
" {\"metric\": \"meters.voltage\", \"timestamp\": 1648432611249, \"value\": 219, \"tags\": {\"location\": \"California.LosAngeles\", \"groupid\": 1}}, " +
"{\"metric\": \"meters.current\", \"timestamp\": 1648432611250, \"value\": 12.6, \"tags\": {\"location\": \"California.SanFrancisco\", \"groupid\": 2}}," +
" {\"metric\": \"meters.voltage\", \"timestamp\": 1648432611250, \"value\": 221, \"tags\": {\"location\": \"California.LosAngeles\", \"groupid\": 1}}]"
};
client.SchemalessInsert(lines, TDengineSchemalessProtocol.TSDB_SML_JSON_PROTOCOL,
TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS, 0, ReqId.GetReqId());
// create database
client.Exec("CREATE DATABASE IF NOT EXISTS power");
// use database
client.Exec("USE power");
// insert influx line protocol data
client.SchemalessInsert(new[]{lineDemo}, TDengineSchemalessProtocol.TSDB_SML_LINE_PROTOCOL,
TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS, 0, ReqId.GetReqId());
// insert opentsdb telnet protocol data
client.SchemalessInsert(new[]{telnetDemo}, TDengineSchemalessProtocol.TSDB_SML_TELNET_PROTOCOL,
TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS, 0, ReqId.GetReqId());
// insert json data
client.SchemalessInsert(new []{jsonDemo}, TDengineSchemalessProtocol.TSDB_SML_JSON_PROTOCOL,
TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_NOT_CONFIGURED, 0, ReqId.GetReqId());
}
}
catch (TDengineError e)
{
// handle TDengine error
Console.WriteLine("Failed to insert data with schemaless; ErrCode:" + e.Code + "; ErrMessage: " + e.Error);
throw;
}
catch (Exception e)
{
// handle other exceptions
Console.WriteLine("Failed to insert data with schemaless; Err:" + e.Message);
throw;
}
// ANCHOR_END: main
}
}
}

View File

@ -13,8 +13,7 @@ namespace TDengineExample
{
try
{
client.Exec("use power");
string query = "SELECT * FROM meters";
string query = "SELECT * FROM power.meters";
using (var rows = client.Query(query))
{
while (rows.Read())

View File

@ -6,42 +6,162 @@ namespace TDengineExample
{
internal class SQLInsertExample
{
public static void Main(string[] args)
{
var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata");
using (var client = DbDriver.Open(builder))
try
{
try
var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata");
using (var client = DbDriver.Open(builder))
{
client.Exec("create database power");
client.Exec("CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))");
string insertQuery =
"INSERT INTO " +
"power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " +
"VALUES " +
"('2023-10-03 14:38:05.000', 10.30000, 219, 0.31000) " +
"('2023-10-03 14:38:15.000', 12.60000, 218, 0.33000) " +
"('2023-10-03 14:38:16.800', 12.30000, 221, 0.31000) " +
"power.d1002 USING power.meters TAGS(3, 'California.SanFrancisco') " +
"VALUES " +
"('2023-10-03 14:38:16.650', 10.30000, 218, 0.25000) " +
"power.d1003 USING power.meters TAGS(2,'California.LosAngeles') " +
"VALUES " +
"('2023-10-03 14:38:05.500', 11.80000, 221, 0.28000) " +
"('2023-10-03 14:38:16.600', 13.40000, 223, 0.29000) " +
"power.d1004 USING power.meters TAGS(3,'California.LosAngeles') " +
"VALUES " +
"('2023-10-03 14:38:05.000', 10.80000, 223, 0.29000) " +
"('2023-10-03 14:38:06.500', 11.50000, 221, 0.35000)";
client.Exec(insertQuery);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
throw;
CreateDatabaseAndTable(client);
InsertData(client);
QueryData(client);
QueryWithReqId(client);
}
}
catch (TDengineError e)
{
// handle TDengine error
Console.WriteLine(e.Message);
throw;
}
catch (Exception e)
{
// handle other exceptions
Console.WriteLine(e.Message);
throw;
}
}
private static void CreateDatabaseAndTable(ITDengineClient client)
{
// ANCHOR: create_db_and_table
try
{
// create database
var affected = client.Exec("CREATE DATABASE IF NOT EXISTS power");
Console.WriteLine($"Create database power, affected rows: {affected}");
// create table
affected = client.Exec(
"CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))");
Console.WriteLine($"Create table meters, affected rows: {affected}");
}
catch (TDengineError e)
{
// handle TDengine error
Console.WriteLine("Failed to create db and table; ErrCode:" + e.Code + "; ErrMessage: " + e.Error);
throw;
}
catch (Exception e)
{
// handle other exceptions
Console.WriteLine("Failed to create db and table; Err:" + 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("insert " + affectedRows + " rows to power.meters successfully.");
}
catch (TDengineError e)
{
// handle TDengine error
Console.WriteLine("Failed to insert data to power.meters; ErrCode:" + e.Code + "; ErrMessage: " + e.Error);
throw;
}
catch (Exception e)
{
// handle other exceptions
Console.WriteLine("Failed to insert data to power.meters; Err:" + 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("Failed to query data from power.meters; ErrCode:" + e.Code + "; ErrMessage: " + e.Error);
throw;
}
catch (Exception e)
{
// handle other exceptions
Console.WriteLine("Failed to query data from power.meters; Err:" + 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 3
using (var rows = client.Query(query,3))
{
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("Failed to execute sql with reqId; ErrCode:" + e.Code + "; ErrMessage: " + e.Error);
throw;
}
catch (Exception e)
{
// handle other exceptions
Console.WriteLine("Failed to execute sql with reqId; Err:" + e.Message);
throw;
}
// ANCHOR_END: query_id
}
}
}
}

View File

@ -5,34 +5,72 @@ namespace TDengineExample
{
internal class StmtInsertExample
{
// ANCHOR: main
public static void Main(string[] args)
{
var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata");
using (var client = DbDriver.Open(builder))
var host = "127.0.0.1";
var numOfSubTable = 10;
var numOfRow = 10;
var random = new Random();
try
{
try
var builder = new ConnectionStringBuilder($"host={host};port=6030;username=root;password=taosdata");
using (var client = DbDriver.Open(builder))
{
client.Exec($"create database power");
// create database
client.Exec("CREATE DATABASE IF NOT EXISTS power");
// use database
client.Exec("USE power");
// create table
client.Exec(
"CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))");
"CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))");
using (var stmt = client.StmtInit())
{
stmt.Prepare(
"Insert into power.d1001 using power.meters tags(2,'California.SanFrancisco') values(?,?,?,?)");
var ts = new DateTime(2023, 10, 03, 14, 38, 05, 000);
stmt.BindRow(new object[] { ts, (float)10.30000, (int)219, (float)0.31000 });
stmt.AddBatch();
stmt.Exec();
var affected = stmt.Affected();
Console.WriteLine($"affected rows: {affected}");
String sql = "INSERT INTO ? USING meters TAGS(?,?) VALUES (?,?,?,?)";
stmt.Prepare(sql);
for (int i = 1; i <= numOfSubTable; i++)
{
var tableName = $"d_bind_{i}";
// set table name
stmt.SetTableName(tableName);
// set tags
stmt.SetTags(new object[] { i, $"location_{i}" });
var current = DateTime.Now;
// bind rows
for (int j = 0; j < numOfRow; j++)
{
stmt.BindRow(new object[]
{
current.Add(TimeSpan.FromMilliseconds(j)),
random.NextSingle() * 30,
random.Next(300),
random.NextSingle()
});
}
// add batch
stmt.AddBatch();
// execute
stmt.Exec();
// get affected rows
var affectedRows = stmt.Affected();
Console.WriteLine($"table {tableName} insert {affectedRows} rows.");
}
}
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
catch (TDengineError e)
{
// handle TDengine error
Console.WriteLine("Failed to insert to table meters using stmt; ErrCode:" + e.Code + "; ErrMessage: " + e.Error);
throw;
}
catch (Exception e)
{
// handle other exceptions
Console.WriteLine("Failed to insert to table meters using stmt; Err:" + e.Message);
throw;
}
}
// ANCHOR_END: main
}
}

View File

@ -1,5 +1,4 @@

using TDengine.Driver;
using TDengine.Driver;
using TDengine.Driver.Client;
using TDengine.TMQ;
@ -9,65 +8,242 @@ namespace TMQExample
{
public static void Main(string[] args)
{
var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata");
using (var client = DbDriver.Open(builder))
try
{
try
var builder = new ConnectionStringBuilder("host=127.0.0.1;port=6030;username=root;password=taosdata");
using (var client = DbDriver.Open(builder))
{
client.Exec("CREATE DATABASE power");
client.Exec("CREATE DATABASE IF NOT EXISTS power");
client.Exec("USE power");
client.Exec(
"CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))");
client.Exec("CREATE TOPIC topic_meters as SELECT * from power.meters");
var cfg = new Dictionary<string, string>()
{
{ "group.id", "group1" },
{ "auto.offset.reset", "latest" },
{ "td.connect.ip", "127.0.0.1" },
{ "td.connect.user", "root" },
{ "td.connect.pass", "taosdata" },
{ "td.connect.port", "6030" },
{ "client.id", "tmq_example" },
{ "enable.auto.commit", "true" },
{ "msg.with.table.name", "false" },
};
var consumer = new ConsumerBuilder<Dictionary<string, object>>(cfg).Build();
consumer.Subscribe(new List<string>() { "topic_meters" });
"CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))");
client.Exec("CREATE TOPIC IF NOT EXISTS topic_meters as SELECT * from power.meters");
var consumer = CreateConsumer();
// insert data
Task.Run(InsertData);
while (true)
{
using (var cr = consumer.Consume(500))
{
if (cr == null) continue;
foreach (var message in cr.Message)
{
Console.WriteLine(
$"message {{{((DateTime)message.Value["ts"]).ToString("yyyy-MM-dd HH:mm:ss.fff")}, " +
$"{message.Value["current"]}, {message.Value["voltage"]}, {message.Value["phase"]}}}");
}
}
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
throw;
// consume message
Consume(consumer);
// seek
Seek(consumer);
// commit
CommitOffset(consumer);
// close
Close(consumer);
Console.WriteLine("Done");
}
}
catch (TDengineError e)
{
// handle TDengine error
Console.WriteLine(e.Message);
throw;
}
catch (Exception e)
{
// handle other exceptions
Console.WriteLine(e.Message);
throw;
}
}
static void InsertData()
{
var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata");
var builder = new ConnectionStringBuilder("host=127.0.0.1;port=6030;username=root;password=taosdata");
using (var client = DbDriver.Open(builder))
{
while (true)
{
client.Exec("INSERT into power.d1001 using power.meters tags(2,'California.SanFrancisco') values(now,11.5,219,0.30)");
client.Exec(
"INSERT into power.d1001 using power.meters tags(2,'California.SanFrancisco') values(now,11.5,219,0.30)");
Task.Delay(1000).Wait();
}
}
}
}
}
static IConsumer<Dictionary<string, object>> CreateConsumer()
{
// ANCHOR: create_consumer
// consumer config
var cfg = new Dictionary<string, string>()
{
{ "td.connect.port", "6030" },
{ "auto.offset.reset", "latest" },
{ "msg.with.table.name", "true" },
{ "enable.auto.commit", "true" },
{ "auto.commit.interval.ms", "1000" },
{ "group.id", "group1" },
{ "client.id", "client1" },
{ "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("Failed to create consumer; ErrCode:" + e.Code + "; ErrMessage: " + e.Error);
throw;
}
catch (Exception e)
{
// handle other exceptions
Console.WriteLine("Failed to create consumer; Err:" + 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(
$"data {{{((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("Failed to poll data; ErrCode:" + e.Code + "; ErrMessage: " + e.Error);
throw;
}
catch (Exception e)
{
// handle other exceptions
Console.WriteLine("Failed to poll data; Err:" + 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));
}
Console.WriteLine("assignment seek to beginning successfully");
// poll data again
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(
$"second data polled: {{{((DateTime)message.Value["ts"]).ToString("yyyy-MM-dd HH:mm:ss.fff")}, " +
$"{message.Value["current"]}, {message.Value["voltage"]}, {message.Value["phase"]}}}");
}
break;
}
}
}
catch (TDengineError e)
{
// handle TDengine error
Console.WriteLine("Failed to seek; ErrCode:" + e.Code + "; ErrMessage: " + e.Error);
throw;
}
catch (Exception e)
{
// handle other exceptions
Console.WriteLine("Failed to seek; Err:" + 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("Failed to commit offset; ErrCode:" + e.Code + "; ErrMessage: " + e.Error);
throw;
}
catch (Exception e)
{
// handle other exceptions
Console.WriteLine("Failed to commit offset; Err:" + e.Message);
throw;
}
}
// ANCHOR_END: commit_offset
}
static void Close(IConsumer<Dictionary<string, object>> consumer)
{
// ANCHOR: close
try
{
// unsubscribe
consumer.Unsubscribe();
}
catch (TDengineError e)
{
// handle TDengine error
Console.WriteLine("Failed to unsubscribe consumer; ErrCode:" + e.Code + "; ErrMessage: " + e.Error);
throw;
}
catch (Exception e)
{
// handle other exceptions
Console.WriteLine("Failed to unsubscribe consumer; Err:" + e.Message);
throw;
}
finally
{
// close consumer
consumer.Close();
}
// ANCHOR_END: close
}
}
}

View File

@ -6,13 +6,35 @@ namespace Examples
{
public class WSConnExample
{
// ANCHOR: main
static void Main(string[] args)
{
var builder = new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata");
using (var client = DbDriver.Open(builder))
var connectionString =
"protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata";
try
{
Console.WriteLine("connected");
// Connect to TDengine server using WebSocket
var builder = new ConnectionStringBuilder(connectionString);
// Open connection with using block, it will close the connection automatically
using (var client = DbDriver.Open(builder))
{
Console.WriteLine("Connected to " + connectionString + " successfully.");
}
}
catch (TDengineError e)
{
// handle TDengine error
Console.WriteLine("Failed to connect to " + connectionString + "; ErrCode:" + e.Code +
"; ErrMessage: " + e.Error);
throw;
}
catch (Exception e)
{
// handle other exceptions
Console.WriteLine("Failed to connect to " + connectionString + "; Err:" + e.Message);
throw;
}
}
// ANCHOR_END: main
}
}
}

View File

@ -1,4 +1,5 @@
using System;
using System.Text;
using TDengine.Driver;
using TDengine.Driver.Client;
@ -8,39 +9,159 @@ namespace Examples
{
public static void Main(string[] args)
{
var builder = new ConnectionStringBuilder("protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata");
using (var client = DbDriver.Open(builder))
try
{
try
var builder = new ConnectionStringBuilder("protocol=WebSocket;host=127.0.0.1;port=6041;useSSL=false;username=root;password=taosdata");
using (var client = DbDriver.Open(builder))
{
client.Exec("create database power");
client.Exec("CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))");
string insertQuery =
"INSERT INTO " +
"power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " +
"VALUES " +
"('2023-10-03 14:38:05.000', 10.30000, 219, 0.31000) " +
"('2023-10-03 14:38:15.000', 12.60000, 218, 0.33000) " +
"('2023-10-03 14:38:16.800', 12.30000, 221, 0.31000) " +
"power.d1002 USING power.meters TAGS(3, 'California.SanFrancisco') " +
"VALUES " +
"('2023-10-03 14:38:16.650', 10.30000, 218, 0.25000) " +
"power.d1003 USING power.meters TAGS(2,'California.LosAngeles') " +
"VALUES " +
"('2023-10-03 14:38:05.500', 11.80000, 221, 0.28000) " +
"('2023-10-03 14:38:16.600', 13.40000, 223, 0.29000) " +
"power.d1004 USING power.meters TAGS(3,'California.LosAngeles') " +
"VALUES " +
"('2023-10-03 14:38:05.000', 10.80000, 223, 0.29000) " +
"('2023-10-03 14:38:06.500', 11.50000, 221, 0.35000)";
client.Exec(insertQuery);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
throw;
CreateDatabaseAndTable(client);
InsertData(client);
QueryData(client);
QueryWithReqId(client);
}
}
catch (TDengineError e)
{
// handle TDengine error
Console.WriteLine(e.Message);
throw;
}
catch (Exception e)
{
// handle other exceptions
Console.WriteLine(e.Message);
throw;
}
}
private static void CreateDatabaseAndTable(ITDengineClient client)
{
// ANCHOR: create_db_and_table
try
{
// create database
var affected = client.Exec("CREATE DATABASE IF NOT EXISTS power");
Console.WriteLine($"Create database power, affected rows: {affected}");
// create table
affected = client.Exec(
"CREATE STABLE IF NOT EXISTS power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))");
Console.WriteLine($"Create table meters, affected rows: {affected}");
}
catch (TDengineError e)
{
// handle TDengine error
Console.WriteLine("Failed to create db and table; ErrCode:" + e.Code + "; ErrMessage: " + e.Error);
throw;
}
catch (Exception e)
{
// handle other exceptions
Console.WriteLine("Failed to create db and table; Err:" + 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("insert " + affectedRows + " rows to power.meters successfully.");
}
catch (TDengineError e)
{
// handle TDengine error
Console.WriteLine("Failed to insert data to power.meters; ErrCode:" + e.Code + "; ErrMessage: " + e.Error);
throw;
}
catch (Exception e)
{
// handle other exceptions
Console.WriteLine("Failed to insert data to power.meters; Err:" + 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("Failed to query data from power.meters; ErrCode:" + e.Code + "; ErrMessage: " + e.Error);
throw;
}
catch (Exception e)
{
// handle other exceptions
Console.WriteLine("Failed to query data from power.meters; Err:" + 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 3
using (var rows = client.Query(query,3))
{
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("Failed to execute sql with reqId; ErrCode:" + e.Code + "; ErrMessage: " + e.Error);
throw;
}
catch (Exception e)
{
// handle other exceptions
Console.WriteLine("Failed to execute sql with reqId; Err:" + e.Message);
throw;
}
// ANCHOR_END: query_id
}
}
}
}

View File

@ -14,8 +14,7 @@ namespace Examples
{
try
{
client.Exec("use power");
string query = "SELECT * FROM meters";
string query = "SELECT * FROM power.meters";
using (var rows = client.Query(query))
{
while (rows.Read())

View File

@ -6,36 +6,72 @@ namespace Examples
{
public class WSStmtExample
{
// ANCHOR: main
public static void Main(string[] args)
{
var builder =
new ConnectionStringBuilder(
"protocol=WebSocket;host=localhost;port=6041;useSSL=false;username=root;password=taosdata");
using (var client = DbDriver.Open(builder))
var host = "127.0.0.1";
var numOfSubTable = 10;
var numOfRow = 10;
var random = new Random();
try
{
try
var builder = new ConnectionStringBuilder($"protocol=WebSocket;host={host};port=6041;useSSL=false;username=root;password=taosdata");
using (var client = DbDriver.Open(builder))
{
client.Exec($"create database power");
// create database
client.Exec("CREATE DATABASE IF NOT EXISTS power");
// use database
client.Exec("USE power");
// create table
client.Exec(
"CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))");
"CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))");
using (var stmt = client.StmtInit())
{
stmt.Prepare(
"Insert into power.d1001 using power.meters tags(2,'California.SanFrancisco') values(?,?,?,?)");
var ts = new DateTime(2023, 10, 03, 14, 38, 05, 000);
stmt.BindRow(new object[] { ts, (float)10.30000, (int)219, (float)0.31000 });
stmt.AddBatch();
stmt.Exec();
var affected = stmt.Affected();
Console.WriteLine($"affected rows: {affected}");
String sql = "INSERT INTO ? USING meters TAGS(?,?) VALUES (?,?,?,?)";
stmt.Prepare(sql);
for (int i = 1; i <= numOfSubTable; i++)
{
var tableName = $"d_bind_{i}";
// set table name
stmt.SetTableName(tableName);
// set tags
stmt.SetTags(new object[] { i, $"location_{i}" });
var current = DateTime.Now;
// bind rows
for (int j = 0; j < numOfRow; j++)
{
stmt.BindRow(new object[]
{
current.Add(TimeSpan.FromMilliseconds(j)),
random.NextSingle() * 30,
random.Next(300),
random.NextSingle()
});
}
// add batch
stmt.AddBatch();
// execute
stmt.Exec();
// get affected rows
var affectedRows = stmt.Affected();
Console.WriteLine($"table {tableName} insert {affectedRows} rows.");
}
}
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
catch (TDengineError e)
{
// handle TDengine error
Console.WriteLine("Failed to insert to table meters using stmt; ErrCode:" + e.Code + "; ErrMessage: " + e.Error);
throw;
}
catch (Exception e)
{
// handle other exceptions
Console.WriteLine("Failed to insert to table meters using stmt; Err:" + e.Message);
throw;
}
}
// ANCHOR_END: main
}
}

View File

@ -0,0 +1,57 @@
using TDengine.Driver;
using TDengine.Driver.Client;
namespace TDengineExample
{
internal class WssmlExample
{
// ANCHOR: main
public static void Main(string[] args)
{
var host = "127.0.0.1";
var lineDemo =
"meters,groupid=2,location=California.SanFrancisco current=10.3000002f64,voltage=219i32,phase=0.31f64 1626006833639";
var telnetDemo = "metric_telnet 1707095283260 4 host=host0 interface=eth0";
var jsonDemo =
"{\"metric\": \"metric_json\",\"timestamp\": 1626846400,\"value\": 10.3, \"tags\": {\"groupid\": 2, \"location\": \"California.SanFrancisco\", \"id\": \"d1001\"}}";
try
{
var builder =
new ConnectionStringBuilder(
$"protocol=WebSocket;host={host};port=6041;username=root;password=taosdata");
using (var client = DbDriver.Open(builder))
{
// create database
client.Exec("CREATE DATABASE IF NOT EXISTS power");
// use database
client.Exec("USE power");
// insert influx line protocol data
client.SchemalessInsert(new[]{lineDemo}, TDengineSchemalessProtocol.TSDB_SML_LINE_PROTOCOL,
TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS, 0, ReqId.GetReqId());
// insert opentsdb telnet protocol data
client.SchemalessInsert(new[]{telnetDemo}, TDengineSchemalessProtocol.TSDB_SML_TELNET_PROTOCOL,
TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_MILLI_SECONDS, 0, ReqId.GetReqId());
// insert json data
client.SchemalessInsert(new []{jsonDemo}, TDengineSchemalessProtocol.TSDB_SML_JSON_PROTOCOL,
TDengineSchemalessPrecision.TSDB_SML_TIMESTAMP_NOT_CONFIGURED, 0, ReqId.GetReqId());
}
}
catch (TDengineError e)
{
// handle TDengine error
Console.WriteLine("Failed to insert data with schemaless; ErrCode:" + e.Code + "; ErrMessage: " + e.Error);
throw;
}
catch (Exception e)
{
// handle other exceptions
Console.WriteLine("Failed to insert data with schemaless; Err:" + e.Message);
throw;
}
}
// ANCHOR_END: main
}
}

View File

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

View File

@ -0,0 +1,250 @@
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", "group1" },
{ "client.id", "client1" },
{ "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("Failed to create consumer; ErrCode:" + e.Code + "; ErrMessage: " + e.Error);
throw;
}
catch (Exception e)
{
// handle other exceptions
Console.WriteLine("Failed to create consumer; Err:" + 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(
$"data {{{((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("Failed to poll data; ErrCode:" + e.Code + "; ErrMessage: " + e.Error);
throw;
}
catch (Exception e)
{
// handle other exceptions
Console.WriteLine("Failed to poll data; Err:" + 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));
}
Console.WriteLine("assignment seek to beginning successfully");
// poll data again
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(
$"second data polled: {{{((DateTime)message.Value["ts"]).ToString("yyyy-MM-dd HH:mm:ss.fff")}, " +
$"{message.Value["current"]}, {message.Value["voltage"]}, {message.Value["phase"]}}}");
}
break;
}
}
}
catch (TDengineError e)
{
// handle TDengine error
Console.WriteLine("Failed to seek; ErrCode:" + e.Code + "; ErrMessage: " + e.Error);
throw;
}
catch (Exception e)
{
// handle other exceptions
Console.WriteLine("Failed to seek; Err:" + 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("Failed to commit offset; ErrCode:" + e.Code + "; ErrMessage: " + e.Error);
throw;
}
catch (Exception e)
{
// handle other exceptions
Console.WriteLine("Failed to commit offset; Err:" + e.Message);
throw;
}
}
// ANCHOR_END: commit_offset
}
static void Close(IConsumer<Dictionary<string, object>> consumer)
{
// ANCHOR: close
try
{
// unsubscribe
consumer.Unsubscribe();
}
catch (TDengineError e)
{
// handle TDengine error
Console.WriteLine("Failed to unsubscribe consumer; ErrCode:" + e.Code + "; ErrMessage: " + e.Error);
throw;
}
catch (Exception e)
{
// handle other exceptions
Console.WriteLine("Failed to unsubscribe consumer; Err:" + e.Message);
throw;
}
finally
{
// close consumer
consumer.Close();
}
// ANCHOR_END: close
}
}
}

View File

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

View File

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

View File

@ -9,16 +9,14 @@ 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 {
log.Fatalln("failed to connect TDengine, err:", err)
return
}
fmt.Println("Connected")
fmt.Println("Connected to " + taosDSN + " successfully.")
defer taos.Close()
}
// use
// var taosDSN = "root:taosdata@tcp(localhost:6030)/dbName"
// if you want to connect a specified database named "dbName".

View File

@ -0,0 +1,32 @@
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)
}
fmt.Println("Connected")
defer taos.Close()
// ANCHOR: pool
// SetMaxOpenConns sets the maximum number of open connections to the database. 0 means unlimited.
taos.SetMaxOpenConns(0)
// SetMaxIdleConns sets the maximum number of connections in the idle connection pool.
taos.SetMaxIdleConns(2)
// SetConnMaxLifetime sets the maximum amount of time a connection may be reused.
taos.SetConnMaxLifetime(0)
// SetConnMaxIdleTime sets the maximum amount of time a connection may be idle.
taos.SetConnMaxIdleTime(0)
// ANCHOR_END: pool
}

View File

@ -9,16 +9,14 @@ 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 {
log.Fatalln("failed to connect TDengine, err:", err)
return
}
fmt.Println("Connected")
fmt.Println("Connected to " + taosDSN + " successfully.")
defer taos.Close()
}
// use
// var taosDSN = "root:taosdata@http(localhost:6041)/dbName"
// if you want to connect a specified database named "dbName".

View File

@ -0,0 +1,22 @@
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)
}
fmt.Println("Connected to " + taosDSN + " successfully.")
defer taos.Close()
}

View File

@ -2,5 +2,12 @@ module goexample
go 1.17
require github.com/taosdata/driver-go/v3 v3.1.0
require github.com/taosdata/driver-go/v3 v3.5.6
require (
github.com/google/uuid v1.3.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
)

View File

@ -1,15 +1,25 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/taosdata/driver-go/v3 v3.1.0/go.mod h1:H2vo/At+rOPY1aMzUV9P49SVX7NlXb3LAbKw+MCLrmU=
github.com/taosdata/driver-go/v3 v3.5.6 h1:LDVtMyT3B9p2VREsd5KKM91D4Y7P4kSdh2SQumXi8bk=
github.com/taosdata/driver-go/v3 v3.5.6/go.mod h1:H2vo/At+rOPY1aMzUV9P49SVX7NlXb3LAbKw+MCLrmU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -0,0 +1,56 @@
package main
import (
"context"
"database/sql"
"fmt"
"log"
"time"
_ "github.com/taosdata/driver-go/v3/taosSql"
)
func main() {
db, err := sql.Open("taosSql", "root:taosdata@tcp(localhost:6030)/")
if err != nil {
log.Fatal("Open database error: ", 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 {
log.Fatal("Query error: ", err)
}
for rows.Next() {
var (
ts time.Time
current float32
location string
)
err = rows.Scan(&ts, &current, &location)
if err != nil {
log.Fatal("Scan error: ", 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 {
log.Fatal("Create database error: ", 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 {
log.Fatal("Create table error: ", 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 {
log.Fatal("Insert data error: ", err)
}
}

View File

@ -0,0 +1,43 @@
package main
import (
"log"
"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 {
log.Fatal("failed to connect TDengine, err:", err)
}
defer conn.Close()
_, err = conn.Exec("CREATE DATABASE IF NOT EXISTS power")
if err != nil {
log.Fatal("failed to create database, err:", err)
}
_, err = conn.Exec("USE power")
if err != nil {
log.Fatal("failed to use database, err:", err)
}
// insert influxdb line protocol
err = conn.InfluxDBInsertLines([]string{lineDemo}, "ms")
if err != nil {
log.Fatal("failed to insert influxdb line protocol, err:", err)
}
// insert opentsdb telnet protocol
err = conn.OpenTSDBInsertTelnetLines([]string{telnetDemo})
if err != nil {
log.Fatal("failed to insert opentsdb telnet line protocol, err:", err)
}
// insert opentsdb json protocol
err = conn.OpenTSDBInsertJsonPayload(jsonDemo)
if err != nil {
log.Fatal("failed to insert opentsdb json format protocol, err:", err)
}
}

View File

@ -0,0 +1,54 @@
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("failed to connect TDengine, err:", err)
}
defer db.Close()
_, err = db.Exec("CREATE DATABASE IF NOT EXISTS power")
if err != nil {
log.Fatal("failed to create database, err:", 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"),
))
if err != nil {
log.Fatal("failed to create schemaless connection, err:", err)
}
// insert influxdb line protocol
err = s.Insert(lineDemo, schemaless.InfluxDBLineProtocol, "ms", 0, common.GetReqID())
if err != nil {
log.Fatal("failed to insert influxdb line protocol, err:", err)
}
// insert opentsdb telnet line protocol
err = s.Insert(telnetDemo, schemaless.OpenTSDBTelnetLineProtocol, "ms", 0, common.GetReqID())
if err != nil {
log.Fatal("failed to insert opentsdb telnet line protocol, err:", err)
}
// insert opentsdb json format protocol
err = s.Insert(jsonDemo, schemaless.OpenTSDBJsonFormatProtocol, "s", 0, common.GetReqID())
if err != nil {
log.Fatal("failed to insert opentsdb json format protocol, err:", err)
}
}

View File

@ -0,0 +1,89 @@
package main
import (
"database/sql"
"fmt"
"log"
"time"
_ "github.com/taosdata/driver-go/v3/taosSql"
)
func main() {
db, err := sql.Open("taosSql", "root:taosdata@tcp(localhost:6030)/")
if err != nil {
log.Fatal("open database failed:", err)
}
defer db.Close()
// ANCHOR: create_db_and_table
// create database
res, err := db.Exec("CREATE DATABASE IF NOT EXISTS power")
if err != nil {
log.Fatal("create database failed:", err)
}
affected, err := res.RowsAffected()
if err != nil {
log.Fatal("get affected rows failed:", err)
}
fmt.Println("create database affected:", affected)
// use database
res, err = db.Exec("USE power")
if err != nil {
log.Fatal("use database failed:", err)
}
affected, err = res.RowsAffected()
if err != nil {
log.Fatal("get affected rows failed:", 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 {
log.Fatal("create table failed:", 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 {
log.Fatal("insert data failed:", err)
}
affected, err = res.RowsAffected()
if err != nil {
log.Fatal("get affected rows failed:", 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 {
log.Fatal("query data failed:", err)
}
for rows.Next() {
var (
ts time.Time
current float32
location string
)
err = rows.Scan(&ts, &current, &location)
if err != nil {
log.Fatal("scan data failed:", err)
}
// you can check data here
fmt.Printf("ts: %s, current: %f, location: %s\n", ts, current, location)
}
// ANCHOR_END: select_data
}

View File

@ -0,0 +1,83 @@
package main
import (
"fmt"
"log"
"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 {
log.Fatal("failed to connect TDengine, err:", err)
}
defer db.Close()
// prepare database and table
_, err = db.Exec("CREATE DATABASE IF NOT EXISTS power")
if err != nil {
log.Fatal("failed to create database, err:", err)
}
_, err = db.Exec("USE power")
if err != nil {
log.Fatal("failed to use database, err:", 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 {
log.Fatal("failed to create table, err:", err)
}
// prepare statement
sql := "INSERT INTO ? USING meters TAGS(?,?) VALUES (?,?,?,?)"
stmt := db.Stmt()
err = stmt.Prepare(sql)
if err != nil {
log.Fatal("failed to prepare statement, err:", 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 {
log.Fatal("failed to set table name and tags, err:", 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 {
log.Fatal("failed to bind row, err:", err)
}
}
// add batch
err = stmt.AddBatch()
if err != nil {
log.Fatal("failed to add batch, err:", err)
}
// execute batch
err = stmt.Execute()
if err != nil {
log.Fatal("failed to execute batch, err:", 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 {
log.Fatal("failed to close statement, err:", err)
}
}

View File

@ -0,0 +1,103 @@
package main
import (
"database/sql"
"fmt"
"log"
"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 {
log.Fatal("failed to connect TDengine, err:", err)
}
defer db.Close()
// prepare database and table
_, err = db.Exec("CREATE DATABASE IF NOT EXISTS power")
if err != nil {
log.Fatal("failed to create database, err:", 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 {
log.Fatal("failed to create table, err:", 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 {
log.Fatal("failed to create stmt connector, err:", err)
}
// prepare statement
sql := "INSERT INTO ? USING meters TAGS(?,?) VALUES (?,?,?,?)"
stmt, err := connector.Init()
if err != nil {
log.Fatal("failed to init stmt, err:", err)
}
err = stmt.Prepare(sql)
if err != nil {
log.Fatal("failed to prepare stmt, err:", 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 {
log.Fatal("failed to set table name, err:", err)
}
// set tags
err = stmt.SetTags(tags, tagsType)
if err != nil {
log.Fatal("failed to set tags, err:", 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 {
log.Fatal("failed to bind param, err:", err)
}
}
// add batch
err = stmt.AddBatch()
if err != nil {
log.Fatal("failed to add batch, err:", err)
}
// execute batch
err = stmt.Exec()
if err != nil {
log.Fatal("failed to exec stmt, err:", 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 {
log.Fatal("failed to close stmt, err:", err)
}
}

View File

@ -0,0 +1,153 @@
package main
import (
"database/sql"
"fmt"
"log"
"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 {
log.Fatal("failed to connect TDengine, err:", 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": "group1",
"client.id": "client1",
})
if err != nil {
log.Fatal("failed to create consumer, err:", err)
}
// ANCHOR_END: create_consumer
// ANCHOR: subscribe
err = consumer.Subscribe("topic_meters", nil)
if err != nil {
log.Fatal("failed to subscribe, err:", 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("data:%v\n", e)
// ANCHOR: commit_offset
// commit offset
topicPartition, err := consumer.CommitOffsets([]tmqcommon.TopicPartition{e.TopicPartition})
if err != nil {
log.Fatal("failed to commit offset, err:", err)
}
fmt.Println(topicPartition)
// ANCHOR_END: commit_offset
case tmqcommon.Error:
fmt.Printf("%% Error: %v: %v\n", e.Code(), e)
log.Fatal("failed to get message, err:", e)
}
// commit all offsets
topicPartition, err := consumer.Commit()
if err != nil {
log.Fatal("failed to commit, err:", err)
}
fmt.Println(topicPartition)
}
}
// ANCHOR_END: subscribe
// ANCHOR: seek
// get assignment
partitions, err := consumer.Assignment()
if err != nil {
log.Fatal("failed to get assignment, err:", 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 {
log.Fatal("failed to seek, err:", err)
}
}
fmt.Println("assignment seek to beginning successfully")
// poll data again
gotData := false
for i := 0; i < 50; i++ {
if gotData {
break
}
ev := consumer.Poll(100)
if ev != nil {
switch e := ev.(type) {
case *tmqcommon.DataMessage:
// process your data here
fmt.Printf("second data polled:%v\n", e)
gotData = true
case tmqcommon.Error:
fmt.Printf("%% Error: %v: %v\n", e.Code(), e)
log.Fatal("failed to get message, err:", e)
}
}
}
// ANCHOR_END: seek
// ANCHOR: close
// unsubscribe
err = consumer.Unsubscribe()
if err != nil {
log.Fatal("failed to unsubscribe, err:", err)
}
// close consumer
err = consumer.Close()
if err != nil {
log.Fatal("failed to close consumer, err:", err)
}
// ANCHOR_END: close
<-done
}
func initEnv(conn *sql.DB) {
_, err := conn.Exec("CREATE DATABASE IF NOT EXISTS power")
if err != nil {
log.Fatal("failed to create database, err:", 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 {
log.Fatal("failed to create stable, err:", 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 {
log.Fatal("failed to create topic, err:", 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 {
log.Fatal("failed to insert data, err:", err)
}
}
done <- struct{}{}
}()
}

View File

@ -0,0 +1,158 @@
package main
import (
"database/sql"
"fmt"
"log"
"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 {
log.Fatal("failed to connect TDengine, err:", 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": "group1",
"client.id": "client1",
})
if err != nil {
log.Fatal("failed to create consumer, err:", err)
}
// ANCHOR_END: create_consumer
// ANCHOR: subscribe
err = consumer.Subscribe("topic_meters", nil)
if err != nil {
log.Fatal("failed to subscribe, err:", 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("data:%v\n", e)
// ANCHOR: commit_offset
// commit offset
topicPartition, err := consumer.CommitOffsets([]tmqcommon.TopicPartition{e.TopicPartition})
if err != nil {
log.Fatal("failed to commit offset, err:", err)
}
fmt.Println(topicPartition)
// ANCHOR_END: commit_offset
case tmqcommon.Error:
fmt.Printf("%% Error: %v: %v\n", e.Code(), e)
log.Fatal("failed to get message, err:", e)
}
// commit all offsets
topicPartition, err := consumer.Commit()
if err != nil {
log.Fatal("failed to commit, err:", err)
}
fmt.Println(topicPartition)
}
}
// ANCHOR_END: subscribe
// ANCHOR: seek
// get assignment
partitions, err := consumer.Assignment()
if err != nil {
log.Fatal("failed to get assignment, err:", 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 {
log.Fatal("failed to seek, err:", err)
}
}
fmt.Println("assignment seek to beginning successfully")
// poll data again
gotData := false
for i := 0; i < 50; i++ {
if gotData {
break
}
ev := consumer.Poll(100)
if ev != nil {
switch e := ev.(type) {
case *tmqcommon.DataMessage:
// process your data here
fmt.Printf("second data polled:%v\n", e)
gotData = true
case tmqcommon.Error:
fmt.Printf("%% Error: %v: %v\n", e.Code(), e)
log.Fatal("failed to get message, err:", e)
}
}
}
// ANCHOR_END: seek
// ANCHOR: close
// unsubscribe
err = consumer.Unsubscribe()
if err != nil {
log.Fatal("failed to unsubscribe, err:", err)
}
// close consumer
err = consumer.Close()
if err != nil {
log.Fatal("failed to close consumer, err:", err)
}
// ANCHOR_END: close
<-done
}
func initEnv(conn *sql.DB) {
_, err := conn.Exec("CREATE DATABASE IF NOT EXISTS power")
if err != nil {
log.Fatal("failed to create database, err:", 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 {
log.Fatal("failed to create stable, err:", 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 {
log.Fatal("failed to create topic, err:", 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 {
log.Fatal("failed to insert data, err:", err)
}
}
done <- struct{}{}
}()
}

View File

@ -27,6 +27,10 @@ public static void main(String[] args) throws SQLException {
} catch (SQLException ex) {
// handle any errors, please refer to the JDBC specifications for detailed exceptions info
System.out.println("Failed to connect to " + jdbcUrl + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw ex;
} catch (Exception ex){
System.out.println("Failed to connect to " + jdbcUrl + "; ErrMessage: " + ex.getMessage());
throw ex;
}
}
// ANCHOR_END: main

View File

@ -16,6 +16,10 @@ public static void main(String[] args) throws SQLException {
} catch (SQLException ex) {
// handle any errors, please refer to the JDBC specifications for detailed exceptions info
System.out.println("Failed to connect to " + jdbcUrl + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw ex;
} catch (Exception ex){
System.out.println("Failed to connect to " + jdbcUrl + "; ErrMessage: " + ex.getMessage());
throw ex;
}
}
// ANCHOR_END: main

View File

@ -28,6 +28,10 @@ public static void main(String[] args) throws SQLException {
} catch (SQLException ex) {
// handle any errors, please refer to the JDBC specifications for detailed exceptions info
System.out.println("Failed to connect to " + jdbcUrl + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw ex;
} catch (Exception ex){
System.out.println("Failed to connect to " + jdbcUrl + "; ErrMessage: " + ex.getMessage());
throw ex;
}
}
// ANCHOR_END: main

View File

@ -2,13 +2,13 @@ const taos = require("@tdengine/websocket");
let db = 'power';
let stable = 'meters';
let tags = ['California.SanFrancisco', 3];
let values = [
[1706786044994, 1706786044995, 1706786044996],
[10.2, 10.3, 10.4],
[292, 293, 294],
[0.32, 0.33, 0.34],
];
let numOfSubTable = 10;
let numOfRow = 10;
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
async function prepare() {
let dsn = 'ws://localhost:6041'
@ -29,24 +29,36 @@ async function prepare() {
connector = await prepare();
stmt = await connector.stmtInit();
await stmt.prepare(`INSERT INTO ? USING ${db}.${stable} (location, groupId) TAGS (?, ?) VALUES (?, ?, ?, ?)`);
await stmt.setTableName('d1001');
let tagParams = stmt.newStmtParam();
tagParams.setVarchar([tags[0]]);
tagParams.setInt([tags[1]]);
await stmt.setTags(tagParams);
let bindParams = stmt.newStmtParam();
bindParams.setTimestamp(values[0]);
bindParams.setFloat(values[1]);
bindParams.setInt(values[2]);
bindParams.setFloat(values[3]);
await stmt.bind(bindParams);
await stmt.batch();
await stmt.exec();
console.log(stmt.getLastAffected());
for (let i = 0; i < numOfSubTable; i++) {
await stmt.setTableName(`d_bind_${i}`);
let tagParams = stmt.newStmtParam();
tagParams.setVarchar([`location_${i}`]);
tagParams.setInt([i]);
await stmt.setTags(tagParams);
let timestampParams = [];
let currentParams = [];
let voltageParams = [];
let phaseParams = [];
const currentMillis = new Date().getTime();
for (let j = 0; j < numOfRow; j++) {
timestampParams.push(currentMillis + j);
currentParams.push(Math.random() * 30);
voltageParams.push(getRandomInt(100, 300));
phaseParams.push(Math.random());
}
let bindParams = stmt.newStmtParam();
bindParams.setTimestamp(timestampParams);
bindParams.setFloat(currentParams);
bindParams.setInt(voltageParams);
bindParams.setFloat(phaseParams);
await stmt.bind(bindParams);
await stmt.batch();
await stmt.exec();
console.log(`d_bind_${i} insert ` + stmt.getLastAffected() + " rows.");
}
}
catch (err) {
console.error(err.code, err.message);
catch (e) {
console.error(e);
}
finally {
if (stmt) {

View File

@ -7,24 +7,30 @@ const topics = ['power_meters_topic'];
// ANCHOR: create_consumer
async function createConsumer() {
let configMap = new Map([
[taos.TMQConstants.GROUP_ID, "gId"],
[taos.TMQConstants.GROUP_ID, "group1"],
[taos.TMQConstants.CLIENT_ID, 'client1'],
[taos.TMQConstants.CONNECT_USER, "root"],
[taos.TMQConstants.CONNECT_PASS, "taosdata"],
[taos.TMQConstants.AUTO_OFFSET_RESET, "latest"],
[taos.TMQConstants.CLIENT_ID, 'test_tmq_client'],
[taos.TMQConstants.WS_URL, 'ws://localhost:6041'],
[taos.TMQConstants.ENABLE_AUTO_COMMIT, 'true'],
[taos.TMQConstants.AUTO_COMMIT_INTERVAL_MS, '1000']
]);
return await taos.tmqConnect(configMap);
try {
return await taos.tmqConnect(configMap);
}catch (err) {
console.log(err);
throw err;
}
}
// ANCHOR_END: create_consumer
async function prepare() {
let conf = new taos.WSConfig('ws://localhost:6041');
conf.setUser('root')
conf.setPwd('taosdata')
conf.setDb('power')
conf.setUser('root');
conf.setPwd('taosdata');
conf.setDb('power');
const createDB = `CREATE DATABASE IF NOT EXISTS POWER ${db} KEEP 3650 DURATION 10 BUFFER 16 WAL_LEVEL 1;`;
const createStable = `CREATE STABLE IF NOT EXISTS ${db}.${stable} (ts timestamp, current float, voltage int, phase float) TAGS (location binary(64), groupId int);`;
@ -32,10 +38,9 @@ async function prepare() {
await wsSql.exec(createDB);
await wsSql.exec(createStable);
// ANCHOR: create_topic
let createTopic = `CREATE TOPIC IF NOT EXISTS ${topics[0]} AS SELECT * FROM ${db}.${stable}`;
await wsSql.exec(createTopic);
// ANCHOR_END: create_topic
let createTopic = `CREATE TOPIC IF NOT EXISTS ${topics[0]} AS SELECT * FROM ${db}.${stable}`;
await wsSql.exec(createTopic);
for (let i = 0; i < 10; i++) {
await wsSql.exec(`INSERT INTO d1001 USING ${stable} (location, groupId) TAGS ("California.SanFrancisco", 3) VALUES (NOW, ${10 + i}, ${200 + i}, ${0.32 + i})`);
@ -43,37 +48,31 @@ await wsSql.exec(createTopic);
wsSql.Close();
}
// ANCHOR: subscribe
async function subscribe(consumer) {
await consumer.subscribe(topics);
for (let i = 0; i < 5; i++) {
let res = await consumer.poll(500);
for (let [key, value] of res) {
console.log(key, value);
}
if (res.size == 0) {
break;
}
await consumer.commit();
// ANCHOR: commit
try {
await consumer.subscribe(['topic_meters']);
for (let i = 0; i < 50; i++) {
let res = await consumer.poll(100);
for (let [key, value] of res) {
console.log(key, value);
}
consumer.commit();
}
} catch (err) {
console.error(err.code, err.message);
throw err;
}
// ANCHOR_END: commit
}
// ANCHOR_END: subscribe
async function test() {
// ANCHOR: unsubscribe
let consumer = null;
try {
await prepare();
let consumer = await createConsumer()
await subscribe(consumer)
// ANCHOR: assignment
let assignment = await consumer.assignment();
console.log(assignment);
assignment = await consumer.seekToBeginning(assignment);
for(let i in assignment) {
console.log("seek after:", assignment[i])
}
// ANCHOR_END: assignment
await subscribe(consumer)
await consumer.unsubscribe();
}
catch (err) {
@ -85,6 +84,7 @@ async function test() {
}
taos.destroy();
}
// ANCHOR_END: unsubscribe
}
test()

View File

@ -0,0 +1,104 @@
const taos = require("@tdengine/websocket");
const db = 'power';
const stable = 'meters';
const topics = ['power_meters_topic'];
// ANCHOR: create_consumer
async function createConsumer() {
let configMap = new Map([
[taos.TMQConstants.GROUP_ID, "group1"],
[taos.TMQConstants.CLIENT_ID, 'client1'],
[taos.TMQConstants.CONNECT_USER, "root"],
[taos.TMQConstants.CONNECT_PASS, "taosdata"],
[taos.TMQConstants.AUTO_OFFSET_RESET, "latest"],
[taos.TMQConstants.WS_URL, 'ws://localhost:6041'],
[taos.TMQConstants.ENABLE_AUTO_COMMIT, 'true'],
[taos.TMQConstants.AUTO_COMMIT_INTERVAL_MS, '1000']
]);
try {
return await taos.tmqConnect(configMap);
}catch (err) {
console.log(err);
throw err;
}
}
// ANCHOR_END: create_consumer
async function prepare() {
let conf = new taos.WSConfig('ws://localhost:6041');
conf.setUser('root');
conf.setPwd('taosdata');
conf.setDb('power');
const createDB = `CREATE DATABASE IF NOT EXISTS POWER ${db} KEEP 3650 DURATION 10 BUFFER 16 WAL_LEVEL 1;`;
const createStable = `CREATE STABLE IF NOT EXISTS ${db}.${stable} (ts timestamp, current float, voltage int, phase float) TAGS (location binary(64), groupId int);`;
let wsSql = await taos.sqlConnect(conf);
await wsSql.exec(createDB);
await wsSql.exec(createStable);
let createTopic = `CREATE TOPIC IF NOT EXISTS ${topics[0]} AS SELECT * FROM ${db}.${stable}`;
await wsSql.exec(createTopic);
for (let i = 0; i < 10; i++) {
await wsSql.exec(`INSERT INTO d1001 USING ${stable} (location, groupId) TAGS ("California.SanFrancisco", 3) VALUES (NOW, ${10 + i}, ${200 + i}, ${0.32 + i})`);
}
wsSql.Close();
}
// ANCHOR: subscribe
async function subscribe(consumer) {
try {
await consumer.subscribe(['topic_meters']);
for (let i = 0; i < 50; i++) {
let res = await consumer.poll(100);
for (let [key, value] of res) {
console.log(key, value);
}
}
}catch (err) {
console.error(err.code, err.message);
throw err;
}
}
// ANCHOR_END: subscribe
// ANCHOR: offset
async function test() {
let consumer = null;
try {
await prepare();
let consumer = await createConsumer()
await consumer.subscribe(['topic_meters']);
let res = new Map();
while (res.size == 0) {
res = await consumer.poll(100);
}
let assignment = await consumer.assignment();
for (let i in assignment) {
console.log("seek before:", assignment[i]);
}
await consumer.seekToBeginning(assignment);
assignment = await consumer.assignment();
for (let i in assignment) {
console.log("seek after:", assignment[i]);
}
await consumer.unsubscribe();
}
catch (err) {
console.error(err.code, err.message);
}
finally {
if (consumer) {
await consumer.close();
}
taos.destroy();
}
}
// ANCHOR_END: offset
test()

View File

@ -4,14 +4,14 @@ def create_connection():
# all parameters are optional.
conn = None
try:
conn = taosws.connect(
conn = taos.connect(
user="root",
password="taosdata",
host="192.168.1.98",
host="localhost",
port=6041,
)
except Exception as err:
print(f'Exception {err}')
print(err)
finally:
if conn:
conn.close()

View File

@ -0,0 +1,20 @@
# ANCHOR: connect
import taosrest
def create_connection():
conn = None
try:
conn = taosrest.connect(url="http://localhost:6041",
user="root",
password="taosdata",
timeout=30)
except Exception as err:
print(err)
finally:
if conn:
conn.close()
# ANCHOR_END: connect
if __name__ == "__main__":
create_connection()

View File

@ -1,11 +1,12 @@
# ANCHOR: connect
from taosrest import connect, TaosRestConnection, TaosRestCursor
conn = connect(url="http://localhost:6041",
user="root",
password="taosdata",
timeout=30)
conn = connect(url="http://localhost:6041",
user="root",
password="taosdata",
timeout=30)
# ANCHOR_END: connect
# ANCHOR: basic
# create STable

View File

@ -1,8 +1,8 @@
# ANCHOR: connect
import taosws
def create_connection():
conn = None
# ANCHOR: connect
try:
conn = taosws.connect(
user="root",
@ -11,9 +11,10 @@ def create_connection():
port=6041,
)
except Exception as err:
print(f'Exception {err}')
# ANCHOR_END: connect
print(err)
return conn
# ANCHOR_END: connect
def create_db_table(conn):
# ANCHOR: create_db
@ -21,12 +22,13 @@ def create_db_table(conn):
conn.execute("CREATE DATABASE IF NOT EXISTS power")
conn.execute("USE power")
conn.execute("CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))")
conn.execute("CREATE TABLE `d0` USING `meters` TAGS(0, 'Los Angles')")
conn.execute("CREATE TABLE IF NOT EXISTS `d0` USING `meters` (groupId, location) TAGS(0, 'Los Angles')")
except Exception as err:
print(f'Exception {err}')
# ANCHOR_END: create_db
def insert(conn):
def insert(conn):
# ANCHOR: insert
sql = """
INSERT INTO
power.d1001 USING power.meters TAGS('California.SanFrancisco', 2)
@ -39,18 +41,26 @@ def insert(conn):
inserted = conn.execute(sql)
assert inserted == 8
except Exception as err:
print(f'Exception {err}')
print(f'Exception111 {err}')
# ANCHOR_END: insert
def query(conn):
result = conn.query("select * from stb")
num_of_fields = result.field_count
print(num_of_fields)
# ANCHOR: query
try:
result = conn.query("select * from meters")
num_of_fields = result.field_count
print(num_of_fields)
for row in result:
print(row)
for row in result:
print(row)
except Exception as err:
print(f'Exception {err}')
# ANCHOR_END: query
# output:
# 3
# ('2023-02-28 15:56:13.329 +08:00', 1, 1)
# ('2023-02-28 15:56:13.333 +08:00', 2, 1)
# ('2023-02-28 15:56:13.337 +08:00', 3, 1)
if __name__ == "__main__":
conn = create_connection()
create_db_table(conn)
insert(conn)
query(conn)
if conn:
conn.close()

View File

@ -1,26 +1,33 @@
import taos
conn = taos.connect(
host="localhost",
user="root",
password="taosdata",
port=6030,
)
conn = None
try:
conn = taos.connect(host="localhost",
user="root",
password="taosdata",
port=6030)
db = "power"
db = "power"
# create database
rowsAffected = conn.execute(f"CREATE DATABASE IF NOT EXISTS {db}")
assert rowsAffected == 0
conn.execute(f"DROP DATABASE IF EXISTS {db}")
conn.execute(f"CREATE DATABASE {db}")
# change database. same as execute "USE db"
rowsAffected = conn.select_db(db)
assert rowsAffected == 0
# create super table
rowsAffected = conn.execute(
"CREATE TABLE IF NOT EXISTS `meters` (`ts` TIMESTAMP, `current` FLOAT, `voltage` INT, `phase` FLOAT) TAGS (`groupid` INT, `location` BINARY(16))"
)
assert rowsAffected == 0
# change database. same as execute "USE db"
conn.select_db(db)
# create table
rowsAffected = conn.execute("CREATE TABLE IF NOT EXISTS `d0` USING `meters` (groupid, location) TAGS(0, 'Los Angles')")
assert rowsAffected == 0
# create super table
conn.execute(
"CREATE TABLE `meters` (`ts` TIMESTAMP, `current` FLOAT, `voltage` INT, `phase` FLOAT) TAGS (`groupid` INT, `location` BINARY(16))"
)
# create table
conn.execute("CREATE TABLE `d0` USING `meters` TAGS(0, 'Los Angles')")
conn.close()
except Exception as err:
print(err)
finally:
if conn:
conn.close()

View File

@ -1,18 +1,28 @@
import taosrest
conn = taosrest.connect(url="http://localhost:6041")
conn = None
try:
conn = taosrest.connect(url="http://localhost:6041",
user="root",
password="taosdata",
timeout=30)
db = "power"
db = "power"
# create database
rowsAffected = conn.execute(f"CREATE DATABASE IF NOT EXISTS {db}")
assert rowsAffected == 0
conn.execute(f"DROP DATABASE IF EXISTS {db}")
conn.execute(f"CREATE DATABASE {db}")
# create super table
rowsAffected = conn.execute(
f"CREATE TABLE IF NOT EXISTS `{db}`.`meters` (`ts` TIMESTAMP, `current` FLOAT, `voltage` INT, `phase` FLOAT) TAGS (`groupid` INT, `location` BINARY(16))"
)
assert rowsAffected == 0
# create table
rowsAffected = conn.execute(f"CREATE TABLE IF NOT EXISTS `{db}`.`d0` USING `{db}`.`meters` (groupid, location) TAGS(0, 'Los Angles')")
assert rowsAffected == 0
# create super table
conn.execute(
f"CREATE TABLE `{db}`.`meters` (`ts` TIMESTAMP, `current` FLOAT, `voltage` INT, `phase` FLOAT) TAGS (`groupid` INT, `location` BINARY(16))"
)
# create table
conn.execute(f"CREATE TABLE `{db}`.`d0` USING `{db}`.`meters` TAGS(0, 'Los Angles')")
conn.close()
except Exception as err:
print(err)
finally:
if conn:
conn.close()

View File

@ -1,22 +1,34 @@
import taosws
dsn = "taosws://root:taosdata@localhost:6041"
conn = taosws.connect(dsn)
conn = None
db = "power"
try:
conn = taosws.connect(user="root",
password="taosdata",
host="localhost",
port=6041)
conn.execute(f"DROP DATABASE IF EXISTS {db}")
conn.execute(f"CREATE DATABASE {db}")
db = "power"
# create database
rowsAffected = conn.execute(f"CREATE DATABASE IF NOT EXISTS {db}")
assert rowsAffected == 0
# change database.
conn.execute(f"USE {db}")
# change database.
rowsAffected = conn.execute(f"USE {db}")
assert rowsAffected == 0
# create super table
rowsAffected = conn.execute(
"CREATE TABLE IF NOT EXISTS `meters` (`ts` TIMESTAMP, `current` FLOAT, `voltage` INT, `phase` FLOAT) TAGS (`groupid` INT, `location` BINARY(16))"
)
assert rowsAffected == 0
# create super table
conn.execute(
"CREATE TABLE `meters` (`ts` TIMESTAMP, `current` FLOAT, `voltage` INT, `phase` FLOAT) TAGS (`groupid` INT, `location` BINARY(16))"
)
# create table
rowsAffected = conn.execute("CREATE TABLE IF NOT EXISTS `d0` USING `meters` (groupid, location) TAGS(0, 'Los Angles')")
assert rowsAffected == 0
# create table
conn.execute("CREATE TABLE `d0` USING `meters` TAGS(0, 'Los Angles')")
conn.close()
except Exception as err:
print(err)
finally:
if conn:
conn.close()

View File

@ -1,76 +1,26 @@
import taos
conn = taos.connect(
host="localhost",
user="root",
password="taosdata",
port=6030,
)
conn = None
db = "power"
try:
conn = taos.connect(user="root",
password="taosdata",
host="localhost",
port=6041)
conn.execute(f"DROP DATABASE IF EXISTS {db}")
conn.execute(f"CREATE DATABASE {db}")
sql = """
INSERT INTO
power.d1001 USING power.meters (groupid, location) 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 (groupid, location) TAGS(3, 'California.SanFrancisco')
VALUES (NOW + 1a, 10.30000, 218, 0.25000)
"""
inserted = conn.execute(sql)
print("inserted into {affectedRows} rows to power.meters successfully.")
# change database. same as execute "USE db"
conn.select_db(db)
# create super table
conn.execute(
"CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)"
)
# ANCHOR: insert
# insert data
sql = """
INSERT INTO
power.d1001 USING power.meters TAGS('California.SanFrancisco', 2)
VALUES ('2018-10-03 14:38:05.000', 10.30000, 219, 0.31000)
('2018-10-03 14:38:15.000', 12.60000, 218, 0.33000) ('2018-10-03 14:38:16.800', 12.30000, 221, 0.31000)
power.d1002 USING power.meters TAGS('California.SanFrancisco', 3)
VALUES ('2018-10-03 14:38:16.650', 10.30000, 218, 0.25000)
power.d1003 USING power.meters TAGS('California.LosAngeles', 2)
VALUES ('2018-10-03 14:38:05.500', 11.80000, 221, 0.28000) ('2018-10-03 14:38:16.600', 13.40000, 223, 0.29000)
power.d1004 USING power.meters TAGS('California.LosAngeles', 3)
VALUES ('2018-10-03 14:38:05.000', 10.80000, 223, 0.29000) ('2018-10-03 14:38:06.500', 11.50000, 221, 0.35000)
"""
inserted = conn.execute(sql)
assert inserted == 8
# ANCHOR_END: insert
# ANCHOR: query
# Execute a sql and get its result set. It's useful for SELECT statement
result = conn.query("SELECT * from meters")
# Get fields from result
fields = result.fields
for field in fields:
print(field)
"""
output:
{name: ts, type: 9, bytes: 8}
{name: current, type: 6, bytes: 4}
{name: voltage, type: 4, bytes: 4}
{name: phase, type: 6, bytes: 4}
{name: location, type: 8, bytes: 64}
{name: groupid, type: 4, bytes: 4}
"""
# Get data from result as list of tuple
data = result.fetch_all()
for row in data:
print(row)
"""
output:
(datetime.datetime(2018, 10, 3, 14, 38, 16, 650000), 10.300000190734863, 218, 0.25, 'California.SanFrancisco', 3)
...
"""
# ANCHOR_END: query
# ANCHOR: req_id
result = conn.query("SELECT * from meters", req_id=1)
# ANCHOR_END: req_id
conn.close()
except Exception as err:
print(err)
finally:
if conn:
conn.close()

View File

@ -1,48 +1,26 @@
import taosrest
conn = taosrest.connect(url="http://localhost:6041")
conn = None
db = "power"
try:
conn = taosrest.connect(url="http://localhost:6041",
user="root",
password="taosdata",
timeout=30)
conn.execute(f"DROP DATABASE IF EXISTS {db}")
conn.execute(f"CREATE DATABASE {db}")
sql = """
INSERT INTO
power.d1001 USING power.meters (groupid, location) 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 (groupid, location) TAGS(3, 'California.SanFrancisco')
VALUES (NOW + 1a, 10.30000, 218, 0.25000)
"""
affectedRows = conn.execute(sql)
print(f"inserted into {affectedRows} rows to power.meters successfully.")
# create super table
conn.execute(
"CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)"
)
# ANCHOR: insert
# rest insert data
sql = """
INSERT INTO
power.d1001 USING power.meters TAGS('California.SanFrancisco', 2)
VALUES ('2018-10-03 14:38:05.000', 10.30000, 219, 0.31000)
('2018-10-03 14:38:15.000', 12.60000, 218, 0.33000) ('2018-10-03 14:38:16.800', 12.30000, 221, 0.31000)
power.d1002 USING power.meters TAGS('California.SanFrancisco', 3)
VALUES ('2018-10-03 14:38:16.650', 10.30000, 218, 0.25000)
power.d1003 USING power.meters TAGS('California.LosAngeles', 2)
VALUES ('2018-10-03 14:38:05.500', 11.80000, 221, 0.28000) ('2018-10-03 14:38:16.600', 13.40000, 223, 0.29000)
power.d1004 USING power.meters TAGS('California.LosAngeles', 3)
VALUES ('2018-10-03 14:38:05.000', 10.80000, 223, 0.29000) ('2018-10-03 14:38:06.500', 11.50000, 221, 0.35000)
"""
inserted = conn.execute(sql)
assert inserted == 8
# ANCHOR_END: insert
# ANCHOR: query
client = taosrest.RestClient("http://localhost:6041")
result = client.sql(f"SELECT * from {db}.meters")
print(result)
"""
output:
{'code': 0, 'column_meta': [['ts', 'TIMESTAMP', 8], ['current', 'FLOAT', 4], ['voltage', 'INT', 4], ['phase', 'FLOAT', 4], ['location', 'VARCHAR', 64], ['groupid', 'INT', 4]], 'data': [[datetime.datetime(2018, 10, 3, 14, 38, 5), 10.3, 219, 0.31, 'California.SanFrancisco', 2], [datetime.datetime(2018, 10, 3, 14, 38, 15), 12.6, 218, 0.33, 'California.SanFrancisco', 2], [datetime.datetime(2018, 10, 3, 14, 38, 16, 800000), 12.3, 221, 0.31, 'California.SanFrancisco', 2], [datetime.datetime(2018, 10, 3, 14, 38, 16, 650000), 10.3, 218, 0.25, 'California.SanFrancisco', 3], [datetime.datetime(2018, 10, 3, 14, 38, 5, 500000), 11.8, 221, 0.28, 'California.LosAngeles', 2], [datetime.datetime(2018, 10, 3, 14, 38, 16, 600000), 13.4, 223, 0.29, 'California.LosAngeles', 2], [datetime.datetime(2018, 10, 3, 14, 38, 5), 10.8, 223, 0.29, 'California.LosAngeles', 3], [datetime.datetime(2018, 10, 3, 14, 38, 6, 500000), 11.5, 221, 0.35, 'California.LosAngeles', 3]], 'rows': 8}
"""
# ANCHOR_END: query
# ANCHOR: req_id
result = client.sql(f"SELECT * from {db}.meters", req_id=1)
# ANCHOR_END: req_id
conn.close()
except Exception as err:
print(err)
finally:
if conn:
conn.close()

View File

@ -1,71 +1,26 @@
import taosws
dsn = "taosws://root:taosdata@localhost:6041"
conn = taosws.connect(dsn)
conn = None
db = "power"
try:
conn = taosws.connect(user="root",
password="taosdata",
host="localhost",
port=6041)
conn.execute(f"DROP DATABASE IF EXISTS {db}")
conn.execute(f"CREATE DATABASE {db}")
sql = """
INSERT INTO
power.d1001 USING power.meters (groupid, location) 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 (groupid, location) TAGS(3, 'California.SanFrancisco')
VALUES (NOW + 1a, 10.30000, 218, 0.25000)
"""
inserted = conn.execute(sql)
print("inserted into {affectedRows} rows to power.meters successfully.")
# change database.
conn.execute(f"USE {db}")
# create super table
conn.execute(
"CREATE STABLE power.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (location BINARY(64), groupId INT)"
)
# ANCHOR: insert
# ws insert data
sql = """
INSERT INTO
power.d1001 USING power.meters TAGS('California.SanFrancisco', 2)
VALUES ('2018-10-03 14:38:05.000', 10.30000, 219, 0.31000)
('2018-10-03 14:38:15.000', 12.60000, 218, 0.33000) ('2018-10-03 14:38:16.800', 12.30000, 221, 0.31000)
power.d1002 USING power.meters TAGS('California.SanFrancisco', 3)
VALUES ('2018-10-03 14:38:16.650', 10.30000, 218, 0.25000)
power.d1003 USING power.meters TAGS('California.LosAngeles', 2)
VALUES ('2018-10-03 14:38:05.500', 11.80000, 221, 0.28000) ('2018-10-03 14:38:16.600', 13.40000, 223, 0.29000)
power.d1004 USING power.meters TAGS('California.LosAngeles', 3)
VALUES ('2018-10-03 14:38:05.000', 10.80000, 223, 0.29000) ('2018-10-03 14:38:06.500', 11.50000, 221, 0.35000)
"""
inserted = conn.execute(sql)
assert inserted == 8
# ANCHOR_END: insert
# ANCHOR: query
# Execute a sql and get its result set. It's useful for SELECT statement
result = conn.query("SELECT * from meters")
# Get fields from result
fields = result.fields
for field in fields:
print(field)
"""
output:
{name: ts, type: TIMESTAMP, bytes: 8}
{name: current, type: FLOAT, bytes: 4}
{name: voltage, type: INT, bytes: 4}
{name: phase, type: FLOAT, bytes: 4}
{name: location, type: BINARY, bytes: 64}
{name: groupid, type: INT, bytes: 4}
"""
# Get rows from result
for row in result:
print(row)
"""
output:
('2018-10-03 14:38:05 +08:00', 10.300000190734863, 219, 0.3100000023841858, 'California.SanFrancisco', 2)
...
"""
# ANCHOR_END: query
# ANCHOR: req_id
result = conn.query_with_req_id("SELECT * from meters", req_id=1)
# ANCHOR_END: req_id
conn.close()
except Exception as err:
print(err)
finally:
if conn:
conn.close()

View File

@ -0,0 +1,26 @@
import taos
conn = None
try:
conn = taos.connect(host="localhost",
port=6030,
user="root",
password="taosdata")
result = conn.query("SELECT ts, current, location FROM power.meters limit 100")
print(result)
# Get fields from result
fields = result.fields
for field in fields:
print(field)
# Get data from result as list of tuple
data = result.fetch_all()
for row in data:
print(row)
except Exception as err:
print(err)
finally:
if conn:
conn.close()

View File

@ -0,0 +1,15 @@
import taosrest
client = None
try:
client = taosrest.RestClient(url="http://localhost:6041",
user="root",
password="taosdata",
timeout=30)
result = client.sql(f"SELECT ts, current, location FROM power.meters limit 100")
print(result)
except Exception as err:
print(err)

View File

@ -0,0 +1,22 @@
import taosws
conn = None
try:
conn = taosws.connect(user="root",
password="taosdata",
host="localhost",
port=6041)
result = conn.query("SELECT ts, current, location FROM power.meters limit 100")
num_of_fields = result.field_count
print(num_of_fields)
for row in result:
print(row)
except Exception as err:
print(err)
finally:
if conn:
conn.close()

View File

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

View File

@ -11,20 +11,21 @@ async fn main() -> anyhow::Result<()> {
let db = "power";
// create database
taos.exec_many([
format!("DROP DATABASE IF EXISTS `{db}`"),
format!("CREATE DATABASE `{db}`"),
format!("CREATE DATABASE IF NOT EXISTS `{db}`"),
format!("USE `{db}`"),
])
.await?;
println!("Create database power successfully.");
// create table
// create super table
taos.exec_many([
// create super table
"CREATE TABLE `meters` (`ts` TIMESTAMP, `current` FLOAT, `voltage` INT, `phase` FLOAT) \
TAGS (`groupid` INT, `location` BINARY(24))",
TAGS (`groupid` INT, `location` BINARY(24))",
]).await?;
println!("Create stable meters successfully.");
// ANCHOR_END: create_db_and_table
// ANCHOR: insert_data
let inserted = taos.exec("INSERT INTO " +
"power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') " +
@ -36,11 +37,12 @@ async fn main() -> anyhow::Result<()> {
"VALUES " +
"(NOW + 1a, 10.30000, 218, 0.25000) ").await?;
println!("inserted: {} rows", inserted);
println!("inserted: {} rows to power.meters successfully.", inserted);
// ANCHOR_END: insert_data
// ANCHOR: query_data
let mut result = taos.query("SELECT * FROM power.meters").await?;
// 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());
@ -60,7 +62,6 @@ async fn main() -> anyhow::Result<()> {
// ANCHOR_END: query_data
// ANCHOR: query_with_req_id
let result = taos.query_with_req_id("SELECT * FROM power.meters", 0).await?;
let result = taos.query_with_req_id("SELECT ts, current, location FROM power.meters limit 1", 1).await?;
// ANCHOR_END: query_with_req_id
}

View File

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

View File

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

View File

@ -38,7 +38,7 @@ async fn main() -> anyhow::Result<()> {
let dsn = "taos://localhost:6030";
let builder = TaosBuilder::from_dsn(dsn)?;
let taos = builder.build()?;
let taos = builder.build().await?;
let db = "tmq";
// prepare database
@ -61,9 +61,10 @@ async fn main() -> anyhow::Result<()> {
// subscribe
let tmq = TmqBuilder::from_dsn("taos://localhost:6030/?group.id=test")?;
let mut consumer = tmq.build()?;
let mut consumer = tmq.build().await?;
consumer.subscribe(["tmq_meters"]).await?;
// ANCHOR: consumer_commit_manually
consumer
.stream()
.try_for_each(|(offset, message)| async {
@ -78,11 +79,54 @@ async fn main() -> anyhow::Result<()> {
println!("** read {} records: {:#?}\n", records.len(), records);
}
}
// commit offset manually when you have processed the message.
consumer.commit(offset).await?;
Ok(())
})
.await?;
// ANCHOR_END: consumer_commit_manually
// 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);
consumer.unsubscribe().await;
task.await??;

View File

@ -9,9 +9,11 @@ async fn main() -> anyhow::Result<()> {
.filter_level(log::LevelFilter::Info)
.init();
use taos_query::prelude::*;
// ANCHOR: create_consumer_dsn
let dsn = "taos://localhost:6030".to_string();
log::info!("dsn: {}", dsn);
let mut dsn = Dsn::from_str(&dsn)?;
// ANCHOR_END: create_consumer_dsn
let taos = TaosBuilder::from_dsn(&dsn)?.build().await?;
@ -43,19 +45,21 @@ async fn main() -> anyhow::Result<()> {
.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());
// ANCHOR: create_consumer_ac
dsn.params.insert("auto.offset.reset".to_string(), "latest".to_string());
dsn.params.insert("msg.with.table.name".to_string(), "true".to_string());
dsn.params.insert("enable.auto.commit".to_string(), "true".to_string());
dsn.params.insert("auto.commit.interval.ms".to_string(), "1000".to_string());
dsn.params.insert("group.id".to_string(), "group1".to_string());
dsn.params.insert("client.id".to_string(), "client1".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_END: create_consumer_ac
// ANCHOR: consume
consumer.subscribe(["topic_meters"]).await?;
{
let mut stream = consumer.stream_with_timeout(Timeout::from_secs(1));
@ -65,7 +69,7 @@ async fn main() -> anyhow::Result<()> {
let database = offset.database();
let vgroup_id = offset.vgroup_id();
log::debug!(
"topic: {}, database: {}, vgroup_id: {}",
"receive message from: topic: {}, database: {}, vgroup_id: {}",
topic,
database,
vgroup_id
@ -80,13 +84,13 @@ async fn main() -> anyhow::Result<()> {
let json = meta.as_json_meta().await?;
let sql = json.to_string();
if let Err(err) = taos.exec(sql).await {
println!("maybe error: {}", err);
println!("maybe error in handling meta message: {}", err);
}
}
MessageSet::Data(data) => {
log::info!("Data");
while let Some(data) = data.fetch_raw_block().await? {
log::debug!("data: {:?}", data);
log::debug!("message data: {:?}", data);
}
}
MessageSet::MetaData(meta, data) => {
@ -97,24 +101,24 @@ async fn main() -> anyhow::Result<()> {
let json = meta.as_json_meta().await?;
let sql = json.to_string();
if let Err(err) = taos.exec(sql).await {
println!("maybe error: {}", err);
println!("maybe error in handling metadata message: {}", err);
}
while let Some(data) = data.fetch_raw_block().await? {
log::debug!("data: {:?}", data);
log::debug!("message data: {:?}", data);
}
}
}
// commit offset manually when handling message successfully
consumer.commit(offset).await?;
}
}
// ANCHOR_END: consume
// ANCHOR: assignments
// ANCHOR: seek_offset
let assignments = consumer.assignments().await.unwrap();
log::info!("assignments: {:?}", assignments);
// ANCHOR_END: assignments
log::info!("start assignments: {:?}", assignments);
// seek offset
for topic_vec_assignment in assignments {
let topic = &topic_vec_assignment.0;
@ -132,23 +136,24 @@ async fn main() -> anyhow::Result<()> {
begin,
end
);
// ANCHOR: seek_offset
let res = consumer.offset_seek(topic, vgroup_id, end).await;
// seek offset of the (topic, vgroup_id) to the begin
let res = consumer.offset_seek(topic, vgroup_id, begin).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_END: seek_offset
// ANCHOR: unsubscribe
consumer.unsubscribe().await;

View File

@ -8,5 +8,7 @@ anyhow = "1"
chrono = "0.4"
serde = { version = "1", features = ["derive"] }
tokio = { version = "1", features = ["rt", "macros", "rt-multi-thread"] }
log = "0.4"
pretty_env_logger = "0.5.0"
taos = { version = "0.*" }

View File

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

View File

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

View File

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

View File

@ -0,0 +1,135 @@
use std::time::Duration;
use chrono::{DateTime, Local};
use taos::*;
// Query options 2, use deserialization with serde.
#[derive(Debug, serde::Deserialize)]
#[allow(dead_code)]
struct Record {
// deserialize timestamp to chrono::DateTime<Local>
ts: DateTime<Local>,
// float to f32
current: Option<f32>,
// int to i32
voltage: Option<i32>,
phase: Option<f32>,
}
async fn prepare(taos: Taos) -> anyhow::Result<()> {
let inserted = taos.exec_many([
// create child table
"CREATE TABLE `d0` USING `meters` TAGS(0, 'California.LosAngles')",
// insert into child table
"INSERT INTO `d0` values(now - 10s, 10, 116, 0.32)",
// insert with NULL values
"INSERT INTO `d0` values(now - 8s, NULL, NULL, NULL)",
// insert and automatically create table with tags if not exists
"INSERT INTO `d1` USING `meters` TAGS(1, 'California.SanFrancisco') values(now - 9s, 10.1, 119, 0.33)",
// insert many records in a single sql
"INSERT INTO `d1` values (now-8s, 10, 120, 0.33) (now - 6s, 10, 119, 0.34) (now - 4s, 11.2, 118, 0.322)",
]).await?;
assert_eq!(inserted, 6);
Ok(())
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let dsn = "ws://localhost:6041";
let builder = TaosBuilder::from_dsn(dsn)?;
let taos = builder.build().await?;
let db = "tmq";
// prepare database
taos.exec_many([
format!("DROP TOPIC IF EXISTS tmq_meters"),
format!("DROP DATABASE IF EXISTS `{db}`"),
format!("CREATE DATABASE `{db}` WAL_RETENTION_PERIOD 3600"),
format!("USE `{db}`"),
// create super table
format!("CREATE TABLE `meters` (`ts` TIMESTAMP, `current` FLOAT, `voltage` INT, `phase` FLOAT) TAGS (`groupid` INT, `location` BINARY(24))"),
// create topic for subscription
format!("CREATE TOPIC tmq_meters AS SELECT * FROM `meters`")
])
.await?;
let task = tokio::spawn(prepare(taos));
tokio::time::sleep(Duration::from_secs(1)).await;
// subscribe
let tmq = TmqBuilder::from_dsn("ws://localhost:6041/?group.id=test")?;
let mut consumer = tmq.build().await?;
consumer.subscribe(["tmq_meters"]).await?;
// ANCHOR: consumer_commit_manually
consumer
.stream()
.try_for_each(|(offset, message)| async {
let topic = offset.topic();
// the vgroup id, like partition id in kafka.
let vgroup_id = offset.vgroup_id();
println!("* in vgroup id {vgroup_id} of topic {topic}\n");
if let Some(data) = message.into_data() {
while let Some(block) = data.fetch_raw_block().await? {
let records: Vec<Record> = block.deserialize().try_collect()?;
println!("** read {} records: {:#?}\n", records.len(), records);
}
}
// commit offset manually when you have processed the message.
consumer.commit(offset).await?;
Ok(())
})
.await?;
// ANCHOR_END: consumer_commit_manually
// 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);
consumer.unsubscribe().await;
task.await??;
Ok(())
}

View File

@ -0,0 +1,136 @@
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::*;
// ANCHOR: create_consumer_dsn
let dsn = "ws://localhost:6041".to_string();
log::info!("dsn: {}", dsn);
let mut dsn = Dsn::from_str(&dsn)?;
// ANCHOR_END: create_consumer_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_ac
dsn.params.insert("auto.offset.reset".to_string(), "latest".to_string());
dsn.params.insert("msg.with.table.name".to_string(), "true".to_string());
dsn.params.insert("enable.auto.commit".to_string(), "true".to_string());
dsn.params.insert("auto.commit.interval.ms".to_string(), "1000".to_string());
dsn.params.insert("group.id".to_string(), "group1".to_string());
dsn.params.insert("client.id".to_string(), "client1".to_string());
let builder = TmqBuilder::from_dsn(&dsn)?;
let mut consumer = builder.build().await?;
// ANCHOR_END: create_consumer_ac
// ANCHOR: subscribe
consumer.subscribe(["topic_meters"]).await?;
// ANCHOR_END: subscribe
// ANCHOR: consume
{
consumer
.stream()
.try_for_each(|(offset, message)| async {
let topic = offset.topic();
// the vgroup id, like partition id in kafka.
let vgroup_id = offset.vgroup_id();
println!("* in vgroup id {vgroup_id} of topic {topic}\n");
if let Some(data) = message.into_data() {
while let Some(block) = data.fetch_raw_block().await? {
let records: Vec<Record> = block.deserialize().try_collect()?;
println!("** read {} records: {:#?}\n", records.len(), records);
}
}
Ok(())
})
.await?;
}
// ANCHOR_END: consume
// ANCHOR: assignments
let assignments = consumer.assignments().await.unwrap();
log::info!("assignments: {:?}", assignments);
// ANCHOR_END: assignments
// seek offset
for topic_vec_assignment in assignments {
let topic = &topic_vec_assignment.0;
let vec_assignment = topic_vec_assignment.1;
for assignment in vec_assignment {
let vgroup_id = assignment.vgroup_id();
let current = assignment.current_offset();
let begin = assignment.begin();
let end = assignment.end();
log::debug!(
"topic: {}, vgroup_id: {}, current offset: {} begin {}, end: {}",
topic,
vgroup_id,
current,
begin,
end
);
// ANCHOR: seek_offset
let res = consumer.offset_seek(topic, vgroup_id, end).await;
if res.is_err() {
log::error!("seek offset error: {:?}", res);
let a = consumer.assignments().await.unwrap();
log::error!("assignments: {:?}", a);
}
// ANCHOR_END: seek_offset
}
let topic_assignment = consumer.topic_assignment(topic).await;
log::debug!("topic assignment: {:?}", topic_assignment);
}
// after seek offset
let assignments = consumer.assignments().await.unwrap();
log::info!("after seek offset assignments: {:?}", assignments);
// ANCHOR: unsubscribe
consumer.unsubscribe().await;
// ANCHOR_END: unsubscribe
tokio::time::sleep(Duration::from_secs(1)).await;
taos.exec_many([
"drop database db2",
"drop topic topic_meters",
"drop database power",
])
.await?;
Ok(())
}

View File

@ -13,8 +13,6 @@ import ConnNode from "./_connect_node.mdx";
import ConnPythonNative from "./_connect_python.mdx";
import ConnCSNative from "./_connect_cs.mdx";
import ConnC from "./_connect_c.mdx";
import ConnR from "./_connect_r.mdx";
import ConnPHP from "./_connect_php.mdx";
import InstallOnLinux from "../../14-reference/05-connector/_linux_install.mdx";
import InstallOnWindows from "../../14-reference/05-connector/_windows_install.mdx";
import InstallOnMacOS from "../../14-reference/05-connector/_macos_install.mdx";
@ -220,7 +218,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>
@ -249,62 +247,12 @@ dotnet add package TDengine.Connector
:::
</TabItem>
<TabItem label="R" value="r">
1. 下载 [taos-jdbcdriver-version-dist.jar](https://repo1.maven.org/maven2/com/taosdata/jdbc/taos-jdbcdriver/3.0.0/)。
2. 安装 R 的依赖包`RJDBC`
```R
install.packages("RJDBC")
```
</TabItem>
<TabItem label="C" value="c">
如果已经安装了 TDengine 服务端软件或 TDengine 客户端驱动 taosc 那么已经安装了 C 连接器,无需额外操作。
<br/>
</TabItem>
<TabItem label="PHP" value="php">
**下载代码并解压:**
```shell
curl -L -o php-tdengine.tar.gz https://github.com/Yurunsoft/php-tdengine/archive/refs/tags/v1.0.2.tar.gz \
&& mkdir php-tdengine \
&& tar -xzf php-tdengine.tar.gz -C php-tdengine --strip-components=1
```
> 版本 `v1.0.2` 只是示例,可替换为任意更新的版本,可在 [TDengine PHP Connector 发布历史](https://github.com/Yurunsoft/php-tdengine/releases) 中查看可用版本。
**非 Swoole 环境:**
```shell
phpize && ./configure && make -j && make install
```
**手动指定 TDengine 目录:**
```shell
phpize && ./configure --with-tdengine-dir=/usr/local/Cellar/tdengine/3.0.0.0 && make -j && make install
```
> `--with-tdengine-dir=` 后跟上 TDengine 目录。
> 适用于默认找不到的情况,或者 macOS 系统用户。
**Swoole 环境:**
```shell
phpize && ./configure --enable-swoole && make -j && make install
```
**启用扩展:**
方法一:在 `php.ini` 中加入 `extension=tdengine`
方法二:运行带参数 `php -d extension=tdengine test.php`
</TabItem>
</Tabs>
@ -321,18 +269,88 @@ Java 连接器建立连接的参数有 URL 和 Properties。
TDengine 的 JDBC URL 规范格式为:
`jdbc:[TAOS|TAOS-RS]://[host_name]:[port]/[database_name]?[user={user}|&password={password}|&charset={charset}|&cfgdir={config_dir}|&locale={locale}|&timezone={timezone}]`
URL 和 Properties 的详细参数说明和如何使用详见 [API 说明](../../reference/connector/java/#url-规范)
URL 和 Properties 的详细参数说明和如何使用详见 [url 规范](../../reference/connector/java/#url-规范)
</TabItem>
<TabItem label="Python" value="python">
</TabItem>
<TabItem label="Go" value="go">
数据源名称具有通用格式,例如 [PEAR DB](http://pear.php.net/manual/en/package.database.db.intro-dsn.php),但没有类型前缀(方括号表示可选):
``` text
[username[:password]@][protocol[(address)]]/[dbname][?param1=value1&...&paramN=valueN]
```
完整形式的 DSN
```text
username:password@protocol(address)/dbname?param=value
```
支持的 DSN 参数如下
原生连接:
- `cfg` 指定 taos.cfg 目录
- `cgoThread` 指定 cgo 同时执行的数量,默认为系统核数
- `cgoAsyncHandlerPoolSize` 指定异步函数的 handle 大小,默认为 10000
REST 连接:
- `disableCompression` 是否接受压缩数据,默认为 true 不接受压缩数据,如果传输数据使用 gzip 压缩设置为 false。
- `readBufferSize` 读取数据的缓存区大小默认为 4K4096当查询结果数据量多时可以适当调大该值。
- `token` 连接云服务时使用的 token。
- `skipVerify` 是否跳过证书验证,默认为 false 不跳过证书验证,如果连接的是不安全的服务设置为 true。
WebSocket 连接:
- `enableCompression` 是否发送压缩数据,默认为 false 不发送压缩数据,如果传输数据使用压缩设置为 true。
- `readTimeout` 读取数据的超时时间,默认为 5m。
- `writeTimeout` 写入数据的超时时间,默认为 10s。
</TabItem>
<TabItem label="Rust" value="rust">
Rust 连接器使用 DSN 来创建连接, DSN 描述字符串基本结构如下:
```text
<driver>[+<protocol>]://[[<username>:<password>@]<host>:<port>][/<database>][?<p1>=<v1>[&<p2>=<v2>]]
|------|------------|---|-----------|-----------|------|------|------------|-----------------------|
|driver| protocol | | username | password | host | port | database | params |
```
DSN 的详细说明和如何使用详见 [连接功能](../../reference/connector/rust/#连接功能)
</TabItem>
<TabItem label="C#" value="csharp">
</TabItem>
<TabItem label="R" value="r">
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="C" value="c">
使用客户端驱动访问 TDengine 集群的基本过程为:建立连接、查询和写入、关闭连接、清除资源。
@ -361,10 +379,6 @@ URL 和 Properties 的详细参数说明和如何使用详见 [API 说明](../..
:::
</TabItem>
<TabItem label="PHP" value="php">
</TabItem>
</Tabs>
@ -373,7 +387,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}}
```
@ -384,10 +398,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
@ -395,17 +413,13 @@ URL 和 Properties 的详细参数说明和如何使用详见 [API 说明](../..
```
</TabItem>
<TabItem label="C#" value="csharp">
<ConnCSNative />
</TabItem>
<TabItem label="R" value="r">
<ConnR/>
```csharp
{{#include docs/examples/csharp/wsConnect/Program.cs:main}}
```
</TabItem>
<TabItem label="C" value="c">
<ConnC />
</TabItem>
<TabItem label="PHP" value="php">
<ConnPHP />
</TabItem>
</Tabs>
### 原生连接
@ -416,33 +430,33 @@ URL 和 Properties 的详细参数说明和如何使用详见 [API 说明](../..
```java
{{#include docs/examples/java/src/main/java/com/taos/example/JNIConnectExample.java:main}}
```
</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">
<ConnR/>
</TabItem>
<TabItem label="C" value="c">
<ConnC />
</TabItem>
<TabItem label="PHP" value="php">
<ConnPHP />
</TabItem>
</TabItem>
<TabItem label="Python" value="python">
<ConnPythonNative />
</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="C" value="c">
<ConnC />
</TabItem>
</Tabs>
### REST 连接
下面是各语言连接器建立 RESt 连接代码样例。演示了如何使用 REST 连接方式连接到 TDengine 数据库。整个过程主要涉及到数据库连接的建立和异常处理。
下面是各语言连接器建立 REST 连接代码样例。演示了如何使用 REST 连接方式连接到 TDengine 数据库。整个过程主要涉及到数据库连接的建立和异常处理。
<Tabs defaultValue="java" groupId="lang">
<TabItem label="Java" value="java">
@ -452,27 +466,23 @@ URL 和 Properties 的详细参数说明和如何使用详见 [API 说明](../..
</TabItem>
<TabItem label="Python" value="python">
```python
{{#include docs/examples/python/connect_rest_examples.py:connect}}
{{#include docs/examples/python/connect_rest_example.py:connect}}
```
</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 />
</TabItem>
<TabItem label="R" value="r">
<ConnR/>
不支持
</TabItem>
<TabItem label="C" value="c">
<ConnC />
</TabItem>
<TabItem label="PHP" value="php">
<ConnPHP />
</TabItem>
</Tabs>
@ -516,22 +526,48 @@ 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/>
不支持
</TabItem>
<TabItem label="C" value="c">
<ConnC />
</TabItem>
<TabItem label="PHP" value="php">
<ConnPHP />
</TabItem>
</Tabs>

View File

@ -11,6 +11,14 @@ TDengine 对 SQL 语言提供了全面的支持,允许用户以熟悉的 SQL
下面介绍使用各语言连接器通过执行 SQL 完成建库、建表、写入数据和查询数据。
:::note
REST 连接:各编程语言的连接器封装使用 `HTTP` 请求的连接,支持数据写入和查询操作,开发者依然使用连接器提供的接口访问 `TDengine`
REST API直接调用 `taosadapter` 提供的 REST API 接口,进行数据写入和查询操作。代码示例使用 `curl` 命令来演示。
:::
## 建库和表
下面以智能电表为例,展示使用各语言连接器如何执行 SQL 命令创建一个名为 `power` 的数据库,然后使用 `power` 数据库为默认数据库。
接着创建一个名为 `meters` 的超级表STABLE其表结构包含时间戳、电流、电压、相位等列以及分组 ID 和位置作为标签。
@ -21,20 +29,43 @@ 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">
- Websocket 连接
```python title="Websocket 连接"
{{#include docs/examples/python/create_db_ws.py}}
```
```python title="原生连接"
{{#include docs/examples/python/create_db_native.py}}
```
```python title="Rest 连接"
{{#include docs/examples/python/create_db_rest.py}}
```
</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:create_db_and_table}}
```
</TabItem>
<TabItem label="Node.js" value="node.js">
```js
{{#include docs/examples/node/websocketexample/sql_example.js:create_db_and_table}}
```
</TabItem>
<TabItem label="C#" value="csharp">
</TabItem>
<TabItem label="R" value="r">
```csharp
{{#include docs/examples/csharp/wsInsert/Program.cs:create_db_and_table}}
```
</TabItem>
<TabItem label="C" value="c">
```c
@ -42,9 +73,25 @@ TDengine 对 SQL 语言提供了全面的支持,允许用户以熟悉的 SQL
```
> **注意**:如果不使用 `USE power` 指定数据库,则后续对表的操作都需要增加数据库名称作为前缀,如 power.meters。
</TabItem>
<TabItem label="PHP" value="php">
<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 条数据,然后打印出实际插入数据条数。
@ -61,14 +108,41 @@ NOW 为系统内部函数,默认为客户端所在计算机当前时间。 NOW
</TabItem>
<TabItem label="Python" value="python">
```python title="Websocket 连接"
{{#include docs/examples/python/insert_ws.py}}
```
```python title="原生连接"
{{#include docs/examples/python/insert_native.py}}
```
```python title="Rest 连接"
{{#include docs/examples/python/insert_rest.py}}
```
</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:insert_data}}
```
</TabItem>
<TabItem label="Node.js" value="node.js">
```js
{{#include docs/examples/node/websocketexample/sql_example.js:insertData}}
```
</TabItem>
<TabItem label="C#" value="csharp">
</TabItem>
<TabItem label="R" value="r">
```csharp
{{#include docs/examples/csharp/wsInsert/Program.cs:insert_data}}
```
</TabItem>
<TabItem label="C" value="c">
```c
@ -78,7 +152,15 @@ NOW 为系统内部函数,默认为客户端所在计算机当前时间。 NOW
**Note**
NOW 为系统内部函数,默认为客户端所在计算机当前时间。 NOW + 1s 代表客户端当前时间往后加 1 秒数字后面代表时间单位a毫秒smh小时dwny
</TabItem>
<TabItem label="PHP" value="php">
<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>
@ -96,21 +178,55 @@ NOW 为系统内部函数,默认为客户端所在计算机当前时间。 NOW
</TabItem>
<TabItem label="Python" value="python">
```python title="Websocket 连接"
{{#include docs/examples/python/query_ws.py}}
```
```python title="原生连接"
{{#include docs/examples/python/query_native.py}}
```
```python title="Rest 连接"
{{#include docs/examples/python/query_rest.py}}
```
</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_data}}
```
</TabItem>
<TabItem label="Node.js" value="node.js">
```js
{{#include docs/examples/node/websocketexample/sql_example.js:queryData}}
```
</TabItem>
<TabItem label="C#" value="csharp">
</TabItem>
<TabItem label="R" value="r">
```csharp
{{#include docs/examples/csharp/wsInsert/Program.cs:select_data}}
```
</TabItem>
<TabItem label="C" value="c">
```c
{{#include docs/examples/c/CQueryDataDemo.c:query_data}}
```
</TabItem>
<TabItem label="PHP" value="php">
<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>
@ -138,18 +254,40 @@ reqId 可用于请求链路追踪reqId 就像分布式系统中的 traceId
<TabItem label="Python" value="python">
</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:query_with_req_id}}
```
</TabItem>
<TabItem label="Node.js" value="node.js">
```js
{{#include docs/examples/node/websocketexample/sql_example.js:sqlWithReqid}}
```
</TabItem>
<TabItem label="C#" value="csharp">
</TabItem>
<TabItem label="R" value="r">
```csharp
{{#include docs/examples/csharp/wsInsert/Program.cs:query_id}}
```
</TabItem>
<TabItem label="C" value="c">
```c
{{#include docs/examples/c/CWithReqIdDemo.c:with_reqid}}
```
</TabItem>
<TabItem label="PHP" value="php">
<TabItem label="REST API" value="rest">
查询数据,指定 reqId 为 3
```bash
curl --location -uroot:taosdata 'http://127.0.0.1:6041/rest/sql?req_id=3' \
--data 'SELECT ts, current, location FROM power.meters limit 1'
```
</TabItem>
</Tabs>

View File

@ -161,7 +161,7 @@ st,t1=3,t2=4,t3=t3 c1=3i64,c6="passit" 1626006833640000000
### Websocket 连接
<Tabs defaultValue="java" groupId="schemaless">
<Tabs defaultValue="java" groupId="lang">
<TabItem value="java" label="Java">
```java
@ -179,17 +179,29 @@ 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
{{#include docs/examples/node/websocketexample/line_example.js}}
```
</TabItem>
<TabItem label="C#" value="csharp">
</TabItem>
<TabItem label="R" value="r">
```csharp
{{#include docs/examples/csharp/wssml/Program.cs:main}}
```
</TabItem>
<TabItem label="C" value="c">
</TabItem>
<TabItem label="PHP" value="php">
</TabItem>
</Tabs>
### 原生连接
@ -205,21 +217,27 @@ 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">
```go
{{#include docs/examples/go/schemaless/native/main.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="C" value="c">
```c
{{#include docs/examples/c/CSmlInsertDemo.c:schemaless}}
```
</TabItem>
</Tabs>
@ -232,17 +250,16 @@ writer.write(lineDemo, SchemalessProtocolType.LINE, SchemalessTimestampType.NANO
<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>
</Tabs>

View File

@ -39,28 +39,30 @@ 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">
```js
{{#include docs/examples/node/websocketexample/sql_example.js:createConnect}}
```
```js
{{#include docs/examples/node/websocketexample/stmt_example.js:createConnect}}
```
</TabItem>
<TabItem label="C#" value="csharp">
</TabItem>
<TabItem label="R" value="r">
```csharp
{{#include docs/examples/csharp/wsStmt/Program.cs:main}}
```
</TabItem>
<TabItem label="C" value="c">
</TabItem>
<TabItem label="PHP" value="php">
</TabItem>
</Tabs>
@ -79,22 +81,22 @@ 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">
</TabItem>
<TabItem label="R" value="r">
```csharp
{{#include docs/examples/csharp/stmtInsert/Program.cs:main}}
```
</TabItem>
<TabItem label="C" value="c">
</TabItem>
<TabItem label="PHP" value="php">
```c
{{#include docs/examples/c/CStmtInsertDemo.c}}
```
</TabItem>
</Tabs>

View File

@ -46,7 +46,7 @@ TDengine 消费者的概念跟 Kafka 类似,消费者通过订阅主题来接
下面是各语言连接器创建参数:
<Tabs defaultValue="java" groupId="lang">
<TabItem value="java" label="Java">
Java 连接器创建消费者的参数为 Properties 可以设置的参数列表请参考 [API 说明](../../reference/connector/java/#消费者)
Java 连接器创建消费者的参数为 Properties 可以设置的参数列表请参考 [消费者参数](../../reference/connector/java/#消费者)
其他参数请参考上文通用基础配置项。
@ -56,24 +56,43 @@ 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">
创建消费者支持属性列表:
</TabItem>
<TabItem label="R" value="r">
- `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="C" value="c">
</TabItem>
<TabItem label="PHP" value="php">
</TabItem>
</Tabs>
@ -97,31 +116,39 @@ 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/restexample/examples/tmq.rs:create_consumer_dsn}}
```
```rust
{{#include docs/examples/rust/restexample/examples/tmq.rs:create_consumer_ac}}
```
</TabItem>
<TabItem label="Node.js" value="node">
```js
{{#include docs/examples/node/websocketexample/tmq_example.js:create_consumer}}
```
</TabItem>
<TabItem label="C#" value="csharp">
</TabItem>
<TabItem label="R" value="r">
```csharp
{{#include docs/examples/csharp/wssubscribe/Program.cs:create_consumer}}
```
</TabItem>
<TabItem label="C" value="c">
</TabItem>
<TabItem label="PHP" value="php">
</TabItem>
</Tabs>
@ -149,28 +176,32 @@ 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">
```rust
{{#include docs/examples/rust/nativeexample/examples/tmq.rs:create_consumer_dsn}}
```
```rust
{{#include docs/examples/rust/nativeexample/examples/tmq.rs:create_consumer_ac}}
```
</TabItem>
<TabItem label="C#" value="csharp">
</TabItem>
<TabItem label="R" value="r">
```csharp
{{#include docs/examples/csharp/subscribe/Program.cs:create_consumer}}
```
</TabItem>
<TabItem label="C" value="c">
</TabItem>
<TabItem label="PHP" value="php">
</TabItem>
</Tabs>
## 订阅消费数据
@ -197,31 +228,35 @@ Java 连接器创建消费者的参数为 Properties 可以设置的参数列
</TabItem>
<TabItem label="Go" value="go">
```go
{{#include docs/examples/go/tmq/ws/main.go:subscribe}}
```
</TabItem>
<TabItem label="Rust" value="rust">
消费者可订阅一个或多个 `TOPIC`,一般建议一个消费者只订阅一个 `TOPIC`
TMQ 消息队列是一个 [futures::Stream](https://docs.rs/futures/latest/futures/stream/index.html) 类型,可以使用相应 API 对每个消息进行消费,并通过 `.commit` 进行已消费标记。
```rust
{{#include docs/examples/rust/restexample/examples/tmq.rs:consume}}
```
</TabItem>
<TabItem label="Node.js" value="node">
```js
{{#include docs/examples/node/websocketexample/tmq_seek_example.js:subscribe}}
```
</TabItem>
<TabItem label="C#" value="csharp">
</TabItem>
<TabItem label="R" value="r">
```csharp
{{#include docs/examples/csharp/wssubscribe/Program.cs:subscribe}}
```
</TabItem>
<TabItem label="C" value="c">
</TabItem>
<TabItem label="PHP" value="php">
</TabItem>
</Tabs>
@ -241,28 +276,25 @@ Java 连接器创建消费者的参数为 Properties 可以设置的参数列
</TabItem>
<TabItem label="Go" value="go">
```go
{{#include docs/examples/go/tmq/native/main.go:subscribe}}
```
</TabItem>
<TabItem label="Rust" value="rust">
同 Websocket 示例代码
</TabItem>
<TabItem label="C#" value="csharp">
</TabItem>
<TabItem label="R" value="r">
```csharp
{{#include docs/examples/csharp/subscribe/Program.cs:subscribe}}
```
</TabItem>
<TabItem label="C" value="c">
</TabItem>
<TabItem label="PHP" value="php">
</TabItem>
</Tabs>
## 指定订阅的 Offset
@ -275,6 +307,10 @@ Java 连接器创建消费者的参数为 Properties 可以设置的参数列
```java
{{#include examples/JDBC/JDBCDemo/src/main/java/com/taosdata/example/WsConsumerLoopFull.java:consumer_seek}}
```
1. 使用 consumer.poll 方法轮询数据,直到获取到数据为止。
2. 对于轮询到的第一批数据,打印第一条数据的内容,并获取当前消费者的分区分配信息。
3. 使用 consumer.seekToBeginning 方法将所有分区的偏移量重置到开始位置,并打印成功重置的消息。
4. 再次使用 consumer.poll 方法轮询数据,并打印第一条数据的内容。
</TabItem>
@ -286,32 +322,42 @@ Java 连接器创建消费者的参数为 Properties 可以设置的参数列
</TabItem>
<TabItem label="Go" value="go">
```go
{{#include docs/examples/go/tmq/ws/main.go:seek}}
```
</TabItem>
<TabItem label="Rust" value="rust">
```rust
{{#include docs/examples/rust/nativeexample/examples/tmq.rs:seek_offset}}
```
1. 通过调用 consumer.assignments() 方法获取消费者当前的分区分配信息,并记录初始分配状态。
2. 遍历每个分区分配信息对于每个分区提取主题topic、消费组IDvgroup_id、当前偏移量current、起始偏移量begin和结束偏移量end
记录这些信息。
1. 调用 consumer.offset_seek 方法将偏移量设置到起始位置。如果操作失败,记录错误信息和当前分配状态。
2. 在所有分区的偏移量调整完成后,再次获取并记录消费者的分区分配信息,以确认偏移量调整后的状态。
</TabItem>
<TabItem label="Node.js" value="node">
```js
{{#include docs/examples/node/websocketexample/tmq_seek_example.js:offset}}
```
</TabItem>
<TabItem label="C#" value="csharp">
</TabItem>
<TabItem label="R" value="r">
```csharp
{{#include docs/examples/csharp/wssubscribe/Program.cs:seek}}
```
</TabItem>
<TabItem label="C" value="c">
</TabItem>
<TabItem label="PHP" value="php">
</TabItem>
</Tabs>
### 原生连接
@ -330,27 +376,23 @@ Java 连接器创建消费者的参数为 Properties 可以设置的参数列
</TabItem>
<TabItem label="Go" value="go">
```go
{{#include docs/examples/go/tmq/native/main.go:seek}}
```
</TabItem>
<TabItem label="Rust" value="rust">
同 Websocket 代码样例。
</TabItem>
<TabItem label="C#" value="csharp">
</TabItem>
<TabItem label="R" value="r">
```csharp
{{#include docs/examples/csharp/subscribe/Program.cs:seek}}
```
</TabItem>
<TabItem label="C" value="c">
</TabItem>
<TabItem label="PHP" value="php">
</TabItem>
</Tabs>
@ -358,6 +400,9 @@ Java 连接器创建消费者的参数为 Properties 可以设置的参数列
## 提交 Offset
当消费者读取并处理完消息后,它可以提交 Offset这表示消费者已经成功处理到这个 Offset 的消息。Offset 提交可以是自动的(根据配置定期提交)或手动的(应用程序控制何时提交)。
当创建消费者时,属性 `enable.auto.commit` 为 false 时,可以手动提交 offset。
**注意**:手工提交消费进度前确保消息正常处理完成,否则处理出错的消息不会被再次消费。自动提交是在本次 `poll` 消息时可能会提交上次消息的消费进度,因此请确保消息处理完毕再进行下一次 `poll` 或消息获取。
### Websocket 连接
<Tabs defaultValue="java" groupId="lang">
<TabItem value="java" label="Java">
@ -377,33 +422,35 @@ Java 连接器创建消费者的参数为 Properties 可以设置的参数列
</TabItem>
<TabItem label="Go" value="go">
```go
{{#include docs/examples/go/tmq/ws/main.go:commit_offset}}
```
</TabItem>
<TabItem label="Rust" value="rust">
```rust
{{#include docs/examples/rust/restexample/examples/subscribe_demo.rs:consumer_commit_manually}}
```
可以通过 `consumer.commit` 方法来手工提交消费进度。
</TabItem>
<TabItem label="Node.js" value="node">
```js
{{#include docs/examples/node/websocketexample/tmq_example.js:commit}}
```
</TabItem>
<TabItem label="C#" value="csharp">
</TabItem>
<TabItem label="R" value="r">
```csharp
{{#include docs/examples/csharp/wssubscribe/Program.cs:commit_offset}}
```
</TabItem>
<TabItem label="C" value="c">
</TabItem>
<TabItem label="PHP" value="php">
</TabItem>
</Tabs>
### 原生连接
@ -423,11 +470,13 @@ Java 连接器创建消费者的参数为 Properties 可以设置的参数列
</TabItem>
<TabItem label="Go" value="go">
```go
{{#include docs/examples/go/tmq/native/main.go:commit_offset}}
```
</TabItem>
<TabItem label="Rust" value="rust">
同 Websocket 代码样例。
</TabItem>
<TabItem label="Node.js" value="node">
@ -435,21 +484,14 @@ Java 连接器创建消费者的参数为 Properties 可以设置的参数列
</TabItem>
<TabItem label="C#" value="csharp">
</TabItem>
<TabItem label="R" value="r">
```csharp
{{#include docs/examples/csharp/subscribe/Program.cs:commit_offset}}
```
</TabItem>
<TabItem label="C" value="c">
</TabItem>
<TabItem label="PHP" value="php">
</TabItem>
</Tabs>
@ -474,37 +516,40 @@ Java 连接器创建消费者的参数为 Properties 可以设置的参数列
</TabItem>
<TabItem label="Go" value="go">
```go
{{#include docs/examples/go/tmq/ws/main.go:close}}
```
</TabItem>
<TabItem label="Rust" value="rust">
```rust
{{#include docs/examples/rust/restexample/examples/tmq.rs:unsubscribe}}
```
**注意**:消费者取消订阅后无法重用,如果想订阅新的 `topic` 请重新创建消费者。
</TabItem>
<TabItem label="Node.js" value="node">
```js
{{#include docs/examples/node/websocketexample/tmq_example.js:unsubscribe}}
```
</TabItem>
<TabItem label="C#" value="csharp">
</TabItem>
<TabItem label="R" value="r">
```csharp
{{#include docs/examples/csharp/wssubscribe/Program.cs:close}}
```
</TabItem>
<TabItem label="C" value="c">
</TabItem>
<TabItem label="PHP" value="php">
</TabItem>
</Tabs>
### 原生连接
<Tabs groupId="lang">
<Tabs defaultValue="java" groupId="lang">
<TabItem value="java" label="Java">
同 Websocket 代码样例。
@ -519,11 +564,13 @@ Java 连接器创建消费者的参数为 Properties 可以设置的参数列
</TabItem>
<TabItem label="Go" value="go">
```go
{{#include docs/examples/go/tmq/native/main.go:close}}
```
</TabItem>
<TabItem label="Rust" value="rust">
同 Websocket 代码样例。
</TabItem>
<TabItem label="Node.js" value="node">
@ -531,21 +578,15 @@ Java 连接器创建消费者的参数为 Properties 可以设置的参数列
</TabItem>
<TabItem label="C#" value="csharp">
</TabItem>
<TabItem label="R" value="r">
```csharp
{{#include docs/examples/csharp/subscribe/Program.cs:close}}
```
</TabItem>
<TabItem label="C" value="c">
</TabItem>
<TabItem label="PHP" value="php">
</TabItem>
</Tabs>
@ -571,33 +612,34 @@ Java 连接器创建消费者的参数为 Properties 可以设置的参数列
</TabItem>
<TabItem label="Go" value="go">
```go
{{#include docs/examples/go/tmq/ws/main.go}}
```
</TabItem>
<TabItem label="Rust" value="rust">
```rust
{{#include docs/examples/rust/restexample/examples/subscribe_demo.rs}}
```
</TabItem>
<TabItem label="Node.js" value="node">
```js
{{#include docs/examples/node/websocketexample/tmq_example.js}}
```
</TabItem>
<TabItem label="C#" value="csharp">
</TabItem>
<TabItem label="R" value="r">
```csharp
{{#include docs/examples/csharp/wssubscribe/Program.cs}}
```
</TabItem>
<TabItem label="C" value="c">
</TabItem>
<TabItem label="PHP" value="php">
</TabItem>
</Tabs>
### 原生连接
@ -624,11 +666,15 @@ Java 连接器创建消费者的参数为 Properties 可以设置的参数列
</TabItem>
<TabItem label="Go" value="go">
```go
{{#include docs/examples/go/tmq/native/main.go}}
```
</TabItem>
<TabItem label="Rust" value="rust">
```rust
{{#include docs/examples/rust/nativeexample/examples/subscribe_demo.rs}}
```
</TabItem>
<TabItem label="Node.js" value="node">
@ -636,19 +682,12 @@ Java 连接器创建消费者的参数为 Properties 可以设置的参数列
</TabItem>
<TabItem label="C#" value="csharp">
</TabItem>
<TabItem label="R" value="r">
```csharp
{{#include docs/examples/csharp/subscribe/Program.cs}}
```
</TabItem>
<TabItem label="C" value="c">
</TabItem>
<TabItem label="PHP" value="php">
</TabItem>
</Tabs>

View File

@ -12,16 +12,6 @@ import RequestId from "./_request_id.mdx";
`driver-go` 是 TDengine 的官方 Go 语言连接器,实现了 Go 语言 [database/sql](https://golang.org/pkg/database/sql/) 包的接口。Go 开发人员可以通过它开发存取 TDengine 集群数据的应用软件。
## 连接方式
`driver-go` 提供三种建立连接的方式。
* **原生连接**,通过 TDengine 客户端驱动程序taosc原生连接 TDengine 实例支持数据写入、查询、数据订阅、schemaless 接口和参数绑定接口等功能。
* **REST 连接**,通过 taosAdapter 提供的 HTTP 接口连接 TDengine 实例,不支持 schemaless 和数据订阅等特性。
* **Websocket 连接**,通过 taosAdapter 提供的 Websocket 接口连接 TDengine 实例WebSocket 连接实现的功能集合和原生连接有少量不同。
连接方式的详细介绍请参考:[连接器建立连接的方式](../../develop/connect/#连接器建立连接的方式)
## 兼容性
支持最低 Go 版本 1.14,建议使用最新 Go 版本
@ -52,7 +42,7 @@ REST 连接支持所有能运行 Go 的平台。
}
```
## TDengine DataType 和 Go DataType
## 数据类型映射
| TDengine DataType | Go Type |
|-------------------|-----------|
@ -74,300 +64,6 @@ REST 连接支持所有能运行 Go 的平台。
**注意**JSON 类型仅在 tag 中支持。
## 安装步骤
### 安装前准备
* 安装 Go 开发环境Go 1.14 及以上GCC 4.8.5 及以上)
* 如果使用原生连接器,请安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../#安装客户端驱动)
配置好环境变量,检查命令:
* ```go env```
* ```gcc -v```
### 安装连接器
1. 使用 `go mod` 命令初始化项目:
```text
go mod init taos-demo
```
2. 引入 taosSql
```go
import (
"database/sql"
_ "github.com/taosdata/driver-go/v3/taosSql"
)
```
3. 使用 `go mod tidy` 更新依赖包:
```text
go mod tidy
```
4. 使用 `go run taos-demo` 运行程序或使用 `go build` 命令编译出二进制文件。
```text
go run taos-demo
go build
```
## 建立连接
数据源名称具有通用格式,例如 [PEAR DB](http://pear.php.net/manual/en/package.database.db.intro-dsn.php),但没有类型前缀(方括号表示可选):
``` text
[username[:password]@][protocol[(address)]]/[dbname][?param1=value1&...&paramN=valueN]
```
完整形式的 DSN
```text
username:password@protocol(address)/dbname?param=value
```
<Tabs defaultValue="rest" groupId="connect">
<TabItem value="native" label="原生连接">
_taosSql_ 通过 cgo 实现了 Go 的 `database/sql/driver` 接口。只需要引入驱动就可以使用 [`database/sql`](https://golang.org/pkg/database/sql/) 的接口。
使用 `taosSql` 作为 `driverName` 并且使用一个正确的 [DSN](#DSN) 作为 `dataSourceName`DSN 支持的参数:
* cfg 指定 taos.cfg 目录
示例:
```go
package main
import (
"database/sql"
"fmt"
_ "github.com/taosdata/driver-go/v3/taosSql"
)
func main() {
var taosUri = "root:taosdata@tcp(localhost:6030)/"
taos, err := sql.Open("taosSql", taosUri)
if err != nil {
fmt.Println("failed to connect TDengine, err:", err)
return
}
}
```
</TabItem>
<TabItem value="rest" label="REST 连接">
_taosRestful_ 通过 `http client` 实现了 Go 的 `database/sql/driver` 接口。只需要引入驱动就可以使用[`database/sql`](https://golang.org/pkg/database/sql/)的接口。
使用 `taosRestful` 作为 `driverName` 并且使用一个正确的 [DSN](#DSN) 作为 `dataSourceName`DSN 支持的参数:
* `disableCompression` 是否接受压缩数据,默认为 true 不接受压缩数据,如果传输数据使用 gzip 压缩设置为 false。
* `readBufferSize` 读取数据的缓存区大小默认为 4K4096当查询结果数据量多时可以适当调大该值。
示例:
```go
package main
import (
"database/sql"
"fmt"
_ "github.com/taosdata/driver-go/v3/taosRestful"
)
func main() {
var taosUri = "root:taosdata@http(localhost:6041)/"
taos, err := sql.Open("taosRestful", taosUri)
if err != nil {
fmt.Println("failed to connect TDengine, err:", err)
return
}
}
```
</TabItem>
<TabItem value="WebSocket" label="WebSocket 连接">
_taosWS_ 通过 `WebSocket` 实现了 Go 的 `database/sql/driver` 接口。只需要引入驱动driver-go 最低版本 3.0.2)就可以使用[`database/sql`](https://golang.org/pkg/database/sql/)的接口。
使用 `taosWS` 作为 `driverName` 并且使用一个正确的 [DSN](#DSN) 作为 `dataSourceName`DSN 支持的参数:
* `writeTimeout` 通过 WebSocket 发送数据的超时时间。
* `readTimeout` 通过 WebSocket 接收响应数据的超时时间。
示例:
```go
package main
import (
"database/sql"
"fmt"
_ "github.com/taosdata/driver-go/v3/taosWS"
)
func main() {
var taosUri = "root:taosdata@ws(localhost:6041)/"
taos, err := sql.Open("taosWS", taosUri)
if err != nil {
fmt.Println("failed to connect TDengine, err:", err)
return
}
}
```
</TabItem>
</Tabs>
### 指定 URL 和 Properties 获取连接
Go 连接器不支持此功能
### 配置参数的优先级
Go 连接器不支持此功能
## 使用示例
### 创建数据库和表
```go
{{#include docs/examples/go/demo/query/main.go:create_db_and_table}}
```
### 插入数据
```go
{{#include docs/examples/go/demo/query/main.go:insert_data}}
```
### 查询数据
```go
{{#include docs/examples/go/demo/query/main.go:query_data}}
```
### 执行带有 reqId 的 SQL
<RequestId />
```go
{{#include docs/examples/go/demo/query/main.go:with_reqid}}
```
### 通过参数绑定写入数据
<Tabs defaultValue="native" groupId="connect">
<TabItem value="native" label="原生连接">
```go
{{#include docs/examples/go/demo/stmt/main.go}}
```
</TabItem>
<TabItem value="WebSocket" label="WebSocket 连接">
```go
{{#include docs/examples/go/demo/stmtws/main.go}}
```
</TabItem>
</Tabs>
### 无模式写入
<Tabs defaultValue="native" groupId="connect">
<TabItem value="native" label="原生连接">
```go
{{#include docs/examples/go/demo/sml/main.go}}
```
</TabItem>
<TabItem value="WebSocket" label="WebSocket 连接">
```go
{{#include docs/examples/go/demo/smlws/main.go}}
```
</TabItem>
</Tabs>
### 执行带有 reqId 的无模式写入
```go
func (s *Schemaless) Insert(lines string, protocol int, precision string, ttl int, reqID int64) error
```
可以通过 `common.GetReqID()` 获取唯一 id。
### 数据订阅
TDengine Go 连接器支持订阅功能,应用 API 如下:
#### 创建 Topic
```go
{{#include docs/examples/go/demo/consumer/main.go:create_topic}}
```
#### 创建 Consumer
```go
{{#include docs/examples/go/demo/consumer/main.go:create_consumer}}
```
#### 订阅消费数据
```go
{{#include docs/examples/go/demo/consumer/main.go:poll_data}}
```
#### 指定订阅 Offset
```go
{{#include docs/examples/go/demo/consumer/main.go:consumer_seek}}
```
#### 关闭订阅
```go
{{#include docs/examples/go/demo/consumer/main.go:consumer_close}}
```
#### 完整示例
<Tabs defaultValue="native" groupId="connect">
<TabItem value="native" label="原生连接">
```go
{{#include docs/examples/go/demo/consumer/main.go}}
```
</TabItem>
<TabItem value="WebSocket" label="WebSocket 连接">
```go
{{#include docs/examples/go/demo/consumerws/main.go}}
```
</TabItem>
</Tabs>
### 更多示例程序
* [示例程序](https://github.com/taosdata/driver-go/tree/3.0/examples)
* [视频教程](https://www.taosdata.com/blog/2020/11/11/1951.html)。
## 常见问题
1. database/sql 中 stmt参数绑定相关接口崩溃
@ -1065,7 +761,7 @@ type ConfigMap map[string]ConfigValue
- `ws.reconnectIntervalMs`WebSocket 重连间隔时间毫秒,默认 2000。
- `ws.reconnectRetryCount`WebSocket 重连重试次数,默认 3。
其他参数请参考:[Consumer 参数列表](../../../develop/tmq/#数据订阅相关参数) 注意TDengine服务端自 3.2.0.0 版本开始消息订阅中的 auto.offset.reset 默认值发生变化。
其他参数请参考:[Consumer 参数列表](../../../develop/tmq/#创建参数) 注意TDengine服务端自 3.2.0.0 版本开始消息订阅中的 auto.offset.reset 默认值发生变化。
- `func (c *Consumer) Subscribe(topic string, rebalanceCb RebalanceCb) error`
- **接口说明**:订阅主题。
@ -1195,4 +891,6 @@ type TopicPartition struct {
## 附录
[driver-go 文档](https://pkg.go.dev/github.com/taosdata/driver-go/v3)
* [driver-go 文档](https://pkg.go.dev/github.com/taosdata/driver-go/v3)。
* [示例程序](https://github.com/taosdata/driver-go/tree/3.0/examples)。
* [视频教程](https://www.taosdata.com/blog/2020/11/11/1951.html)。

View File

@ -82,360 +82,7 @@ TDengine 目前支持时间戳、数字、字符、布尔类型,与 Rust 对
**注意**JSON 类型仅在 tag 中支持。
## 安装步骤
### 安装前准备
* 安装 Rust 开发工具链
* 如果使用原生连接,请安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../#安装客户端驱动)
### 安装连接器
根据选择的连接方式,按照如下说明在 [Rust](https://rust-lang.org) 项目中添加 [taos][taos] 依赖:
<Tabs defaultValue="default">
<TabItem value="default" label="同时支持">
在 `Cargo.toml` 文件中添加 [taos][taos]
```toml
[dependencies]
# use default feature
taos = "*"
```
</TabItem>
<TabItem value="rest" label="仅 Websocket">
在 `Cargo.toml` 文件中添加 [taos][taos],并启用 `ws` 特性。
```toml
[dependencies]
taos = { version = "*", default-features = false, features = ["ws"] }
```
当仅启用 `ws` 特性时,可同时指定 `r2d2` 使得在同步blocking/sync模式下使用 [r2d2] 作为连接池:
```toml
[dependencies]
taos = { version = "*", default-features = false, features = ["r2d2", "ws"] }
```
</TabItem>
<TabItem value="native" label="仅原生连接">
在 `Cargo.toml` 文件中添加 [taos][taos],并启用 `native` 特性:
```toml
[dependencies]
taos = { version = "*", default-features = false, features = ["native"] }
```
</TabItem>
</Tabs>
## 建立连接
[TaosBuilder] 通过 DSN 连接描述字符串创建一个连接构造器。
```rust
let builder = TaosBuilder::from_dsn("taos://")?;
```
现在您可以使用该对象创建连接:
```rust
let conn = builder.build()?;
```
连接对象可以创建多个:
```rust
let conn1 = builder.build()?;
let conn2 = builder.build()?;
```
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 描述字符串示例如下:
```text
taos+ws://localhost:6041/test
```
表示使用 Websocket`ws`)方式通过 `6041` 端口连接服务器 `localhost`,并指定默认数据库为 `test`。
这使得用户可以通过 DSN 指定连接方式:
```rust
use taos::*;
// use native protocol.
let builder = TaosBuilder::from_dsn("taos://localhost:6030")?;
let conn1 = builder.build();
// use websocket protocol.
let builder2 = TaosBuilder::from_dsn("taos+ws://localhost:6041")?;
let conn2 = builder2.build();
```
建立连接后,您可以进行相关数据库操作:
```rust
async fn demo(taos: &Taos, db: &str) -> Result<(), Error> {
// prepare database
taos.exec_many([
format!("DROP DATABASE IF EXISTS `{db}`"),
format!("CREATE DATABASE `{db}`"),
format!("USE `{db}`"),
])
.await?;
let inserted = taos.exec_many([
// create super table
"CREATE TABLE `meters` (`ts` TIMESTAMP, `current` FLOAT, `voltage` INT, `phase` FLOAT) \
TAGS (`groupid` INT, `location` BINARY(24))",
// create child table
"CREATE TABLE `d0` USING `meters` TAGS(0, 'California.LosAngles')",
// insert into child table
"INSERT INTO `d0` values(now - 10s, 10, 116, 0.32)",
// insert with NULL values
"INSERT INTO `d0` values(now - 8s, NULL, NULL, NULL)",
// insert and automatically create table with tags if not exists
"INSERT INTO `d1` USING `meters` TAGS(1, 'California.SanFrancisco') values(now - 9s, 10.1, 119, 0.33)",
// insert many records in a single sql
"INSERT INTO `d1` values (now-8s, 10, 120, 0.33) (now - 6s, 10, 119, 0.34) (now - 4s, 11.2, 118, 0.322)",
]).await?;
assert_eq!(inserted, 6);
let mut result = taos.query("select * from `meters`").await?;
for field in result.fields() {
println!("got field: {}", field.name());
}
let values = result.
}
```
查询数据可以通过两种方式:使用内建类型或 [serde](https://serde.rs) 序列化框架。
```rust
// Query option 1, use rows stream.
let mut rows = result.rows();
while let Some(row) = rows.try_next().await? {
for (name, value) in row {
println!("got value of {}: {}", name, value);
}
}
// Query options 2, use deserialization with serde.
#[derive(Debug, serde::Deserialize)]
#[allow(dead_code)]
struct Record {
// deserialize timestamp to chrono::DateTime<Local>
ts: DateTime<Local>,
// float to f32
current: Option<f32>,
// int to i32
voltage: Option<i32>,
phase: Option<f32>,
groupid: i32,
// binary/varchar to String
location: String,
}
let records: Vec<Record> = taos
.query("select * from `meters`")
.await?
.deserialize()
.try_collect()
.await?;
dbg!(records);
Ok(())
```
## 使用示例
### 创建数据库和表
```rust
{{#include docs/examples/rust/nativeexample/examples/query.rs:create_db_and_table}}
```
> **注意**:如果不使用 `use db` 指定数据库,则后续对表的操作都需要增加数据库名称作为前缀,如 db.tb。
### 插入数据
```rust
{{#include docs/examples/rust/nativeexample/examples/query.rs:insert_data}}
```
### 查询数据
```rust
{{#include docs/examples/rust/nativeexample/examples/query.rs:query_data}}
```
### 执行带有 req_id 的 SQL
<RequestId />
```rust
{{#include docs/examples/rust/nativeexample/examples/query.rs:query_with_req_id}}
```
### 通过参数绑定写入数据
TDengine 的 Rust 连接器实现了参数绑定方式对数据写入INSERT场景的支持。采用这种方式写入数据时能避免 SQL 语法解析的资源消耗,从而在很多情况下显著提升写入性能。
参数绑定接口详见[API参考](#stmt-api)
```rust
{{#include docs/examples/rust/nativeexample/examples/stmt.rs}}
```
### 无模式写入
TDengine 支持无模式写入功能。无模式写入兼容 InfluxDB 的 行协议Line Protocol、OpenTSDB 的 telnet 行协议和 OpenTSDB 的 JSON 格式协议。详情请参见[无模式写入](../../reference/schemaless/)。
```rust
{{#include docs/examples/rust/nativeexample/examples/schemaless.rs}}
```
### 执行带有 req_id 的无模式写入
此 req_id 可用于请求链路追踪。
```rust
let sml_data = SmlDataBuilder::default()
.protocol(SchemalessProtocol::Line)
.data(data)
.req_id(100u64)
.build()?;
client.put(&sml_data)?
```
### 数据订阅
TDengine 通过消息队列 [TMQ](../../taos-sql/tmq/) 启动一个订阅。
#### 创建 Topic
```rust
{{#include docs/examples/rust/nativeexample/examples/tmq.rs:create_topic}}
```
#### 创建 Consumer
创建消费者:
```rust
{{#include docs/examples/rust/nativeexample/examples/tmq.rs:create_consumer}}
```
#### 订阅消费数据
消费者可订阅一个或多个 `TOPIC`。
```rust
{{#include docs/examples/rust/nativeexample/examples/tmq.rs:subscribe}}
```
TMQ 消息队列是一个 [futures::Stream](https://docs.rs/futures/latest/futures/stream/index.html) 类型,可以使用相应 API 对每个消息进行消费,并通过 `.commit` 进行已消费标记。
```rust
{{#include docs/examples/rust/nativeexample/examples/tmq.rs:consume}}
```
获取消费进度:
版本要求 connector-rust >= v0.8.8 TDengine >= 3.0.5.0
```rust
{{#include docs/examples/rust/nativeexample/examples/tmq.rs:assignments}}
```
#### 指定订阅 Offset
按照指定的进度消费:
版本要求 connector-rust >= v0.8.8 TDengine >= 3.0.5.0
```rust
{{#include docs/examples/rust/nativeexample/examples/tmq.rs:seek_offset}}
```
#### 关闭订阅
```rust
{{#include docs/examples/rust/nativeexample/examples/tmq.rs:unsubscribe}}
```
对于 TMQ DSN, 有以下配置项可以进行设置,需要注意的是,`group.id` 是必须的。
- `group.id`: 同一个消费者组,将以至少消费一次的方式进行消息负载均衡。
- `client.id`: 可选的订阅客户端识别项。
- `auto.offset.reset`: 可选初始化订阅起点, *earliest* 为从头开始订阅, *latest* 为仅从最新数据开始订阅,默认值根据 TDengine 版本有所不同,详细参见 [数据订阅](https://docs.taosdata.com/develop/tmq/)。注意,此选项在同一个 `group.id` 中仅生效一次。
- `enable.auto.commit`: 当设置为 `true` 时,将启用自动标记模式,当对数据一致性不敏感时,可以启用此方式。
- `auto.commit.interval.ms`: 自动标记的时间间隔。
#### 完整示例
完整订阅示例参见 [GitHub 示例文件](https://github.com/taosdata/TDengine/blob/3.0/docs/examples/rust/nativeexample/examples/tmq.rs).
### 与连接池使用
在复杂应用中,建议启用连接池。[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()?;
```
### 更多示例程序
## 示例程序汇总
示例程序源码位于 `TDengine/examples/rust` 下:
@ -445,168 +92,6 @@ let taos = pool.get()?;
请参考 [FAQ](../../train-faq/faq)
## API 参考
[Taos][struct.Taos] 对象提供了多个数据库操作的 API
1. `exec`: 执行某个非查询类 SQL 语句,例如 `CREATE``ALTER``INSERT` 等。
```rust
let affected_rows = taos.exec("INSERT INTO tb1 VALUES(now, NULL)").await?;
```
2. `exec_many`: 同时(顺序)执行多个 SQL 语句。
```rust
taos.exec_many([
"CREATE DATABASE test",
"USE test",
"CREATE TABLE `tb1` (`ts` TIMESTAMP, `val` INT)",
]).await?;
```
3. `query`:执行查询语句,返回 [ResultSet] 对象。
```rust
let mut q = taos.query("select * from log.logs").await?;
```
[ResultSet] 对象存储了查询结果数据和返回的列的基本信息(列名,类型,长度):
列信息使用 [.fields()] 方法获取:
```rust
let cols = q.fields();
for col in cols {
println!("name: {}, type: {:?} , bytes: {}", col.name(), col.ty(), col.bytes());
}
```
逐行获取数据:
```rust
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}`): {}",
nrows, col, name, value
);
}
nrows += 1;
}
```
或使用 [serde](https://serde.rs) 序列化框架。
```rust
#[derive(Debug, Deserialize)]
struct Record {
// deserialize timestamp to chrono::DateTime<Local>
ts: DateTime<Local>,
// float to f32
current: Option<f32>,
// int to i32
voltage: Option<i32>,
phase: Option<f32>,
groupid: i32,
// binary/varchar to String
location: String,
}
let records: Vec<Record> = taos
.query("select * from `meters`")
.await?
.deserialize()
.try_collect()
.await?;
```
需要注意的是,需要使用 Rust 异步函数和异步运行时。
[Taos][struct.Taos] 提供部分 SQL 的 Rust 方法化以减少 `format!` 代码块的频率:
- `.describe(table: &str)`: 执行 `DESCRIBE` 并返回一个 Rust 数据结构。
- `.create_database(database: &str)`: 执行 `CREATE DATABASE` 语句。
- `.use_database(database: &str)`: 执行 `USE` 语句。
除此之外,该结构也是参数绑定和行协议接口的入口,使用方法请参考具体的 API 说明。
<p>
<a id="stmt-api" style={{color:'#141414'}}>
参数绑定接口
</a>
</p>
与 C 接口类似Rust 提供参数绑定接口。首先,通过 [Taos][struct.Taos] 对象创建一个 SQL 语句的参数绑定对象 [Stmt]
```rust
let mut stmt = Stmt::init(&taos).await?;
stmt.prepare("INSERT INTO ? USING meters TAGS(?, ?) VALUES(?, ?, ?, ?)")?;
```
参数绑定对象提供了一组接口用于实现参数绑定:
`.set_tbname(name)`
用于绑定表名。
```rust
let mut stmt = taos.stmt("insert into ? values(? ,?)")?;
stmt.set_tbname("d0")?;
```
`.set_tags(&[tag])`
当 SQL 语句使用超级表时,用于绑定子表表名和标签值:
```rust
let mut stmt = taos.stmt("insert into ? using stb0 tags(?) values(? ,?)")?;
stmt.set_tbname("d0")?;
stmt.set_tags(&[Value::VarChar("涛思".to_string())])?;
```
`.bind(&[column])`
用于绑定值类型。使用 [ColumnView] 结构体构建需要的类型并绑定:
```rust
let params = vec![
ColumnView::from_millis_timestamp(vec![164000000000]),
ColumnView::from_bools(vec![true]),
ColumnView::from_tiny_ints(vec![i8::MAX]),
ColumnView::from_small_ints(vec![i16::MAX]),
ColumnView::from_ints(vec![i32::MAX]),
ColumnView::from_big_ints(vec![i64::MAX]),
ColumnView::from_unsigned_tiny_ints(vec![u8::MAX]),
ColumnView::from_unsigned_small_ints(vec![u16::MAX]),
ColumnView::from_unsigned_ints(vec![u32::MAX]),
ColumnView::from_unsigned_big_ints(vec![u64::MAX]),
ColumnView::from_floats(vec![f32::MAX]),
ColumnView::from_doubles(vec![f64::MAX]),
ColumnView::from_varchar(vec!["ABC"]),
ColumnView::from_nchar(vec!["涛思数据"]),
];
let rows = stmt.bind(&params)?.add_batch()?.execute()?;
```
`.execute()`
执行 SQL。[Stmt] 对象可以复用,在执行后可以重新绑定并执行。执行前请确保所有数据已通过 `.add_batch` 加入到执行队列中。
```rust
stmt.execute()?;
// next bind cycle.
//stmt.set_tbname()?;
//stmt.bind()?;
//stmt.execute()?;
```
一个可运行的示例请见 [GitHub 上的示例](https://github.com/taosdata/taos-connector-rust/blob/main/examples/bind.rs)。
## API 参考
Rust 连接器的接口分为同步接口和异步接口,一般同步接口是由异步接口实现,方法签名除 async 关键字外基本相同。对于同步接口和异步接口功能一样的接口,本文档只提供同步接口的说明。
@ -640,16 +125,16 @@ DSN 描述字符串基本结构如下:
一个完整的 DSN 描述字符串示例如下:`taos+ws://localhost:6041/test` 表示使用 Websocket`ws`)方式通过 `6041` 端口连接服务器 `localhost`,并指定默认数据库为 `test`。
#### TaosBuilder
TaosBuilder 结构体提供了建立连接,检查连接,以及获取服务端版本号等功能。
TaosBuilder 结构体主要提供了根据 DSN 构建 Taos 对象的方法,还提供了检查连接,以及获取客户端版本号等功能。
- `fn available_params() -> &'static [&'static str]`
- **接口说明**获取DSN中可用的参数列表。
- **接口说明**:获取 DSN 中可用的参数列表。
- **返回值**:返回静态字符串切片的引用,包含可用的参数名称。
- `fn from_dsn<D: IntoDsn>(dsn: D) -> RawResult<Self>`
- **接口说明**使用DSN字符串创建连接不检查连接。
- **接口说明**:使用 DSN 字符串创建连接,不检查连接。
- **参数说明**
- `dsn`DSN字符串或可转换为DSN的类型。
- `dsn`DSN 字符串或可转换为 DSN 的类型。
- **返回值**:成功时返回自身类型的 `RawResult`,失败时返回错误。
- `fn client_version() -> &'static str`
@ -664,14 +149,15 @@ TaosBuilder 结构体提供了建立连接,检查连接,以及获取服务
- `fn ready(&self) -> bool`
- **接口说明**:检查是否准备好连接。
- **返回值**大多数情况下返回true表示地址准备好连接。
- **返回值**:大多数情况下返回 `true`,表示地址准备好连接。
- `fn build(&self) -> RawResult<Self::Target>`
- **接口说明**:从此结构创建新的连接
- **接口说明**:从此结构创建新的 Taos 对象
- **返回值**:成功时返回目标连接类型的 `RawResult`,失败时返回错误。
### 执行 SQL
执行 SQL 主要涉及到 Taos 结构体,以及结果集 ResultSet 结构体,还有列信息 Field。
执行 SQL 主要使用 Taos 结构体,获取结果集以及元数据需要使用下节介绍的 ResultSet 结构体 和列信息 Field 结构体。
#### Taos
Taos 结构体提供了多个数据库操作的 API包括执行 SQL无模式写入以及一些常用数据库查询的封装如创建数据库获取
@ -684,34 +170,34 @@ Taos 结构体提供了多个数据库操作的 API包括执行 SQL
- **返回值**如果使用websocket协议则返回 `true`,否则返回 `false`。
- `fn query<T: AsRef<str>>(&self, sql: T) -> RawResult<Self::ResultSet>`
- **接口说明**执行SQL查询。
- **接口说明**:执行 SQL 查询。
- **参数说明**
- `sql`要执行的SQL语句。
- `sql`:要执行的 SQL 语句。
- **返回值**:成功时返回结果集 `ResultSet` 的 `RawResult`,失败时返回错误。
- `fn query_with_req_id<T: AsRef<str>>(&self, sql: T, req_id: u64) -> RawResult<Self::ResultSet>`
- **接口说明**带请求ID执行SQL查询。
- **接口说明**:带请求 ID 执行 SQL 查询。
- **参数说明**
- `sql`要执行的SQL语句。
- `req_id`请求ID。
- `sql`:要执行的 SQL 语句。
- `req_id`:请求 ID。
- **返回值**:成功时返回结果集 `ResultSet` 的 `RawResult`,失败时返回错误。
- `fn exec<T: AsRef<str>>(&self, sql: T) -> RawResult<usize>`
- **接口说明**执行SQL语句。
- **接口说明**:执行 SQL 语句。
- **参数说明**
- `sql`要执行的SQL语句。
- `sql`:要执行的 SQL 语句。
- **返回值**:成功时返回受影响的行数,失败时返回错误。
- `fn exec_many<T: AsRef<str>, I: IntoIterator<Item = T>>(&self, input: I) -> RawResult<usize>`
- **接口说明**批量执行SQL语句。
- **接口说明**:批量执行 SQL 语句。
- **参数说明**
- `input`要执行的SQL语句集合。
- `input`:要执行的 SQL 语句集合。
- **返回值**:成功时返回总共受影响的行数,失败时返回错误。
- `fn query_one<T: AsRef<str>, O: DeserializeOwned>(&self, sql: T) -> RawResult<Option<O>>`
- **接口说明**执行SQL查询并返回单个结果。
- **接口说明**:执行 SQL 查询并返回单个结果。
- **参数说明**
- `sql`要执行的SQL语句。
- `sql`:要执行的 SQL 语句。
- **返回值**:成功时返回可选的结果对象,失败时返回错误。
- `fn server_version(&self) -> RawResult<Cow<str>>`
@ -722,7 +208,7 @@ Taos 结构体提供了多个数据库操作的 API包括执行 SQL
- **接口说明**:创建主题。
- **参数说明**
- `name`:主题名称。
- `sql`关联的SQL语句。
- `sql`:关联的 SQ L语句。
- **返回值**:成功时返回空的 `RawResult`,失败时返回错误。
- `fn databases(&self) -> RawResult<Vec<ShowDatabase>>`
@ -737,7 +223,7 @@ Taos 结构体提供了多个数据库操作的 API包括执行 SQL
- **接口说明**:描述表结构。
- **参数说明**
- `table`:表名称。
- **返回值**:成功时返回表描述的 `RawResult`,失败时返回错误。
- **返回值**:成功时返回表结构描述的 `RawResult`,失败时返回错误。
- `fn database_exists(&self, name: &str) -> RawResult<bool>`
- **接口说明**:检查数据库是否存在。
@ -746,12 +232,43 @@ Taos 结构体提供了多个数据库操作的 API包括执行 SQL
- **返回值**:成功时返回布尔值的 `RawResult`,指示数据库是否存在,失败时返回错误。
- `fn put(&self, data: &SmlData) -> RawResult<()>`
- **接口说明**:写入无模式数据。
- **接口说明**:写入无模式数据SmlData 结构介绍见下文
- **参数说明**
- `data`:无模式数据。
- **返回值**:成功时返回空的 `RawResult`,失败时返回错误。
### SmlData
SmlData 结构体提供了无模式写入的数据结构,以及获取属性的方法。
- `pub struct SmlData`
- **结构体说明**`SmlData` 结构体用于存储无模式数据及其相关信息。
- **字段说明**
- `protocol`:无模式协议,支持 `Line`, `Telnet`, `Json`, 三种。
- `precision`:时间戳精度,支持 `Hours`, `Minutes`, `Seconds`, `Millisecond`(默认), `Microsecond`, `Nanosecond`。
- `data`:数据列表。
- `ttl`:数据存活时间,单位为秒。
- `req_id`:请求 ID。
- `pub fn protocol(&self) -> SchemalessProtocol`
- **接口说明**:获取无模式协议。
- **返回值**:无模式协议类型,支持 `Line`, `Telnet`, `Json`, 三种。
- `pub fn precision(&self) -> SchemalessPrecision`
- **接口说明**:获取时间戳精度。
- **返回值**:时间戳精度类型,支持 `Hours`, `Minutes`, `Seconds`, `Millisecond`(默认), `Microsecond`, `Nanosecond`。
- `pub fn data(&self) -> &Vec<String>`
- **接口说明**:获取数据列表。
- **返回值**:数据列表的引用。
- `pub fn ttl(&self) -> Option<i32>`
- **接口说明**:获取数据存活时间。
- **返回值**:数据存活时间(可选),单位为秒。
- `pub fn req_id(&self) -> Option<u64>`
- **接口说明**:获取请求 ID。
- **返回值**:请求 ID可选
### 结果获取
#### ResultSet
ResultSet 结构体提供了结果集的一些方法,可以用来获取结果集的数据和元数据。
@ -844,16 +361,16 @@ Stmt 结构体提供了参数绑定相关功能,用于实现高效写入。
- **返回值**:成功时返回初始化的实例,失败时返回错误。
- `fn init_with_req_id(taos: &Q, req_id: u64) -> RawResult<Self>`
- **接口说明**使用请求ID初始化参数绑定实例。
- **接口说明**:使用请求 ID 初始化参数绑定实例。
- **参数说明**
- `taos`:数据库连接实例。
- `req_id`请求ID。
- `req_id`:请求 ID。
- **返回值**:成功时返回初始化的实例,失败时返回错误。
- `fn prepare<S: AsRef<str>>(&mut self, sql: S) -> RawResult<&mut Self>`
- **接口说明**:准备要绑定的 SQL 语句。
- **参数说明**
- `sql`要准备的SQL语句。
- `sql`:要准备的 SQL 语句。
- **返回值**:成功时返回自身的可变引用,失败时返回错误。
- `fn set_tbname<S: AsRef<str>>(&mut self, name: S) -> RawResult<&mut Self>`
@ -921,7 +438,7 @@ Stmt 结构体提供了参数绑定相关功能,用于实现高效写入。
- `fn ready(&self) -> bool`
- **接口说明**:检查是否准备好连接。
- **返回值**大多数情况下返回true表示地址准备好连接。
- **返回值**:大多数情况下返回 `true`,表示地址准备好连接。
- `fn build(&self) -> RawResult<Self::Target>`
- **接口说明**:从此结构创建新的连接。
@ -1002,12 +519,8 @@ Offset 结构体提供了获取当前消息所属的数据库,主题和分区
- **接口说明**:获取当前消息的分区 ID。
- **返回值**:分区 ID。
其他相关结构体 API 使用说明请移步 Rust 文档托管网页https://docs.rs/taos。
[taos]: https://github.com/taosdata/rust-connector-taos
[deadpool]: https://crates.io/crates/deadpool
[r2d2]: https://crates.io/crates/r2d2
[TaosBuilder]: https://docs.rs/taos/latest/taos/struct.TaosBuilder.html
[TaosCfg]: https://docs.rs/taos/latest/taos/struct.TaosCfg.html
[struct.Taos]: https://docs.rs/taos/latest/taos/struct.Taos.html
[Stmt]: https://docs.rs/taos/latest/taos/struct.Stmt.html
## 附录
- Rust 连接器文档https://docs.rs/taos
- Rust 连接器项目地址: https://github.com/taosdata/rust-connector-taos
- deadpool 连接池: https://crates.io/crates/deadpool
- r2d2 连接池: https://crates.io/crates/r2d2

File diff suppressed because it is too large Load Diff

View File

@ -24,24 +24,24 @@ public abstract class AbsConsumerLoop {
public AbsConsumerLoop() 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", "client1");
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 with " + config.getProperty("bootstrap.servers") + " ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw new SQLException("Failed to create consumer", ex);
}
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", "client1");
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 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");
@ -53,65 +53,65 @@ try {
public void pollDataCodePiece() throws SQLException {
// ANCHOR: poll_data_code_piece
try {
consumer.subscribe(topics);
while (!shutdown.get()) {
ConsumerRecords<ResultBean> records = consumer.poll(Duration.ofMillis(100));
for (ConsumerRecord<ResultBean> record : records) {
ResultBean bean = record.value();
// process your data here
process(bean);
try {
consumer.subscribe(topics);
while (!shutdown.get()) {
ConsumerRecords<ResultBean> records = consumer.poll(Duration.ofMillis(100));
for (ConsumerRecord<ResultBean> record : records) {
ResultBean bean = record.value();
// process your data here
process(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);
} finally {
consumer.close();
shutdownLatch.countDown();
}
}
} 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);
} finally {
consumer.close();
shutdownLatch.countDown();
}
// ANCHOR_END: poll_data_code_piece
}
public void commitCodePiece() throws SQLException {
// ANCHOR: commit_code_piece
try {
consumer.subscribe(topics);
while (!shutdown.get()) {
ConsumerRecords<ResultBean> records = consumer.poll(Duration.ofMillis(100));
for (ConsumerRecord<ResultBean> record : records) {
ResultBean bean = record.value();
// process your data here
process(bean);
try {
consumer.subscribe(topics);
while (!shutdown.get()) {
ConsumerRecords<ResultBean> records = consumer.poll(Duration.ofMillis(100));
for (ConsumerRecord<ResultBean> record : records) {
ResultBean bean = record.value();
// process your data here
process(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);
} finally {
consumer.close();
shutdownLatch.countDown();
}
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);
} finally {
consumer.close();
shutdownLatch.countDown();
}
// ANCHOR_END: commit_code_piece
}
public void unsubscribeCodePiece() throws SQLException {
// 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();
}
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
}
@ -119,14 +119,14 @@ try {
try {
// ANCHOR: poll_data
consumer.subscribe(topics);
while (!shutdown.get()) {
ConsumerRecords<ResultBean> records = consumer.poll(Duration.ofMillis(100));
for (ConsumerRecord<ResultBean> record : records) {
ResultBean bean = record.value();
process(bean);
}
}
consumer.subscribe(topics);
while (!shutdown.get()) {
ConsumerRecords<ResultBean> records = consumer.poll(Duration.ofMillis(100));
for (ConsumerRecord<ResultBean> record : records) {
ResultBean bean = record.value();
process(bean);
}
}
// ANCHOR_END: poll_data
consumer.unsubscribe();

View File

@ -15,37 +15,41 @@ import java.util.concurrent.TimeUnit;
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);
}
static private volatile boolean stopFlag = false;
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 ex) {
System.out.println("Failed to create jni consumer, host : " + config.getProperty("bootstrap.servers")
+ "; ErrMessage: " + ex.getMessage());
throw new SQLException("Failed to create consumer", ex);
}
// ANCHOR_END: create_consumer
}
public static void pollDataExample() throws SQLException {
try (TaosConsumer<ResultBean> consumer = getConsumer()){
public static void pollDataExample(TaosConsumer<ResultBean> consumer) throws SQLException {
try{
// subscribe to the topics
List<String> topics = Collections.singletonList("topic_meters");
@ -67,113 +71,117 @@ try {
// 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);
} catch (Exception ex) {
System.out.println("Failed to poll data from topic_meters; ErrMessage: " + ex.getMessage());
throw new SQLException("Failed to poll data from topic_meters", ex);
}
}
public static void pollExample() throws SQLException {
public static void pollExample(TaosConsumer<ResultBean> consumer) throws SQLException {
// ANCHOR: poll_data_code_piece
try (TaosConsumer<ResultBean> consumer = getConsumer()){
List<String> topics = Collections.singletonList("topic_meters");
try {
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));
// 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);
} catch (Exception ex) {
System.out.println("Failed to poll data; ErrMessage: " + ex.getMessage());
throw new SQLException("Failed to poll data", ex);
}
}
} 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 {
public static void seekExample(TaosConsumer<ResultBean> consumer) throws SQLException {
// ANCHOR: consumer_seek
try (TaosConsumer<ResultBean> consumer = getConsumer()){
List<String> topics = Collections.singletonList("topic_meters");
try {
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));
}
// subscribe to the topics
consumer.subscribe(topics);
System.out.println("subscribe topics successfully");
Set<TopicPartition> assignment = consumer.assignment();
System.out.println("now assignment: " + JSON.toJSONString(assignment));
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;
}
ConsumerRecords<ResultBean> records = ConsumerRecords.emptyRecord();
// make sure we have got some data
while (records.isEmpty()) {
records = consumer.poll(Duration.ofMillis(100));
}
// 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);
}
consumer.seekToBeginning(assignment);
System.out.println("assignment seek to beginning successfully");
System.out.println("beginning assignment: " + JSON.toJSONString(assignment));
} 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);
} catch (Exception ex) {
System.out.println("seek example failed; ErrMessage: " + ex.getMessage());
throw new SQLException("seek example failed", ex);
}
// ANCHOR_END: consumer_seek
}
public static void commitExample() throws SQLException {
public static void commitExample(TaosConsumer<ResultBean> consumer) throws SQLException {
// ANCHOR: commit_code_piece
try (TaosConsumer<ResultBean> consumer = getConsumer()){
List<String> topics = Collections.singletonList("topic_meters");
try {
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));
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);
} catch (Exception ex) {
System.out.println("Failed to execute consumer functions. ErrMessage: " + ex.getMessage());
throw new SQLException("Failed to execute consumer functions", ex);
}
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();
public static void unsubscribeExample(TaosConsumer<ResultBean> consumer) throws SQLException {
List<String> topics = Collections.singletonList("topic_meters");
consumer.subscribe(topics);
// ANCHOR: unsubscribe_data_code_piece
try {
consumer.unsubscribe();
} catch (SQLException ex){
} 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 {
} catch (Exception ex) {
System.out.println("Failed to unsubscribe consumer. ErrMessage: " + ex.getMessage());
throw new SQLException("Failed to unsubscribe consumer", ex);
}
finally {
consumer.close();
}
// ANCHOR_END: unsubscribe_data_code_piece
@ -182,6 +190,7 @@ try (TaosConsumer<ResultBean> consumer = getConsumer()){
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;
@ -240,23 +249,23 @@ try (TaosConsumer<ResultBean> consumer = getConsumer()){
}
}
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) ");
}
public static void prepareData() throws SQLException, InterruptedException {
try {
int affectedRows = statement.executeUpdate(insertQuery.toString());
assert affectedRows == 10000;
int i = 0;
while (!stopFlag) {
i++;
String insertQuery = "INSERT INTO power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') VALUES (NOW + " + i + "a, 10.30000, 219, 0.31000) ";
int affectedRows = statement.executeUpdate(insertQuery);
assert affectedRows == 1;
Thread.sleep(1);
}
} 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{
public static void prepareMeta() throws SQLException {
try {
statement.executeUpdate("CREATE DATABASE IF NOT EXISTS power");
statement.executeUpdate("USE power");
@ -288,6 +297,7 @@ try (TaosConsumer<ResultBean> consumer = getConsumer()){
}
System.out.println("Connection created successfully.");
}
public static void closeConnection() throws SQLException {
try {
if (statement != null) {
@ -310,7 +320,7 @@ try (TaosConsumer<ResultBean> consumer = getConsumer()){
}
public static void main(String[] args) throws SQLException {
public static void main(String[] args) throws SQLException, InterruptedException {
initConnection();
prepareMeta();
@ -321,11 +331,14 @@ try (TaosConsumer<ResultBean> consumer = getConsumer()){
executor.submit(() -> {
try {
// please use one example at a time
pollDataExample();
// seekExample();
// pollExample();
// commitExample();
unsubscribeExample();
TaosConsumer<ResultBean> consumer = getConsumer();
pollDataExample(consumer);
seekExample(consumer);
pollExample(consumer);
commitExample(consumer);
unsubscribeExample(consumer);
stopFlag = true;
} catch (SQLException ex) {
System.out.println("Failed to poll data from topic_meters, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
}
@ -337,16 +350,16 @@ try (TaosConsumer<ResultBean> consumer = getConsumer()){
System.out.println("Data prepared successfully");
// 关闭线程池不再接收新任务
// close the executor, which will make the executor reject new tasks
executor.shutdown();
try {
// 等待直到所有任务完成
// wait for the executor to terminate
boolean result = executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
assert result;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (Exception e){
} catch (Exception e) {
e.printStackTrace();
System.out.println("Wait executor termination failed.");
}

View File

@ -20,9 +20,9 @@ public class ConsumerLoopImp {
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
// ANCHOR: create_topic
Connection connection = DriverManager.getConnection(url, properties);
Statement statement = connection.createStatement();
statement.executeUpdate("CREATE TOPIC IF NOT EXISTS topic_meters AS SELECT ts, current, voltage, phase, groupid, location FROM meters");
Connection connection = DriverManager.getConnection(url, properties);
Statement statement = connection.createStatement();
statement.executeUpdate("CREATE TOPIC IF NOT EXISTS topic_meters AS SELECT ts, current, voltage, phase, groupid, location FROM meters");
// ANCHOR_END: create_topic
statement.close();

View File

@ -35,29 +35,29 @@ public class ConsumerOffsetSeek {
config.setProperty("value.deserializer.encoding", "UTF-8");
// ANCHOR: consumer_seek
String topic = "topic_meters";
Map<TopicPartition, Long> offset = null;
try (TaosConsumer<AbsConsumerLoop.ResultBean> consumer = new TaosConsumer<>(config)) {
consumer.subscribe(Collections.singletonList(topic));
for (int i = 0; i < 10; i++) {
if (i == 3) {
// Saving consumption position
offset = consumer.position(topic);
}
if (i == 5) {
// reset consumption to the previously saved position
for (Map.Entry<TopicPartition, Long> entry : offset.entrySet()) {
consumer.seek(entry.getKey(), entry.getValue());
String topic = "topic_meters";
Map<TopicPartition, Long> offset = null;
try (TaosConsumer<AbsConsumerLoop.ResultBean> consumer = new TaosConsumer<>(config)) {
consumer.subscribe(Collections.singletonList(topic));
for (int i = 0; i < 10; i++) {
if (i == 3) {
// Saving consumption position
offset = consumer.position(topic);
}
if (i == 5) {
// reset consumption to the previously saved position
for (Map.Entry<TopicPartition, Long> entry : offset.entrySet()) {
consumer.seek(entry.getKey(), entry.getValue());
}
}
ConsumerRecords<AbsConsumerLoop.ResultBean> records = consumer.poll(Duration.ofMillis(500));
// you can handle data here
}
} catch (SQLException ex) {
// handle any errors, please refer to the JDBC specifications for detailed exceptions info
System.out.println("Failed to execute consumer functions. server: " + config.getProperty("bootstrap.servers") + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw new SQLException("Failed to execute consumer functions", ex);
}
ConsumerRecords<AbsConsumerLoop.ResultBean> records = consumer.poll(Duration.ofMillis(500));
// you can handle data here
}
} catch (SQLException ex) {
// handle any errors, please refer to the JDBC specifications for detailed exceptions info
System.out.println("Failed to execute consumer functions. server: " + config.getProperty("bootstrap.servers") + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw new SQLException("Failed to execute consumer functions", ex);
}
// ANCHOR_END: consumer_seek
}
}

View File

@ -16,97 +16,97 @@ public class JdbcBasicDemo {
public static void main(String[] args) throws SQLException {
final String url = "jdbc:TAOS://" + host + ":6030/?user=" + user + "&password=" + password;
final String url = "jdbc:TAOS://" + host + ":6030/?user=" + user + "&password=" + password;
// get connection
Properties properties = new Properties();
properties.setProperty("charset", "UTF-8");
properties.setProperty("locale", "en_US.UTF-8");
properties.setProperty("timezone", "UTC-8");
System.out.println("get connection starting...");
try(Connection connection = DriverManager.getConnection(url, properties)){
Properties properties = new Properties();
properties.setProperty("charset", "UTF-8");
properties.setProperty("locale", "en_US.UTF-8");
properties.setProperty("timezone", "UTC-8");
System.out.println("get connection starting...");
try (Connection connection = DriverManager.getConnection(url, properties)) {
if (connection != null){
System.out.println("[ OK ] Connection established.");
} else {
System.out.println("[ ERR ] Connection can not be established.");
return;
}
if (connection != null) {
System.out.println("[ OK ] Connection established.");
} else {
System.out.println("[ ERR ] Connection can not be established.");
return;
}
Statement stmt = connection.createStatement();
Statement stmt = connection.createStatement();
// ANCHOR: create_db_and_table
// create database
stmt.executeUpdate("CREATE DATABASE IF NOT EXISTS power");
stmt.executeUpdate("CREATE DATABASE IF NOT EXISTS power");
// use database
stmt.executeUpdate("USE power");
stmt.executeUpdate("USE power");
// create table
stmt.executeUpdate("CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))");
stmt.executeUpdate("CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))");
// ANCHOR_END: create_db_and_table
// ANCHOR: insert_data
// insert data
String 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) ";
int affectedRows = stmt.executeUpdate(insertQuery);
System.out.println("insert " + affectedRows + " rows.");
String 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) ";
int affectedRows = stmt.executeUpdate(insertQuery);
System.out.println("insert " + affectedRows + " rows.");
// ANCHOR_END: insert_data
// ANCHOR: query_data
// query data
ResultSet resultSet = stmt.executeQuery("SELECT * FROM meters");
ResultSet resultSet = stmt.executeQuery("SELECT * FROM meters");
Timestamp ts;
float current;
String location;
while(resultSet.next()){
ts = resultSet.getTimestamp(1);
current = resultSet.getFloat(2);
location = resultSet.getString("location");
Timestamp ts;
float current;
String location;
while (resultSet.next()) {
ts = resultSet.getTimestamp(1);
current = resultSet.getFloat(2);
location = resultSet.getString("location");
System.out.printf("%s, %f, %s\n", ts, current, location);
}
System.out.printf("%s, %f, %s\n", ts, current, location);
}
// ANCHOR_END: query_data
// ANCHOR: with_reqid
AbstractStatement aStmt = (AbstractStatement) connection.createStatement();
aStmt.execute("CREATE DATABASE IF NOT EXISTS power", 1L);
aStmt.executeUpdate("USE power", 2L);
try (ResultSet rs = aStmt.executeQuery("SELECT * FROM meters limit 1", 3L)) {
while(rs.next()){
Timestamp timestamp = rs.getTimestamp(1);
System.out.println("timestamp = " + timestamp);
}
}
aStmt.close();
AbstractStatement aStmt = (AbstractStatement) connection.createStatement();
aStmt.execute("CREATE DATABASE IF NOT EXISTS power", 1L);
aStmt.executeUpdate("USE power", 2L);
try (ResultSet rs = aStmt.executeQuery("SELECT * FROM meters limit 1", 3L)) {
while (rs.next()) {
Timestamp timestamp = rs.getTimestamp(1);
System.out.println("timestamp = " + timestamp);
}
}
aStmt.close();
// ANCHOR_END: with_reqid
String sql = "SELECT * FROM meters limit 2;";
String sql = "SELECT * FROM meters limit 2;";
// ANCHOR: jdbc_exception
try (Statement statement = connection.createStatement();
// executeQuery
ResultSet tempResultSet = statement.executeQuery(sql)) {
try (Statement statement = connection.createStatement();
// executeQuery
ResultSet tempResultSet = statement.executeQuery(sql)) {
// print result
printResult(tempResultSet);
} catch (SQLException e) {
System.out.println("ERROR Message: " + e.getMessage());
System.out.println("ERROR Code: " + e.getErrorCode());
e.printStackTrace();
}
// print result
printResult(tempResultSet);
} catch (SQLException e) {
System.out.println("ERROR Message: " + e.getMessage());
System.out.println("ERROR Code: " + e.getErrorCode());
e.printStackTrace();
}
// ANCHOR_END: jdbc_exception
} catch (SQLException ex) {
// handle any errors, please refer to the JDBC specifications for detailed exceptions info

View File

@ -15,37 +15,41 @@ public class JdbcCreatDBDemo {
public static void main(String[] args) throws SQLException {
final String jdbcUrl = "jdbc:TAOS://" + host + ":6030/?user=" + user + "&password=" + password;
final String jdbcUrl = "jdbc:TAOS://" + host + ":6030/?user=" + user + "&password=" + password;
// get connection
Properties properties = new Properties();
properties.setProperty("charset", "UTF-8");
properties.setProperty("locale", "en_US.UTF-8");
properties.setProperty("timezone", "UTC-8");
System.out.println("get connection starting...");
Properties properties = new Properties();
properties.setProperty("charset", "UTF-8");
properties.setProperty("locale", "en_US.UTF-8");
properties.setProperty("timezone", "UTC-8");
System.out.println("get connection starting...");
// ANCHOR: create_db_and_table
try (Connection connection = DriverManager.getConnection(jdbcUrl, properties);
Statement stmt = connection.createStatement()) {
try (Connection connection = DriverManager.getConnection(jdbcUrl, properties);
Statement stmt = connection.createStatement()) {
// create database
int rowsAffected = stmt.executeUpdate("CREATE DATABASE IF NOT EXISTS power");
// you can check rowsAffected here
assert rowsAffected == 0;
// create database
int rowsAffected = stmt.executeUpdate("CREATE DATABASE IF NOT EXISTS power");
// you can check rowsAffected here
assert rowsAffected == 0;
// use database
rowsAffected = stmt.executeUpdate("USE power");
// you can check rowsAffected here
assert rowsAffected == 0;
// use database
rowsAffected = stmt.executeUpdate("USE power");
// you can check rowsAffected here
assert rowsAffected == 0;
// create table
rowsAffected = stmt.executeUpdate("CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))");
// you can check rowsAffected here
assert rowsAffected == 0;
// create table
rowsAffected = stmt.executeUpdate("CREATE STABLE IF NOT EXISTS meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS (groupId INT, location BINARY(24))");
// you can check rowsAffected here
assert rowsAffected == 0;
} catch (SQLException ex) {
// handle any errors, please refer to the JDBC specifications for detailed exceptions info
System.out.println("Failed to create db and table, url:" + jdbcUrl + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
}
} catch (SQLException ex) {
// handle any errors, please refer to the JDBC specifications for detailed exceptions info
System.out.println("Failed to create db and table, url:" + jdbcUrl + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw ex;
} catch (Exception ex){
System.out.println("Failed to create db and table, url:" + jdbcUrl + "; ErrMessage: " + ex.getMessage());
throw ex;
}
// ANCHOR_END: create_db_and_table
}

View File

@ -15,36 +15,39 @@ public class JdbcInsertDataDemo {
public static void main(String[] args) throws SQLException {
final String jdbcUrl = "jdbc:TAOS://" + host + ":6030/?user=" + user + "&password=" + password;
final String jdbcUrl = "jdbc:TAOS://" + host + ":6030/?user=" + user + "&password=" + password;
// get connection
Properties properties = new Properties();
properties.setProperty("charset", "UTF-8");
properties.setProperty("locale", "en_US.UTF-8");
properties.setProperty("timezone", "UTC-8");
System.out.println("get connection starting...");
Properties properties = new Properties();
properties.setProperty("charset", "UTF-8");
properties.setProperty("locale", "en_US.UTF-8");
properties.setProperty("timezone", "UTC-8");
System.out.println("get connection starting...");
// ANCHOR: insert_data
try (Connection connection = DriverManager.getConnection(jdbcUrl, properties);
Statement stmt = connection.createStatement()) {
try (Connection connection = DriverManager.getConnection(jdbcUrl, properties);
Statement stmt = connection.createStatement()) {
// insert data, please make sure the database and table are created before
String 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) ";
int affectedRows = stmt.executeUpdate(insertQuery);
// you can check affectedRows here
System.out.println("inserted into " + affectedRows + " rows to power.meters successfully.");
} catch (SQLException ex) {
// handle any errors, please refer to the JDBC specifications for detailed exceptions info
System.out.println("Failed to insert data to power.meters, url:" + jdbcUrl + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
}
// insert data, please make sure the database and table are created before
String 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) ";
int affectedRows = stmt.executeUpdate(insertQuery);
// you can check affectedRows here
System.out.println("inserted into " + affectedRows + " rows to power.meters successfully.");
} catch (SQLException ex) {
// handle any errors, please refer to the JDBC specifications for detailed exceptions info
System.out.println("Failed to insert data to power.meters, url:" + jdbcUrl + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw ex;
} catch (Exception ex){
System.out.println("Failed to insert data to power.meters, url:" + jdbcUrl + "; ErrMessage: " + ex.getMessage());
throw ex;
}
// ANCHOR_END: insert_data
}
}

View File

@ -15,36 +15,40 @@ public class JdbcQueryDemo {
public static void main(String[] args) throws SQLException {
final String jdbcUrl = "jdbc:TAOS://" + host + ":6030/?user=" + user + "&password=" + password;
final String jdbcUrl = "jdbc:TAOS://" + host + ":6030/?user=" + user + "&password=" + password;
// get connection
Properties properties = new Properties();
properties.setProperty("charset", "UTF-8");
properties.setProperty("locale", "en_US.UTF-8");
properties.setProperty("timezone", "UTC-8");
System.out.println("get connection starting...");
Properties properties = new Properties();
properties.setProperty("charset", "UTF-8");
properties.setProperty("locale", "en_US.UTF-8");
properties.setProperty("timezone", "UTC-8");
System.out.println("get connection starting...");
// ANCHOR: query_data
try (Connection connection = DriverManager.getConnection(jdbcUrl, properties);
Statement stmt = connection.createStatement();
// query data, make sure the database and table are created before
ResultSet resultSet = stmt.executeQuery("SELECT ts, current, location FROM power.meters limit 100")) {
try (Connection connection = DriverManager.getConnection(jdbcUrl, properties);
Statement stmt = connection.createStatement();
// query data, make sure the database and table are created before
ResultSet resultSet = stmt.executeQuery("SELECT ts, current, location FROM power.meters limit 100")) {
Timestamp ts;
float current;
String location;
while (resultSet.next()) {
ts = resultSet.getTimestamp(1);
current = resultSet.getFloat(2);
// we recommend using the column name to get the value
location = resultSet.getString("location");
Timestamp ts;
float current;
String location;
while (resultSet.next()) {
ts = resultSet.getTimestamp(1);
current = resultSet.getFloat(2);
// we recommend using the column name to get the value
location = resultSet.getString("location");
// you can check data here
System.out.printf("ts: %s, current: %f, location: %s %n", ts, current, location);
}
} catch (SQLException ex) {
// handle any errors, please refer to the JDBC specifications for detailed exceptions info
System.out.println("Failed to query data from power.meters, url:" + jdbcUrl + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
}
// you can check data here
System.out.printf("ts: %s, current: %f, location: %s %n", ts, current, location);
}
} catch (SQLException ex) {
// handle any errors, please refer to the JDBC specifications for detailed exceptions info
System.out.println("Failed to query data from power.meters, url:" + jdbcUrl + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw ex;
} catch (Exception ex){
System.out.println("Failed to query data from power.meters, url:" + jdbcUrl + "; ErrMessage: " + ex.getMessage());
throw ex;
}
// ANCHOR_END: query_data
}

View File

@ -15,31 +15,34 @@ public class JdbcReqIdDemo {
public static void main(String[] args) throws SQLException {
final String jdbcUrl = "jdbc:TAOS://" + host + ":6030/?user=" + user + "&password=" + password;
final String jdbcUrl = "jdbc:TAOS://" + host + ":6030/?user=" + user + "&password=" + password;
// get connection
Properties properties = new Properties();
properties.setProperty("charset", "UTF-8");
properties.setProperty("locale", "en_US.UTF-8");
properties.setProperty("timezone", "UTC-8");
System.out.println("get connection starting...");
Properties properties = new Properties();
properties.setProperty("charset", "UTF-8");
properties.setProperty("locale", "en_US.UTF-8");
properties.setProperty("timezone", "UTC-8");
System.out.println("get connection starting...");
// ANCHOR: with_reqid
try (Connection connection = DriverManager.getConnection(jdbcUrl, properties);
// Create a statement that allows specifying a request ID
AbstractStatement aStmt = (AbstractStatement) connection.createStatement()) {
try (Connection connection = DriverManager.getConnection(jdbcUrl, properties);
// Create a statement that allows specifying a request ID
AbstractStatement aStmt = (AbstractStatement) connection.createStatement()) {
try (ResultSet rs = aStmt.executeQuery("SELECT ts, current, location FROM power.meters limit 1", 3L)) {
while (rs.next()) {
Timestamp timestamp = rs.getTimestamp(1);
System.out.println("timestamp = " + timestamp);
try (ResultSet rs = aStmt.executeQuery("SELECT ts, current, location FROM power.meters limit 1", 3L)) {
while (rs.next()) {
Timestamp timestamp = rs.getTimestamp(1);
System.out.println("timestamp = " + timestamp);
}
}
} catch (SQLException ex) {
// handle any errors, please refer to the JDBC specifications for detailed exceptions info
System.out.println("Failed to execute sql with reqId, url:" + jdbcUrl + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw ex;
} catch (Exception ex){
System.out.println("Failed to execute sql with reqId, url:" + jdbcUrl + "; ErrMessage: " + ex.getMessage());
throw ex;
}
}
} catch (SQLException ex) {
// handle any errors, please refer to the JDBC specifications for detailed exceptions info
System.out.println("Failed to execute sql with reqId, url:" + jdbcUrl + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
}
// ANCHOR_END: with_reqid
}

View File

@ -69,6 +69,10 @@ public class ParameterBindingBasicDemo {
} 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());
throw ex;
} catch (Exception ex){
System.out.println("Failed to insert to table meters using stmt, url: " + jdbcUrl + "; ErrMessage: " + ex.getMessage());
throw ex;
}
}

View File

@ -31,20 +31,27 @@ public class ParameterBindingFullDemo {
public static void main(String[] args) throws SQLException {
String jdbcUrl = "jdbc:TAOS://" + host + ":6030/";
Connection conn = DriverManager.getConnection(jdbcUrl, "root", "taosdata");
try (Connection conn = DriverManager.getConnection(jdbcUrl, "root", "taosdata")) {
init(conn);
init(conn);
bindInteger(conn);
bindFloat(conn);
bindBoolean(conn);
bindBytes(conn);
bindString(conn);
bindVarbinary(conn);
bindGeometry(conn);
bindInteger(conn);
bindFloat(conn);
bindBoolean(conn);
bindBytes(conn);
bindString(conn);
bindVarbinary(conn);
bindGeometry(conn);
clean(conn);
conn.close();
clean(conn);
} 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());
throw ex;
} catch (Exception ex){
System.out.println("Failed to insert to table meters using stmt, url: " + jdbcUrl + "; ErrMessage: " + ex.getMessage());
throw ex;
}
}
private static void init(Connection conn) throws SQLException {

View File

@ -28,6 +28,10 @@ public class SchemalessJniTest {
} catch (SQLException ex) {
// handle any errors, please refer to the JDBC specifications for detailed exceptions info
System.out.println("Failed to insert data with schemaless, host:" + host + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw ex;
} catch (Exception ex){
System.out.println("Failed to insert data with schemaless, host:" + host + "; ErrMessage: " + ex.getMessage());
throw ex;
}
}

View File

@ -28,6 +28,10 @@ public class SchemalessWsTest {
} catch (SQLException ex) {
// handle any errors, please refer to the JDBC specifications for detailed exceptions info
System.out.println("Failed to insert data with schemaless, host:" + host + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw ex;
} catch (Exception ex){
System.out.println("Failed to insert data with schemaless, host:" + host + "; ErrMessage: " + ex.getMessage());
throw ex;
}
}

View File

@ -50,6 +50,10 @@ public class WSParameterBindingBasicDemo {
} 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());
throw ex;
} catch (Exception ex){
System.out.println("Failed to insert to table meters using stmt, url: " + jdbcUrl + "; ErrMessage: " + ex.getMessage());
throw ex;
}
}

View File

@ -39,8 +39,11 @@ public class WSParameterBindingFullDemo {
} catch (SQLException ex) {
// handle any errors, please refer to the JDBC specifications for detailed exceptions info
System.out.println("Error Code: " + ex.getErrorCode());
System.out.println("Message: " + ex.getMessage());
System.out.println("Failed to insert to table meters using stmt, url: " + jdbcUrl + "; ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
throw ex;
} catch (Exception ex){
System.out.println("Failed to insert to table meters using stmt, url: " + jdbcUrl + "; ErrMessage: " + ex.getMessage());
throw ex;
}
}

View File

@ -6,10 +6,7 @@ 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.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
@ -18,37 +15,39 @@ import java.util.concurrent.TimeUnit;
public class WsConsumerLoopFull {
static private Connection connection;
static private Statement statement;
public static TaosConsumer<ResultBean> getConsumer() throws SQLException{
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");
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", "1");
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);
}
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 ex) {
System.out.println("Failed to create websocket consumer, host : " + config.getProperty("bootstrap.servers")
+ "; ErrMessage: " + ex.getMessage());
throw new SQLException("Failed to create consumer", ex);
}
// ANCHOR_END: create_consumer
}
}
public static void pollDataExample() throws SQLException {
try (TaosConsumer<ResultBean> consumer = getConsumer()){
public static void pollDataExample(TaosConsumer<ResultBean> consumer) throws SQLException {
try{
// subscribe to the topics
List<String> topics = Collections.singletonList("topic_meters");
@ -70,194 +69,199 @@ try {
// 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);
} catch (Exception ex) {
System.out.println("Failed to poll data from topic_meters; ErrMessage: " + ex.getMessage());
throw new SQLException("Failed to poll data from topic_meters", ex);
}
}
public static void pollExample() throws SQLException {
public static void pollExample(TaosConsumer<ResultBean> consumer) throws SQLException {
// ANCHOR: poll_data_code_piece
try (TaosConsumer<ResultBean> consumer = getConsumer()){
List<String> topics = Collections.singletonList("topic_meters");
try {
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));
// 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);
} catch (Exception ex) {
System.out.println("Failed to poll data; ErrMessage: " + ex.getMessage());
throw new SQLException("Failed to poll data", ex);
}
}
} 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 {
public static void seekExample(TaosConsumer<ResultBean> consumer) throws SQLException {
// ANCHOR: consumer_seek
try (TaosConsumer<ResultBean> consumer = getConsumer()){
List<String> topics = Collections.singletonList("topic_meters");
try {
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));
}
// subscribe to the topics
consumer.subscribe(topics);
System.out.println("subscribe topics successfully");
Set<TopicPartition> assignment = consumer.assignment();
System.out.println("now assignment: " + JSON.toJSONString(assignment));
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;
}
ConsumerRecords<ResultBean> records = ConsumerRecords.emptyRecord();
// make sure we have got some data
while (records.isEmpty()) {
records = consumer.poll(Duration.ofMillis(100));
}
// 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);
}
consumer.seekToBeginning(assignment);
System.out.println("assignment seek to beginning successfully");
System.out.println("beginning assignment: " + JSON.toJSONString(assignment));
} 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);
} catch (Exception ex) {
System.out.println("seek example failed; ErrMessage: " + ex.getMessage());
throw new SQLException("seek example failed", ex);
}
// ANCHOR_END: consumer_seek
}
public static void commitExample() throws SQLException {
public static void commitExample(TaosConsumer<ResultBean> consumer) throws SQLException {
// ANCHOR: commit_code_piece
try (TaosConsumer<ResultBean> consumer = getConsumer()){
List<String> topics = Collections.singletonList("topic_meters");
try {
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));
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);
} catch (Exception ex) {
System.out.println("Failed to execute consumer functions. ErrMessage: " + ex.getMessage());
throw new SQLException("Failed to execute consumer functions", ex);
}
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();
public static void unsubscribeExample(TaosConsumer<ResultBean> consumer) throws SQLException {
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();
}
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);
} catch (Exception ex) {
System.out.println("Failed to unsubscribe consumer. 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> {
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;
}
// 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 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) ");
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, InterruptedException {
try {
int affectedRows = statement.executeUpdate(insertQuery.toString());
assert affectedRows == 10000;
for (int i = 0; i < 3000; i++) {
String insertQuery = "INSERT INTO power.d1001 USING power.meters TAGS(2,'California.SanFrancisco') VALUES (NOW + " + i + "a, 10.30000, 219, 0.31000) ";
int affectedRows = statement.executeUpdate(insertQuery);
assert affectedRows == 1;
Thread.sleep(1);
}
} 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{
public static void prepareMeta() throws SQLException {
try {
statement.executeUpdate("CREATE DATABASE IF NOT EXISTS power");
statement.executeUpdate("USE power");
@ -289,6 +293,7 @@ public static class ResultBean {
}
System.out.println("Connection created successfully.");
}
public static void closeConnection() throws SQLException {
try {
if (statement != null) {
@ -311,7 +316,7 @@ public static class ResultBean {
}
public static void main(String[] args) throws SQLException {
public static void main(String[] args) throws SQLException, InterruptedException {
initConnection();
prepareMeta();
@ -322,13 +327,22 @@ public static class ResultBean {
executor.submit(() -> {
try {
// please use one example at a time
pollDataExample();
// seekExample();
// pollExample();
// commitExample();
unsubscribeExample();
TaosConsumer<ResultBean> consumer = getConsumer();
pollDataExample(consumer);
seekExample(consumer);
consumer.unsubscribe();
pollExample(consumer);
consumer.unsubscribe();
commitExample(consumer);
consumer.unsubscribe();
unsubscribeExample(consumer);
} catch (SQLException ex) {
System.out.println("Failed to poll data from topic_meters, ErrCode:" + ex.getErrorCode() + "; ErrMessage: " + ex.getMessage());
return;
} catch (Exception ex) {
System.out.println("Failed to poll data from topic_meters, ErrMessage: " + ex.getMessage());
return;
}
System.out.println("pollDataExample executed successfully");
});
@ -338,16 +352,16 @@ public static class ResultBean {
System.out.println("Data prepared successfully");
// 关闭线程池不再接收新任务
// close the executor, which will make the executor reject new tasks
executor.shutdown();
try {
// 等待直到所有任务完成
// wait for the executor to terminate
boolean result = executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
assert result;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (Exception e){
} catch (Exception e) {
e.printStackTrace();
System.out.println("Wait executor termination failed.");
}

View File

@ -7,32 +7,59 @@ pgrep taosadapter || taosadapter >> /dev/null 2>&1 &
cd ../../docs/examples/csharp
dotnet run --project connect/connect.csproj
taos -s "drop database if exists power"
dotnet run --project sqlInsert/sqlinsert.csproj
dotnet run --project query/query.csproj
#dotnet run --project subscribe/subscribe.csproj
#taos -s "drop topic if exists topic_example"
taos -s "drop database if exists power"
dotnet run --project stmtInsert/stmtinsert.csproj
dotnet run --project wsConnect/wsConnect.csproj
taos -s "drop database if exists test"
sleep 1
dotnet run --project influxdbLine/influxdbline.csproj
taos -s "drop database if exists test"
sleep 1
dotnet run --project optsTelnet/optstelnet.csproj
taos -s "drop database if exists test"
sleep 1
dotnet run --project optsJSON/optsJSON.csproj
taos -s "create database if not exists test"
# query
taos -s "drop database if exists power"
dotnet run --project wsConnect/wsConnect.csproj
sleep 1
dotnet run --project wsInsert/wsInsert.csproj
dotnet run --project wsQuery/wsQuery.csproj
taos -s "drop database if exists power"
sleep 1
dotnet run --project sqlInsert/sqlinsert.csproj
dotnet run --project query/query.csproj
# stmt
taos -s "drop database if exists power"
sleep 1
dotnet run --project wsStmt/wsStmt.csproj
taos -s "drop database if exists test"
taos -s "drop database if exists power"
sleep 1
dotnet run --project stmtInsert/stmtinsert.csproj
# schemaless
taos -s "drop database if exists power"
sleep 1
dotnet run --project wssml/wssml.csproj
taos -s "drop database if exists power"
sleep 1
dotnet run --project nativesml/nativesml.csproj
# subscribe
taos -s "drop topic if exists topic_meters"
sleep 1
taos -s "drop database if exists power"
sleep 1
dotnet run --project wssubscribe/wssubscribe.csproj
taos -s "drop topic if exists topic_meters"
sleep 1
taos -s "drop database if exists power"
sleep 1
dotnet run --project subscribe/subscribe.csproj

View File

@ -4,7 +4,7 @@ set -e
taosd >>/dev/null 2>&1 &
taosadapter >>/dev/null 2>&1 &
sleep 10
sleep 1
cd ../../docs/examples/go
go mod tidy
@ -12,20 +12,67 @@ go mod tidy
go run ./connect/afconn/main.go
go run ./connect/cgoexample/main.go
go run ./connect/restexample/main.go
go run ./connect/connpool/main.go
go run ./connect/wsexample/main.go
taos -s "drop database if exists power"
go run ./sqlquery/main.go
taos -s "drop database if exists power"
sleep 1
go run ./queryreqid/main.go
taos -s "drop database if exists power"
sleep 1
go run ./stmt/native/main.go
taos -s "drop database if exists power"
sleep 1
go run ./stmt/ws/main.go
taos -s "drop database if exists power"
sleep 1
go run ./schemaless/native/main.go
taos -s "drop database if exists power"
sleep 1
go run ./schemaless/ws/main.go
taos -s "drop topic if exists topic_meters"
sleep 1
taos -s "drop database if exists power"
sleep 1
go run ./tmq/native/main.go
taos -s "drop topic if exists topic_meters"
sleep 1
taos -s "drop database if exists power"
sleep 1
go run ./tmq/ws/main.go
taos -s "drop database if exists test"
sleep 1
go run ./insert/json/main.go
taos -s "drop database if exists test"
sleep 1
go run ./insert/line/main.go
taos -s "drop topic if exists topic_meters"
sleep 1
taos -s "drop database if exists power"
sleep 1
go run ./insert/sql/main.go
taos -s "drop database if exists power"
sleep 1
go run ./insert/stmt/main.go
taos -s "drop database if exists test"
sleep 1
go run ./insert/telnet/main.go
go run ./query/sync/main.go
taos -s "drop topic if exists example_tmq_topic"
sleep 1
taos -s "drop database if exists example_tmq"
sleep 1
go run ./sub/main.go