未验证 提交 d6c5a2e6 编写于 作者: X xiaolei li 提交者: GitHub

[TD-11431]<feature>: csharp publish nuget user manul and user sample update (#8853)

* [TD-11431]<feature>:c# connector publish and example fix

* update c# connector manual since connector publish to nuget

* fix doc,remove <feff>
上级 3137e8a2
...@@ -1037,43 +1037,62 @@ HTTP 请求 URL 采用 `sqlutc` 时,返回结果集的时间戳将采用 UTC ...@@ -1037,43 +1037,62 @@ HTTP 请求 URL 采用 `sqlutc` 时,返回结果集的时间戳将采用 UTC
## <a class="anchor" id="csharp"></a>CSharp Connector ## <a class="anchor" id="csharp"></a>CSharp Connector
C#连接器支持的系统有:Linux 64/Windows x64/Windows x86 * C#连接器支持的系统有:Linux 64/Windows x64/Windows x86
* C#连接器现在也支持从[Nuget下载引用](https://www.nuget.org/packages/TDengine.Connector/)
* 在Windows系统上,C#应用程序可以使用TDengine的原生C接口来执行所有数据库操作,后续版本将提供ORM(Dapper)框架驱动。
### 安装准备 ### 安装准备
* 应用驱动安装请参考[安装连接器驱动步骤](https://www.taosdata.com/cn/documentation/connector#driver) * 应用驱动安装请参考[安装连接器驱动步骤](https://www.taosdata.com/cn/documentation/connector#driver)
* 接口文件TDengineDrivercs.cs和参考程序示例TDengineTest.cs均位于Windows客户端install_directory/examples/C#目录下。 * 接口文件TDengineDrivercs.cs和参考程序示例TDengineTest.cs均位于Windows客户端install_directory/examples/C#目录下。
* 在Windows系统上,C#应用程序可以使用TDengine的原生C接口来执行所有数据库操作,后续版本将提供ORM(Dapper)框架驱动。 * 安装[.NET SDK](https://dotnet.microsoft.com/download)
### 示例程序 ### 示例程序
示例程序源码位于install_directory/examples/C#,有: 示例程序源码位于
* {client_install_directory}/examples/C#
* [github C# example source code](https://github.com/taosdata/TDengine/tree/develop/tests/examples/C%23)
TDengineTest.cs C#示例源程序 **注意:** TDengineTest.cs C#示例源程序,包含了数据库连接参数,以及如何执行数据插入、查询等操作。
### 安装验证 ### 安装验证
运行install_directory/examples/C#/C#Checker/C#Checker.exe 需要先安装 .Net SDK
```cmd ```cmd
cd {install_directory}/examples/C#/C#Checker cd {client_install_directory}/examples/C#/C#Checker
csc /optimize *.cs //运行测试
C#Checker.exe -h <fqdn> dotnet run -- -h <FQDN>. // 此步骤会先build,然后再运行。
``` ```
### C#连接器的使用 ### C#连接器的使用
在Windows系统上,C#应用程序可以使用TDengine的C#连接器接口来执行所有数据库的操作。使用的具体步骤如下所示: 在Windows系统上,C#应用程序可以使用TDengine的C#连接器接口来执行所有数据库的操作。使用的具体步骤如下所示:
1. 将接口文件TDengineDrivercs.cs加入到应用程序所在的项目空间中。 需要 .NET SDK
2. 用户可以参考TDengineTest.cs来定义数据库连接参数,以及如何执行数据插入、查询等操作。 * 创建一个c# project.
``` cmd
mkdir test
cd test
dotnet new console
```
* 通过Nuget引用TDengineDriver包
``` cmd
dotnet add package TDengine.Connector
```
* 在项目中需要用到TDengineConnector的地方引用TDengineDriver namespace。
```c#
using TDengineDriver;
```
* 用户可以参考[TDengineTest.cs](https://github.com/taosdata/TDengine/tree/develop/tests/examples/C%23/TDengineTest)来定义数据库连接参数,以及如何执行数据插入、查询等操作。
此接口需要用到taos.dll文件,所以在执行应用程序前,拷贝Windows客户端install_directory/driver目录中的taos.dll文件到项目最后生成.exe可执行文件所在的文件夹。之后运行exe文件,即可访问TDengine数据库并做插入、查询等操作。
**注意:** **注意:**
1. TDengine V2.0.3.0之后同时支持32位和64位Windows系统,所以C#项目在生成.exe文件时,“解决方案”/“项目”的“平台”请选择对应的“X86” 或“x64”。 * TDengine V2.0.3.0之后同时支持32位和64位Windows系统,所以C#项目在生成.exe文件时,“解决方案”/“项目”的“平台”请选择对应的“X86” 或“x64”。
2. 此接口目前已经在Visual Studio 2015/2017中验证过,其它VS版本尚待验证。 * 此接口目前已经在Visual Studio 2015/2017中验证过,其它VS版本尚待验证。
* 此连接器需要用到taos.dll文件,所以在未安装客户端时需要在执行应用程序前,拷贝Windows{client_install_directory}/driver目录中的taos.dll文件到项目最后生成.exe可执行文件所在的文件夹。之后运行exe文件,即可访问TDengine数据库并做插入、查询等操作。
### 第三方驱动 ### 第三方驱动
......
...@@ -841,37 +841,60 @@ Only some configuration parameters related to RESTful interface are listed below ...@@ -841,37 +841,60 @@ Only some configuration parameters related to RESTful interface are listed below
## <a class="anchor" id="csharp"></a> CSharp Connector ## <a class="anchor" id="csharp"></a> CSharp Connector
The C # connector supports: Linux 64/Windows x64/Windows x86.
* The C # connector supports: Linux 64/Windows x64/Windows x86.
* C# connector can be download and include as normal table form [Nuget.org](https://www.nuget.org/packages/TDengine.Connector/).
* On Windows, C # applications can use the native C interface of TDengine to perform all database operations, and future versions will provide the ORM (Dapper) framework driver.
### Installation preparation ### Installation preparation
- For application driver installation, please refer to the[ steps of installing connector driver](https://www.taosdata.com/en/documentation/connector#driver). * For application driver installation, please refer to the[ steps of installing connector driver](https://www.taosdata.com/en/documentation/connector#driver).
- . NET interface file TDengineDrivercs.cs and reference sample TDengineTest.cs are both located in the Windows client install_directory/examples/C# directory. * .NET interface file TDengineDrivercs.cs and reference sample TDengineTest.cs are both located in the Windows client install_directory/examples/C# directory.
- On Windows, C # applications can use the native C interface of TDengine to perform all database operations, and future versions will provide the ORM (Dapper) framework driver. * Install [.NET SDK](https://dotnet.microsoft.com/download)
### Installation verification ### Example Source Code
you can find sample code under follow directions:
* {client_install_directory}/examples/C#
* [github C# example source code](https://github.com/taosdata/TDengine/tree/develop/tests/examples/C%23)
Run install_directory/examples/C#/C#Checker/C#Checker.exe **Tips:** TDengineTest.cs One of C# connector's sample code that include basic examples like connection,sql executions and so on.
### Installation verification
Run {client_install_directory}/examples/C#/C#Checker/C#Checker.cs
Need install .Net SDK first
```cmd ```cmd
cd {install_directory}/examples/C#/C#Checker cd {client_install_directory}/examples/C#/C#Checker
csc /optimize *.cs //run c#checker.cs
C#Checker.exe -h <fqdn> dotnet run -- -h <FQDN> //dotnet run will build project first by default.
``` ```
### How to use C# connector ### How to use C# connector
On Windows system, .NET applications can use the .NET interface of TDengine to perform all database operations. The steps to use it are as follows: On Windows system, .NET applications can use the .NET interface of TDengine to perform all database operations. The steps to use it are as follows:
1. Add the. NET interface file TDengineDrivercs.cs to the .NET project where the application is located. need to install .NET SDK first
2. Users can refer to TDengineTest.cs to define database connection parameters and how to perform data insert, query and other operations; * create a c# project.
``` cmd
mkdir test
cd test
dotnet new console
```
* add TDengineDriver as an package through Nuget
This. NET interface requires the taos.dll file, so before executing the application, copy the taos.dll file in the Windows client install_directory/driver directory to the folder where the. NET project finally generated the .exe executable file. After running the exe file, you can access the TDengine database and do operations such as insert and query. ``` cmd
dotnet add package TDengine.Connector
```
* inlucde the TDnengineDriver in you application's namespace
```C#
using TDengineDriver;
```
* user can reference from[TDengineTest.cs](https://github.com/taosdata/TDengine/tree/develop/tests/examples/C%23/TDengineTest) and learn how to define database connection,query,insert and other basic data manipulations.
**Note:** **Note:**
1. TDengine V2.0. 3.0 supports both 32-bit and 64-bit Windows systems, so when. NET project generates a .exe file, please select the corresponding "X86" or "x64" for the "Platform" under "Solution"/"Project". * TDengine V2.0. 3.0 supports both 32-bit and 64-bit Windows systems, so when. NET project generates a .exe file, please select the corresponding "X86" or "x64" for the "Platform" under "Solution"/"Project".
2. This. NET interface has been verified in Visual Studio 2015/2017, and other VS versions have yet to be verified. * This. NET interface has been verified in Visual Studio 2015/2017, and other VS versions have yet to be verified.
* Since this. NET connector interface requires the taos.dll file, so before executing the application, copy the taos.dll file in the Windows {client_install_directory}/driver directory to the folder where the. NET project finally generated the .exe executable file. After running the exe file, you can access the TDengine database and do operations such as insert and query(This step can be skip if the client has been installed on you machine).
### Third-party Driver ### Third-party Driver
......
...@@ -19,7 +19,7 @@ using System.Runtime.InteropServices; ...@@ -19,7 +19,7 @@ using System.Runtime.InteropServices;
namespace TDengineDriver namespace TDengineDriver
{ {
enum TDengineDataType public enum TDengineDataType
{ {
TSDB_DATA_TYPE_NULL = 0, // 1 bytes TSDB_DATA_TYPE_NULL = 0, // 1 bytes
TSDB_DATA_TYPE_BOOL = 1, // 1 bytes TSDB_DATA_TYPE_BOOL = 1, // 1 bytes
...@@ -33,12 +33,12 @@ namespace TDengineDriver ...@@ -33,12 +33,12 @@ namespace TDengineDriver
TSDB_DATA_TYPE_TIMESTAMP = 9,// 8 bytes TSDB_DATA_TYPE_TIMESTAMP = 9,// 8 bytes
TSDB_DATA_TYPE_NCHAR = 10, // unicode string TSDB_DATA_TYPE_NCHAR = 10, // unicode string
TSDB_DATA_TYPE_UTINYINT = 11,// 1 byte TSDB_DATA_TYPE_UTINYINT = 11,// 1 byte
TSDB_DATA_TYPE_USMALLINT= 12,// 2 bytes TSDB_DATA_TYPE_USMALLINT = 12,// 2 bytes
TSDB_DATA_TYPE_UINT = 13, // 4 bytes TSDB_DATA_TYPE_UINT = 13, // 4 bytes
TSDB_DATA_TYPE_UBIGINT= 14 // 8 bytes TSDB_DATA_TYPE_UBIGINT = 14 // 8 bytes
} }
enum TDengineInitOption public enum TDengineInitOption
{ {
TSDB_OPTION_LOCALE = 0, TSDB_OPTION_LOCALE = 0,
TSDB_OPTION_CHARSET = 1, TSDB_OPTION_CHARSET = 1,
...@@ -47,7 +47,7 @@ namespace TDengineDriver ...@@ -47,7 +47,7 @@ namespace TDengineDriver
TDDB_OPTION_SHELL_ACTIVITY_TIMER = 4 TDDB_OPTION_SHELL_ACTIVITY_TIMER = 4
} }
class TDengineMeta public class TDengineMeta
{ {
public string name; public string name;
public short size; public short size;
...@@ -90,7 +90,7 @@ namespace TDengineDriver ...@@ -90,7 +90,7 @@ namespace TDengineDriver
} }
} }
class TDengine public class TDengine
{ {
public const int TSDB_CODE_SUCCESS = 0; public const int TSDB_CODE_SUCCESS = 0;
......
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<RootNamespace>C_checker</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="TDengine.Connector" Version="1.0.2" />
</ItemGroup>
</Project>
/*
* 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/>.
*/
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace TDengineDriver
{
enum TDengineDataType
{
TSDB_DATA_TYPE_NULL = 0, // 1 bytes
TSDB_DATA_TYPE_BOOL = 1, // 1 bytes
TSDB_DATA_TYPE_TINYINT = 2, // 1 bytes
TSDB_DATA_TYPE_SMALLINT = 3, // 2 bytes
TSDB_DATA_TYPE_INT = 4, // 4 bytes
TSDB_DATA_TYPE_BIGINT = 5, // 8 bytes
TSDB_DATA_TYPE_FLOAT = 6, // 4 bytes
TSDB_DATA_TYPE_DOUBLE = 7, // 8 bytes
TSDB_DATA_TYPE_BINARY = 8, // string
TSDB_DATA_TYPE_TIMESTAMP = 9,// 8 bytes
TSDB_DATA_TYPE_NCHAR = 10, // unicode string
TSDB_DATA_TYPE_UTINYINT = 11,// 1 byte
TSDB_DATA_TYPE_USMALLINT= 12,// 2 bytes
TSDB_DATA_TYPE_UINT = 13, // 4 bytes
TSDB_DATA_TYPE_UBIGINT= 14 // 8 bytes
}
enum TDengineInitOption
{
TSDB_OPTION_LOCALE = 0,
TSDB_OPTION_CHARSET = 1,
TSDB_OPTION_TIMEZONE = 2,
TDDB_OPTION_CONFIGDIR = 3,
TDDB_OPTION_SHELL_ACTIVITY_TIMER = 4
}
class TDengineMeta
{
public string name;
public short size;
public byte type;
public string TypeName()
{
switch ((TDengineDataType)type)
{
case TDengineDataType.TSDB_DATA_TYPE_BOOL:
return "BOOL";
case TDengineDataType.TSDB_DATA_TYPE_TINYINT:
return "TINYINT";
case TDengineDataType.TSDB_DATA_TYPE_SMALLINT:
return "SMALLINT";
case TDengineDataType.TSDB_DATA_TYPE_INT:
return "INT";
case TDengineDataType.TSDB_DATA_TYPE_BIGINT:
return "BIGINT";
case TDengineDataType.TSDB_DATA_TYPE_UTINYINT:
return "TINYINT UNSIGNED";
case TDengineDataType.TSDB_DATA_TYPE_USMALLINT:
return "SMALLINT UNSIGNED";
case TDengineDataType.TSDB_DATA_TYPE_UINT:
return "INT UNSIGNED";
case TDengineDataType.TSDB_DATA_TYPE_UBIGINT:
return "BIGINT UNSIGNED";
case TDengineDataType.TSDB_DATA_TYPE_FLOAT:
return "FLOAT";
case TDengineDataType.TSDB_DATA_TYPE_DOUBLE:
return "DOUBLE";
case TDengineDataType.TSDB_DATA_TYPE_BINARY:
return "STRING";
case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP:
return "TIMESTAMP";
case TDengineDataType.TSDB_DATA_TYPE_NCHAR:
return "NCHAR";
default:
return "undefine";
}
}
}
class TDengine
{
public const int TSDB_CODE_SUCCESS = 0;
[DllImport("taos", EntryPoint = "taos_init", CallingConvention = CallingConvention.Cdecl)]
static extern public void Init();
[DllImport("taos", EntryPoint = "taos_cleanup", CallingConvention = CallingConvention.Cdecl)]
static extern public void Cleanup();
[DllImport("taos", EntryPoint = "taos_options", CallingConvention = CallingConvention.Cdecl)]
static extern public void Options(int option, string value);
[DllImport("taos", EntryPoint = "taos_connect", CallingConvention = CallingConvention.Cdecl)]
static extern public IntPtr Connect(string ip, string user, string password, string db, short port);
[DllImport("taos", EntryPoint = "taos_errstr", CallingConvention = CallingConvention.Cdecl)]
static extern private IntPtr taos_errstr(IntPtr res);
static public string Error(IntPtr res)
{
IntPtr errPtr = taos_errstr(res);
return Marshal.PtrToStringAnsi(errPtr);
}
[DllImport("taos", EntryPoint = "taos_errno", CallingConvention = CallingConvention.Cdecl)]
static extern public int ErrorNo(IntPtr res);
[DllImport("taos", EntryPoint = "taos_query", CallingConvention = CallingConvention.Cdecl)]
static extern public IntPtr Query(IntPtr conn, string sqlstr);
[DllImport("taos", EntryPoint = "taos_affected_rows", CallingConvention = CallingConvention.Cdecl)]
static extern public int AffectRows(IntPtr res);
[DllImport("taos", EntryPoint = "taos_field_count", CallingConvention = CallingConvention.Cdecl)]
static extern public int FieldCount(IntPtr res);
[DllImport("taos", EntryPoint = "taos_fetch_fields", CallingConvention = CallingConvention.Cdecl)]
static extern private IntPtr taos_fetch_fields(IntPtr res);
static public List<TDengineMeta> FetchFields(IntPtr res)
{
const int fieldSize = 68;
List<TDengineMeta> metas = new List<TDengineMeta>();
if (res == IntPtr.Zero)
{
return metas;
}
int fieldCount = FieldCount(res);
IntPtr fieldsPtr = taos_fetch_fields(res);
for (int i = 0; i < fieldCount; ++i)
{
int offset = i * fieldSize;
TDengineMeta meta = new TDengineMeta();
meta.name = Marshal.PtrToStringAnsi(fieldsPtr + offset);
meta.type = Marshal.ReadByte(fieldsPtr + offset + 65);
meta.size = Marshal.ReadInt16(fieldsPtr + offset + 66);
metas.Add(meta);
}
return metas;
}
[DllImport("taos", EntryPoint = "taos_fetch_row", CallingConvention = CallingConvention.Cdecl)]
static extern public IntPtr FetchRows(IntPtr res);
[DllImport("taos", EntryPoint = "taos_free_result", CallingConvention = CallingConvention.Cdecl)]
static extern public IntPtr FreeResult(IntPtr res);
[DllImport("taos", EntryPoint = "taos_close", CallingConvention = CallingConvention.Cdecl)]
static extern public int Close(IntPtr taos);
//get precision in restultset
[DllImport("taos", EntryPoint = "taos_result_precision", CallingConvention = CallingConvention.Cdecl)]
static extern public int ResultPrecision(IntPtr taos);
//schemaless API
[DllImport("taos",SetLastError = true, EntryPoint = "taos_schemaless_insert", CallingConvention = CallingConvention.Cdecl)]
static extern public IntPtr SchemalessInsert(IntPtr taos, string[] lines, int numLines, int protocol, int precision);
}
}
/*
* 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/>.
*/
using System;
using System.Text;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Collections;
namespace TDengineDriver
{
class TDengineTest
{
//connect parameters
private string host;
private string configDir;
private string user;
private string password;
private short port = 0;
//sql parameters
private string dbName;
private string stableName;
private string tablePrefix;
private bool isInsertData;
private bool isQueryData;
private long tableCount;
private long totalRows;
private long batchRows;
private long beginTimestamp = 1551369600000L;
private IntPtr conn = IntPtr.Zero;
private long rowsInserted = 0;
static void Main(string[] args)
{
TDengineTest tester = new TDengineTest();
tester.ReadArgument(args);
Console.WriteLine("---------------------------------------------------------------");
Console.WriteLine("Starting Testing...");
Console.WriteLine("---------------------------------------------------------------");
tester.InitTDengine();
tester.ConnectTDengine();
tester.CreateDbAndTable();
tester.ExecuteInsert();
tester.ExecuteQuery();
tester.CloseConnection();
Console.WriteLine("---------------------------------------------------------------");
Console.WriteLine("Stop Testing...");
Console.WriteLine("---------------------------------------------------------------");
}
public long GetArgumentAsLong(String[] argv, String argName, int minVal, int maxVal, int defaultValue)
{
int argc = argv.Length;
for (int i = 0; i < argc; ++i)
{
if (argName != argv[i])
{
continue;
}
if (i < argc - 1)
{
String tmp = argv[i + 1];
if (tmp[0] == '-')
{
Console.WriteLine("option {0:G} requires an argument", tmp);
ExitProgram();
}
long tmpVal = Convert.ToInt64(tmp);
if (tmpVal < minVal || tmpVal > maxVal)
{
Console.WriteLine("option {0:G} should in range [{1:G}, {2:G}]", argName, minVal, maxVal);
ExitProgram();
}
return tmpVal;
}
}
return defaultValue;
}
public String GetArgumentAsString(String[] argv, String argName, String defaultValue)
{
int argc = argv.Length;
for (int i = 0; i < argc; ++i)
{
if (argName != argv[i])
{
continue;
}
if (i < argc - 1)
{
String tmp = argv[i + 1];
if (tmp[0] == '-')
{
Console.WriteLine("option {0:G} requires an argument", tmp);
ExitProgram();
}
return tmp;
}
}
return defaultValue;
}
public void PrintHelp(String[] argv)
{
for (int i = 0; i < argv.Length; ++i)
{
if ("--help" == argv[i])
{
String indent = " ";
Console.WriteLine("taosTest is simple example to operate TDengine use C# Language.\n");
Console.WriteLine("{0:G}{1:G}", indent, "-h");
Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "TDEngine server IP address to connect");
Console.WriteLine("{0:G}{1:G}", indent, "-u");
Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "The TDEngine user name to use when connecting to the server, default is root");
Console.WriteLine("{0:G}{1:G}", indent, "-p");
Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "The TDEngine user name to use when connecting to the server, default is taosdata");
Console.WriteLine("{0:G}{1:G}", indent, "-d");
Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "Database used to create table or import data, default is db");
Console.WriteLine("{0:G}{1:G}", indent, "-s");
Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "Super Tables used to create table, default is mt");
Console.WriteLine("{0:G}{1:G}", indent, "-t");
Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "Table prefixs, default is t");
Console.WriteLine("{0:G}{1:G}", indent, "-w");
Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "Whether to insert data");
Console.WriteLine("{0:G}{1:G}", indent, "-r");
Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "Whether to query data");
Console.WriteLine("{0:G}{1:G}", indent, "-n");
Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "How many Tables to create, default is 10");
Console.WriteLine("{0:G}{1:G}", indent, "-b");
Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "How many rows per insert batch, default is 10");
Console.WriteLine("{0:G}{1:G}", indent, "-i");
Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "How many rows to insert, default is 100");
Console.WriteLine("{0:G}{1:G}", indent, "-c");
Console.WriteLine("{0:G}{1:G}{2:G}", indent, indent, "Configuration directory");
ExitProgram();
}
}
}
public void ReadArgument(String[] argv)
{
PrintHelp(argv);
host = this.GetArgumentAsString(argv, "-h", "127.0.0.1");
user = this.GetArgumentAsString(argv, "-u", "root");
password = this.GetArgumentAsString(argv, "-p", "taosdata");
dbName = this.GetArgumentAsString(argv, "-d", "db");
stableName = this.GetArgumentAsString(argv, "-s", "st");
tablePrefix = this.GetArgumentAsString(argv, "-t", "t");
isInsertData = this.GetArgumentAsLong(argv, "-w", 0, 1, 1) != 0;
isQueryData = this.GetArgumentAsLong(argv, "-r", 0, 1, 1) != 0;
tableCount = this.GetArgumentAsLong(argv, "-n", 1, 10000, 10);
batchRows = this.GetArgumentAsLong(argv, "-b", 1, 1000, 500);
totalRows = this.GetArgumentAsLong(argv, "-i", 1, 10000000, 10000);
configDir = this.GetArgumentAsString(argv, "-c", "C:/TDengine/cfg");
}
public void InitTDengine()
{
TDengine.Options((int)TDengineInitOption.TDDB_OPTION_CONFIGDIR, this.configDir);
TDengine.Options((int)TDengineInitOption.TDDB_OPTION_SHELL_ACTIVITY_TIMER, "60");
TDengine.Init();
Console.WriteLine("TDengine Initialization finished");
}
public void ConnectTDengine()
{
string db = "";
this.conn = TDengine.Connect(this.host, this.user, this.password, db, this.port);
if (this.conn == IntPtr.Zero)
{
Console.WriteLine("Connect to TDengine failed");
ExitProgram();
}
else
{
Console.WriteLine("Connect to TDengine success");
}
}
public void CreateDbAndTable()
{
if (!this.isInsertData)
{
return;
}
StringBuilder sql = new StringBuilder();
sql.Append("create database if not exists ").Append(this.dbName);
IntPtr res = TDengine.Query(this.conn, sql.ToString());
if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0))
{
Console.Write(sql.ToString() + " failure, ");
if (res != IntPtr.Zero) {
Console.Write("reason: " + TDengine.Error(res));
}
Console.WriteLine("");
ExitProgram();
}
else
{
Console.WriteLine(sql.ToString() + " success");
}
TDengine.FreeResult(res);
sql.Clear();
sql.Append("use ").Append(this.dbName);
res = TDengine.Query(this.conn, sql.ToString());
if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0))
{
Console.Write(sql.ToString() + " failure, ");
if (res != IntPtr.Zero) {
Console.Write("reason: " + TDengine.Error(res));
}
Console.WriteLine("");
ExitProgram();
}
else
{
Console.WriteLine(sql.ToString() + " success");
}
TDengine.FreeResult(res);
sql.Clear();
sql.Append("create table if not exists ").Append(this.stableName).Append("(ts timestamp, v1 bool, v2 tinyint, v3 smallint, v4 int, v5 bigint, v6 float, v7 double, v8 binary(10), v9 nchar(10)) tags(t1 int)");
res = TDengine.Query(this.conn, sql.ToString());
if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0))
{
Console.Write(sql.ToString() + " failure, ");
if (res != IntPtr.Zero) {
Console.Write("reason: " + TDengine.Error(res));
}
Console.WriteLine("");
ExitProgram();
}
else
{
Console.WriteLine(sql.ToString() + " success");
}
TDengine.FreeResult(res);
for (int i = 0; i < this.tableCount; i++)
{
sql.Clear();
sql = sql.Append("create table if not exists ").Append(this.tablePrefix).Append(i)
.Append(" using ").Append(this.stableName).Append(" tags(").Append(i).Append(")");
res = TDengine.Query(this.conn, sql.ToString());
if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0))
{
Console.Write(sql.ToString() + " failure, ");
if (res != IntPtr.Zero) {
Console.Write("reason: " + TDengine.Error(res));
}
Console.WriteLine("");
ExitProgram();
}
else
{
Console.WriteLine(sql.ToString() + " success");
}
TDengine.FreeResult(res);
}
Console.WriteLine("create db and table success");
}
public void ExecuteInsert()
{
if (!this.isInsertData)
{
return;
}
System.DateTime start = new System.DateTime();
long loopCount = this.totalRows / this.batchRows;
for (int table = 0; table < this.tableCount; ++table)
{
for (long loop = 0; loop < loopCount; loop++)
{
StringBuilder sql = new StringBuilder();
sql.Append("insert into ").Append(this.tablePrefix).Append(table).Append(" values");
for (int batch = 0; batch < this.batchRows; ++batch)
{
long rows = loop * this.batchRows + batch;
sql.Append("(")
.Append(this.beginTimestamp + rows)
.Append(", 1, 2, 3,")
.Append(rows)
.Append(", 5, 6, 7, 'abc', 'def')");
}
IntPtr res = TDengine.Query(this.conn, sql.ToString());
if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0))
{
Console.Write(sql.ToString() + " failure, ");
if (res != IntPtr.Zero) {
Console.Write("reason: " + TDengine.Error(res));
}
Console.WriteLine("");
}
int affectRows = TDengine.AffectRows(res);
this.rowsInserted += affectRows;
TDengine.FreeResult(res);
}
}
System.DateTime end = new System.DateTime();
TimeSpan ts = end - start;
Console.Write("Total {0:G} rows inserted, {1:G} rows failed, time spend {2:G} seconds.\n"
, this.rowsInserted, this.totalRows * this.tableCount - this.rowsInserted, ts.TotalSeconds);
}
public void ExecuteQuery()
{
if (!this.isQueryData)
{
return;
}
System.DateTime start = new System.DateTime();
long queryRows = 0;
for (int i = 0; i < 1/*this.tableCount*/; ++i)
{
String sql = "select * from " + this.dbName + "." + tablePrefix + i;
Console.WriteLine(sql);
IntPtr res = TDengine.Query(conn, sql);
if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0))
{
Console.Write(sql.ToString() + " failure, ");
if (res != IntPtr.Zero) {
Console.Write("reason: " + TDengine.Error(res));
}
Console.WriteLine("");
ExitProgram();
}
int fieldCount = TDengine.FieldCount(res);
Console.WriteLine("field count: " + fieldCount);
List<TDengineMeta> metas = TDengine.FetchFields(res);
for (int j = 0; j < metas.Count; j++)
{
TDengineMeta meta = (TDengineMeta)metas[j];
Console.WriteLine("index:" + j + ", type:" + meta.type + ", typename:" + meta.TypeName() + ", name:" + meta.name + ", size:" + meta.size);
}
IntPtr rowdata;
StringBuilder builder = new StringBuilder();
while ((rowdata = TDengine.FetchRows(res)) != IntPtr.Zero)
{
queryRows++;
for (int fields = 0; fields < fieldCount; ++fields)
{
TDengineMeta meta = metas[fields];
int offset = IntPtr.Size * fields;
IntPtr data = Marshal.ReadIntPtr(rowdata, offset);
builder.Append("---");
if (data == IntPtr.Zero)
{
builder.Append("NULL");
continue;
}
switch ((TDengineDataType)meta.type)
{
case TDengineDataType.TSDB_DATA_TYPE_BOOL:
bool v1 = Marshal.ReadByte(data) == 0 ? false : true;
builder.Append(v1);
break;
case TDengineDataType.TSDB_DATA_TYPE_TINYINT:
byte v2 = Marshal.ReadByte(data);
builder.Append(v2);
break;
case TDengineDataType.TSDB_DATA_TYPE_SMALLINT:
short v3 = Marshal.ReadInt16(data);
builder.Append(v3);
break;
case TDengineDataType.TSDB_DATA_TYPE_INT:
int v4 = Marshal.ReadInt32(data);
builder.Append(v4);
break;
case TDengineDataType.TSDB_DATA_TYPE_BIGINT:
long v5 = Marshal.ReadInt64(data);
builder.Append(v5);
break;
case TDengineDataType.TSDB_DATA_TYPE_FLOAT:
float v6 = (float)Marshal.PtrToStructure(data, typeof(float));
builder.Append(v6);
break;
case TDengineDataType.TSDB_DATA_TYPE_DOUBLE:
double v7 = (double)Marshal.PtrToStructure(data, typeof(double));
builder.Append(v7);
break;
case TDengineDataType.TSDB_DATA_TYPE_BINARY:
string v8 = Marshal.PtrToStringAnsi(data);
builder.Append(v8);
break;
case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP:
long v9 = Marshal.ReadInt64(data);
builder.Append(v9);
break;
case TDengineDataType.TSDB_DATA_TYPE_NCHAR:
string v10 = Marshal.PtrToStringAnsi(data);
builder.Append(v10);
break;
case TDengineDataType.TSDB_DATA_TYPE_UTINYINT:
byte v11 = Marshal.ReadByte(data);
builder.Append(v11);
break;
case TDengineDataType.TSDB_DATA_TYPE_USMALLINT:
ushort v12 = (ushort)Marshal.ReadInt16(data);
builder.Append(v12);
break;
case TDengineDataType.TSDB_DATA_TYPE_UINT:
uint v13 = (uint)Marshal.ReadInt32(data);
builder.Append(v13);
break;
case TDengineDataType.TSDB_DATA_TYPE_UBIGINT:
ulong v14 = (ulong)Marshal.ReadInt64(data);
builder.Append(v14);
break;
}
}
builder.Append("---");
if (queryRows <= 10)
{
Console.WriteLine(builder.ToString());
}
builder.Clear();
}
if (TDengine.ErrorNo(res) != 0)
{
Console.Write("Query is not complete, Error {0:G}",
TDengine.ErrorNo(res), TDengine.Error(res));
}
Console.WriteLine("");
TDengine.FreeResult(res);
}
System.DateTime end = new System.DateTime();
TimeSpan ts = end - start;
Console.Write("Total {0:G} rows inserted, {1:G} rows query, time spend {2:G} seconds.\n"
, this.rowsInserted, queryRows, ts.TotalSeconds);
}
public void CloseConnection()
{
if (this.conn != IntPtr.Zero)
{
TDengine.Close(this.conn);
}
}
static void ExitProgram()
{
TDengine.Cleanup();
System.Environment.Exit(0);
}
}
}
此差异已折叠。
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="TDengine.Connector" Version="1.0.2" />
</ItemGroup>
</Project>
/*
* 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/>.
*/
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace TDengineDriver
{
enum TDengineDataType
{
TSDB_DATA_TYPE_NULL = 0, // 1 bytes
TSDB_DATA_TYPE_BOOL = 1, // 1 bytes
TSDB_DATA_TYPE_TINYINT = 2, // 1 bytes
TSDB_DATA_TYPE_SMALLINT = 3, // 2 bytes
TSDB_DATA_TYPE_INT = 4, // 4 bytes
TSDB_DATA_TYPE_BIGINT = 5, // 8 bytes
TSDB_DATA_TYPE_FLOAT = 6, // 4 bytes
TSDB_DATA_TYPE_DOUBLE = 7, // 8 bytes
TSDB_DATA_TYPE_BINARY = 8, // string
TSDB_DATA_TYPE_TIMESTAMP = 9,// 8 bytes
TSDB_DATA_TYPE_NCHAR = 10, // unicode string
TSDB_DATA_TYPE_UTINYINT = 11,// 1 byte
TSDB_DATA_TYPE_USMALLINT= 12,// 2 bytes
TSDB_DATA_TYPE_UINT = 13, // 4 bytes
TSDB_DATA_TYPE_UBIGINT= 14 // 8 bytes
}
enum TDengineInitOption
{
TSDB_OPTION_LOCALE = 0,
TSDB_OPTION_CHARSET = 1,
TSDB_OPTION_TIMEZONE = 2,
TDDB_OPTION_CONFIGDIR = 3,
TDDB_OPTION_SHELL_ACTIVITY_TIMER = 4
}
class TDengineMeta
{
public string name;
public short size;
public byte type;
public string TypeName()
{
switch ((TDengineDataType)type)
{
case TDengineDataType.TSDB_DATA_TYPE_BOOL:
return "BOOL";
case TDengineDataType.TSDB_DATA_TYPE_TINYINT:
return "TINYINT";
case TDengineDataType.TSDB_DATA_TYPE_SMALLINT:
return "SMALLINT";
case TDengineDataType.TSDB_DATA_TYPE_INT:
return "INT";
case TDengineDataType.TSDB_DATA_TYPE_BIGINT:
return "BIGINT";
case TDengineDataType.TSDB_DATA_TYPE_UTINYINT:
return "TINYINT UNSIGNED";
case TDengineDataType.TSDB_DATA_TYPE_USMALLINT:
return "SMALLINT UNSIGNED";
case TDengineDataType.TSDB_DATA_TYPE_UINT:
return "INT UNSIGNED";
case TDengineDataType.TSDB_DATA_TYPE_UBIGINT:
return "BIGINT UNSIGNED";
case TDengineDataType.TSDB_DATA_TYPE_FLOAT:
return "FLOAT";
case TDengineDataType.TSDB_DATA_TYPE_DOUBLE:
return "DOUBLE";
case TDengineDataType.TSDB_DATA_TYPE_BINARY:
return "STRING";
case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP:
return "TIMESTAMP";
case TDengineDataType.TSDB_DATA_TYPE_NCHAR:
return "NCHAR";
default:
return "undefine";
}
}
}
class TDengine
{
public const int TSDB_CODE_SUCCESS = 0;
[DllImport("taos", EntryPoint = "taos_init", CallingConvention = CallingConvention.Cdecl)]
static extern public void Init();
[DllImport("taos", EntryPoint = "taos_cleanup", CallingConvention = CallingConvention.Cdecl)]
static extern public void Cleanup();
[DllImport("taos", EntryPoint = "taos_options", CallingConvention = CallingConvention.Cdecl)]
static extern public void Options(int option, string value);
[DllImport("taos", EntryPoint = "taos_connect", CallingConvention = CallingConvention.Cdecl)]
static extern public IntPtr Connect(string ip, string user, string password, string db, short port);
[DllImport("taos", EntryPoint = "taos_errstr", CallingConvention = CallingConvention.Cdecl)]
static extern private IntPtr taos_errstr(IntPtr res);
static public string Error(IntPtr res)
{
IntPtr errPtr = taos_errstr(res);
return Marshal.PtrToStringAnsi(errPtr);
}
[DllImport("taos", EntryPoint = "taos_errno", CallingConvention = CallingConvention.Cdecl)]
static extern public int ErrorNo(IntPtr res);
[DllImport("taos", EntryPoint = "taos_query", CallingConvention = CallingConvention.Cdecl)]
static extern public IntPtr Query(IntPtr conn, string sqlstr);
[DllImport("taos", EntryPoint = "taos_affected_rows", CallingConvention = CallingConvention.Cdecl)]
static extern public int AffectRows(IntPtr res);
[DllImport("taos", EntryPoint = "taos_field_count", CallingConvention = CallingConvention.Cdecl)]
static extern public int FieldCount(IntPtr res);
[DllImport("taos", EntryPoint = "taos_fetch_fields", CallingConvention = CallingConvention.Cdecl)]
static extern private IntPtr taos_fetch_fields(IntPtr res);
static public List<TDengineMeta> FetchFields(IntPtr res)
{
const int fieldSize = 68;
List<TDengineMeta> metas = new List<TDengineMeta>();
if (res == IntPtr.Zero)
{
return metas;
}
int fieldCount = FieldCount(res);
IntPtr fieldsPtr = taos_fetch_fields(res);
for (int i = 0; i < fieldCount; ++i)
{
int offset = i * fieldSize;
TDengineMeta meta = new TDengineMeta();
meta.name = Marshal.PtrToStringAnsi(fieldsPtr + offset);
meta.type = Marshal.ReadByte(fieldsPtr + offset + 65);
meta.size = Marshal.ReadInt16(fieldsPtr + offset + 66);
metas.Add(meta);
}
return metas;
}
[DllImport("taos", EntryPoint = "taos_fetch_row", CallingConvention = CallingConvention.Cdecl)]
static extern public IntPtr FetchRows(IntPtr res);
[DllImport("taos", EntryPoint = "taos_free_result", CallingConvention = CallingConvention.Cdecl)]
static extern public IntPtr FreeResult(IntPtr res);
[DllImport("taos", EntryPoint = "taos_close", CallingConvention = CallingConvention.Cdecl)]
static extern public int Close(IntPtr taos);
//get precisionin parameter restultset
[DllImport("taos", EntryPoint = "taos_result_precision", CallingConvention = CallingConvention.Cdecl)]
static extern public int ResultPrecision(IntPtr taos);
}
}
...@@ -6,4 +6,8 @@ ...@@ -6,4 +6,8 @@
<GenerateAssemblyInfo>false</GenerateAssemblyInfo> <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<PackageReference Include="TDengine.Connector" Version="1.0.2" />
</ItemGroup>
</Project> </Project>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册