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

[TD-12867]<fix>(connector):csharp commector insert cn failed (#9794)

* [TD-12867]<fix>:csharp connector insert cn failed

* submit to linux

* [TD-12867]<fix>(connector):csharp commector insert cn failed

* [TD-12867]<fix>(connector):csharp fix insert chinses fiailed
上级 4443a76b
......@@ -173,7 +173,17 @@ namespace TDengineDriver
static extern public int ErrorNo(IntPtr res);
[DllImport("taos", EntryPoint = "taos_query", CallingConvention = CallingConvention.Cdecl)]
static extern public IntPtr Query(IntPtr conn, string sqlstr);
// static extern public IntPtr Query(IntPtr conn, string sqlstr);
static extern private IntPtr Query(IntPtr conn, IntPtr byteArr);
static public IntPtr Query(IntPtr conn,string command)
{
IntPtr res = IntPtr.Zero;
IntPtr commandBuffer = Marshal.StringToCoTaskMemUTF8(command);
res = Query(conn,commandBuffer);
return res;
}
[DllImport("taos", EntryPoint = "taos_affected_rows", CallingConvention = CallingConvention.Cdecl)]
static extern public int AffectRows(IntPtr res);
......
......@@ -2,7 +2,6 @@ using System;
using System.Runtime.InteropServices;
using System.Text;
namespace TDengineDriver
{
/// <summary>
......@@ -248,9 +247,10 @@ namespace TDengineDriver
{
TAOS_BIND bind = new TAOS_BIND();
IntPtr umanageBinary = Marshal.StringToHGlobalAnsi(val);
// IntPtr umanageBinary = Marshal.StringToHGlobalAnsi(val);
IntPtr umanageBinary = Marshal.StringToCoTaskMemUTF8(val);
var strToBytes = System.Text.Encoding.Default.GetBytes(val);
var strToBytes = System.Text.Encoding.UTF8.GetBytes(val);
int leng = strToBytes.Length;
IntPtr lenPtr = Marshal.AllocHGlobal(sizeof(ulong));
Marshal.WriteInt64(lenPtr, leng);
......@@ -266,8 +266,9 @@ namespace TDengineDriver
public static TAOS_BIND BindNchar(String val)
{
TAOS_BIND bind = new TAOS_BIND();
var strToBytes = System.Text.Encoding.Default.GetBytes(val);
IntPtr umanageNchar = (IntPtr)Marshal.StringToHGlobalAnsi(val);
var strToBytes = System.Text.Encoding.UTF8.GetBytes(val);
// IntPtr umanageNchar = (IntPtr)Marshal.StringToHGlobalAnsi(val);
IntPtr umanageNchar = (IntPtr)Marshal.StringToCoTaskMemUTF8(val);
int leng = strToBytes.Length;
......
......@@ -2,7 +2,6 @@ using System;
using System.Text;
using System.Runtime.InteropServices;
namespace TDengineDriver
{
public class TaosMultiBind
......
using System;
using Test.UtilsTools;
using TDengineDriver;
using Test.UtilsTools.DataSource;
using Xunit;
using System.Collections.Generic;
using Test.UtilsTools.ResultSet;
namespace Cases
{
public class InsertCnCharacterCases
{
/// <author>xiaolei</author>
/// <Name>InsertCnCharacterCases.TestInsertCnToNtable</Name>
/// <describe>test insert Chinese character into normal table's nchar column</describe>
/// <filename>InsertCn.cs</filename>
/// <result>pass or failed </result>
[Fact(DisplayName = "InsertCnCharacterCases.TestInsertCnToNtable()")]
public void TestInsertCnToNtable()
{
IntPtr conn = UtilsTools.TDConnection();
IntPtr _res = IntPtr.Zero;
string tableName = "cn_insert_nchar_ntable";
// var expectResData = new List<String> { "1637064040000", "true", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "XI", "XII", "{\"k1\": \"v1\"}" };
var colData = new List<Object>{1637064040000,1,"涛思数据",
1637064041000,2,"涛思数据taosdata",
1637064042000,3,"TDegnine涛思数据",
1637064043000,4,"4涛思数据",
1637064044000,5,"涛思数据5",
1637064045000,6,"taos涛思数据6",
1637064046000,7,"7涛思数据taos",
1637064047000,8,"8&涛思数据taos",
1637064048000,9,"&涛思数据taos9"
};
String dropTb = "drop table if exists " + tableName;
String createTb = $"create table if not exists {tableName} (ts timestamp,v4 int,blob nchar(200));";
String insertSql = UtilsTools.ConstructInsertSql(tableName, "", colData, null, 9);
String selectSql = "select * from " + tableName;
String dropSql = "drop table " + tableName;
List<TDengineMeta> expectResMeta = DataSource.GetMetaFromDLL(createTb);
UtilsTools.ExecuteUpdate(conn, dropTb);
UtilsTools.ExecuteUpdate(conn, createTb);
UtilsTools.ExecuteUpdate(conn, insertSql);
_res = UtilsTools.ExecuteQuery(conn, selectSql);
ResultSet actualResult = new ResultSet(_res);
List<TDengineMeta> actualMeta = actualResult.GetResultMeta();
List<String> actualResData = actualResult.GetResultData();
//Assert Meta data
for (int i = 0; i < actualMeta.Count; i++)
{
Assert.Equal(expectResMeta[i].name, actualMeta[i].name);
Assert.Equal(expectResMeta[i].type, actualMeta[i].type);
Assert.Equal(expectResMeta[i].size, actualMeta[i].size);
}
// Assert retrieve data
for (int i = 0; i < actualResData.Count; i++)
{
Assert.Equal(colData[i].ToString(), actualResData[i]);
}
}
/// <author>xiaolei</author>
/// <Name>InsertCnCharacterCases.TestInsertCnToStable</Name>
/// <describe>test insert Chinese character into stable's nchar column,both tag and column</describe>
/// <filename>InsertCn.cs</filename>
/// <result>pass or failed </result>
[Fact(DisplayName = "InsertCnCharacterCases.TestInsertCnToStable()")]
public void TestInsertCnToStable()
{
IntPtr conn = UtilsTools.TDConnection();
IntPtr _res = IntPtr.Zero;
string tableName = "cn_insert_nchar_stable";
var colData = new List<Object>{1637064040000,1,"涛思数据",
1637064041000,2,"涛思数据taosdata",
1637064042000,3,"TDegnine涛思数据",
1637064043000,4,"4涛思数据",
1637064044000,5,"涛思数据5",
1637064045000,6,"taos涛思数据6",
1637064046000,7,"7涛思数据taos",
1637064047000,8,"8&涛思数据taos",
1637064048000,9,"&涛思数据taos9"
};
var tagData = new List<Object>{1,"涛思数据",};
String dropTb = "drop table if exists " + tableName;
String createTb = $"create table {tableName} (ts timestamp,v4 int,blob nchar(200))tags(id int,name nchar(50));";
String insertSql = UtilsTools.ConstructInsertSql(tableName+"_sub1", tableName, colData, tagData, 9);
String selectSql = "select * from " + tableName;
String dropSql = "drop table " + tableName;
List<TDengineMeta> expectResMeta = DataSource.GetMetaFromDLL(createTb);
List<Object> expectResData = UtilsTools.CombineColAndTagData(colData,tagData,9);
UtilsTools.ExecuteUpdate(conn, dropTb);
UtilsTools.ExecuteUpdate(conn, createTb);
UtilsTools.ExecuteUpdate(conn, insertSql);
_res = UtilsTools.ExecuteQuery(conn, selectSql);
ResultSet actualResult = new ResultSet(_res);
List<TDengineMeta> actualMeta = actualResult.GetResultMeta();
List<String> actualResData = actualResult.GetResultData();
//Assert Meta data
for (int i = 0; i < actualMeta.Count; i++)
{
Assert.Equal(expectResMeta[i].name, actualMeta[i].name);
Assert.Equal(expectResMeta[i].type, actualMeta[i].type);
Assert.Equal(expectResMeta[i].size, actualMeta[i].size);
}
// Assert retrieve data
for (int i = 0; i < actualResData.Count; i++)
{
Assert.Equal(expectResData[i].ToString(), actualResData[i]);
}
}
/// <author>xiaolei</author>
/// <Name>InsertCnCharacterCases.TestInsertMutilCnToNtable</Name>
/// <describe>test insert Chinese character into normal table's multiple nchar columns</describe>
/// <filename>InsertCn.cs</filename>
/// <result>pass or failed </result>
[Fact(DisplayName = "InsertCnCharacterCases.TestInsertMutilCnToNtable()")]
public void TestInsertMutilCnToNtable()
{
IntPtr conn = UtilsTools.TDConnection();
IntPtr _res = IntPtr.Zero;
string tableName = "cn_multi_insert_nchar_ntable";
var colData = new List<Object>{1637064040000,1,"涛思数据","保利广场","Beijing","China",
1637064041000,2,"涛思数据taosdata","保利广场baoli","Beijing","China",
1637064042000,3,"TDegnine涛思数据","time广场","NewYork","US",
1637064043000,4,"4涛思数据","4广场南部","London","UK",
1637064044000,5,"涛思数据5","!广场路中部123","Tokyo","JP",
1637064045000,6,"taos涛思数据6","青年广场123号!","Washin","DC",
1637064046000,7,"7涛思数据taos","asdf#壮年广场%#endregion","NewYork","US",
1637064047000,8,"8&涛思数据taos","incluse阿斯顿发","NewYork","US",
1637064048000,9,"&涛思数据taos9","123黑化肥werq会挥……&¥%发!afsdfa","NewYork","US",
};
String dropTb = "drop table if exists " + tableName;
String createTb = $"create table if not exists {tableName} (ts timestamp,v4 int,blob nchar(200),location nchar(200),city binary(100),coutry binary(200));";
String insertSql = UtilsTools.ConstructInsertSql(tableName, "", colData, null, 9);
String selectSql = "select * from " + tableName;
String dropSql = "drop table " + tableName;
List<TDengineMeta> expectResMeta = DataSource.GetMetaFromDLL(createTb);
UtilsTools.ExecuteUpdate(conn, dropTb);
UtilsTools.ExecuteUpdate(conn, createTb);
UtilsTools.ExecuteUpdate(conn, insertSql);
_res = UtilsTools.ExecuteQuery(conn, selectSql);
ResultSet actualResult = new ResultSet(_res);
List<TDengineMeta> actualMeta = actualResult.GetResultMeta();
List<String> actualResData = actualResult.GetResultData();
//Assert Meta data
for (int i = 0; i < actualMeta.Count; i++)
{
Assert.Equal(expectResMeta[i].name, actualMeta[i].name);
Assert.Equal(expectResMeta[i].type, actualMeta[i].type);
Assert.Equal(expectResMeta[i].size, actualMeta[i].size);
}
// Assert retrieve data
for (int i = 0; i < actualResData.Count; i++)
{
Assert.Equal(colData[i].ToString(), actualResData[i]);
}
}
/// <author>xiaolei</author>
/// <Name>InsertCnCharacterCases.TestInsertMutilCnToStable</Name>
/// <describe>test insert Chinese character into stable's multiple nchar columns</describe>
/// <filename>InsertCn.cs</filename>
/// <result>pass or failed </result>
[Fact(DisplayName = "InsertCnCharacterCases.TestInsertMutilCnToStable()")]
public void TestInsertMutilCnToStable()
{
IntPtr conn = UtilsTools.TDConnection();
IntPtr _res = IntPtr.Zero;
string tableName = "cn_multi_insert_nchar_stable";
var colData = new List<Object>{1637064040000,1,"涛思数据","保利广场","Beijing","China",
1637064041000,2,"涛思数据taosdata","保利广场baoli","Beijing","China",
1637064042000,3,"TDegnine涛思数据","time广场","NewYork","US",
1637064043000,4,"4涛思数据","4广场南部","London","UK",
1637064044000,5,"涛思数据5","!广场路中部123","Tokyo","JP",
1637064045000,6,"taos涛思数据6","青年广场123号!","Washin","DC",
1637064046000,7,"7涛思数据taos","asdf#壮年广场%#endregion","NewYork","US",
1637064047000,8,"8&涛思数据taos","incluse阿斯顿发","NewYork","US",
1637064048000,9,"&涛思数据taos9","123黑化肥werq会挥……&¥%发!afsdfa","NewYork","US",
};
var tagData = new List<Object>{1,"涛思数据","中国北方&南方长江黄河!49wq","tdengine"};
String dropTb = "drop table if exists " + tableName;
String createTb = $"create table if not exists {tableName} (ts timestamp," +
$"v4 int," +
$"blob nchar(200)," +
$"locate nchar(200)," +
$"country nchar(200)," +
$"city nchar(50)" +
$")tags(" +
$"id int," +
$"name nchar(50)," +
$"addr nchar(200)," +
$"en_name binary(200));";
String insertSql = UtilsTools.ConstructInsertSql(tableName+"_sub1", tableName, colData, tagData, 9);
String selectSql = "select * from " + tableName;
String dropSql = "drop table " + tableName;
List<TDengineMeta> expectResMeta = DataSource.GetMetaFromDLL(createTb);
List<Object> expectResData = UtilsTools.CombineColAndTagData(colData,tagData,9);
UtilsTools.ExecuteUpdate(conn, dropTb);
UtilsTools.ExecuteUpdate(conn, createTb);
UtilsTools.ExecuteUpdate(conn, insertSql);
_res = UtilsTools.ExecuteQuery(conn, selectSql);
ResultSet actualResult = new ResultSet(_res);
List<TDengineMeta> actualMeta = actualResult.GetResultMeta();
List<String> actualResData = actualResult.GetResultData();
//Assert Meta data
for (int i = 0; i < actualMeta.Count; i++)
{
Assert.Equal(expectResMeta[i].name, actualMeta[i].name);
Assert.Equal(expectResMeta[i].type, actualMeta[i].type);
Assert.Equal(expectResMeta[i].size, actualMeta[i].size);
}
// Assert retrieve data
for (int i = 0; i < actualResData.Count; i++)
{
Assert.Equal(expectResData[i].ToString(), actualResData[i]);
}
}
}
}
\ No newline at end of file
using System;
using Test.UtilsTools;
using TDengineDriver;
using System.Collections.Generic;
using Xunit;
using Test.UtilsTools.ResultSet;
namespace Cases
{
public class FetchFieldCases
{
/// <author>xiaolei</author>
/// <Name>FetchFieldCases.TestFetchFieldJsonTag</Name>
/// <describe>test taos_fetch_fields(), check the meta data</describe>
/// <filename>TaosFeild.cs</filename>
/// <result>pass or failed </result>
[Fact(DisplayName = "FetchFieldCases.TestFetchFieldJsonTag()")]
public void TestFetchFieldJsonTag()
{
IntPtr conn = UtilsTools.TDConnection();
IntPtr _res = IntPtr.Zero;
string tableName = "fetchfeilds";
var expectResMeta = new List<TDengineMeta> {
UtilsTools.ConstructTDengineMeta("ts", "timestamp"),
UtilsTools.ConstructTDengineMeta("b", "bool"),
UtilsTools.ConstructTDengineMeta("v1", "tinyint"),
UtilsTools.ConstructTDengineMeta("v2", "smallint"),
UtilsTools.ConstructTDengineMeta("v4", "int"),
UtilsTools.ConstructTDengineMeta("v8", "bigint"),
UtilsTools.ConstructTDengineMeta("f4", "float"),
UtilsTools.ConstructTDengineMeta("f8", "double"),
UtilsTools.ConstructTDengineMeta("u1", "tinyint unsigned"),
UtilsTools.ConstructTDengineMeta("u2", "smallint unsigned"),
UtilsTools.ConstructTDengineMeta("u4", "int unsigned"),
UtilsTools.ConstructTDengineMeta("u8", "bigint unsigned"),
UtilsTools.ConstructTDengineMeta("bin", "binary(200)"),
UtilsTools.ConstructTDengineMeta("blob", "nchar(200)"),
UtilsTools.ConstructTDengineMeta("jsontag", "json"),
};
var expectResData = new List<String> { "1637064040000", "true", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "XI", "XII", "{\"k1\": \"v1\"}" };
String dropTb = "drop table if exists " + tableName;
String createTb = "create stable " + tableName
+ " (ts timestamp" +
",b bool" +
",v1 tinyint" +
",v2 smallint" +
",v4 int" +
",v8 bigint" +
",f4 float" +
",f8 double" +
",u1 tinyint unsigned" +
",u2 smallint unsigned" +
",u4 int unsigned" +
",u8 bigint unsigned" +
",bin binary(200)" +
",blob nchar(200)" +
")" +
"tags" +
"(jsontag json);";
String insertSql = "insert into " + tableName + "_t1 using " + tableName +
" tags('{\"k1\": \"v1\"}') " +
"values(1637064040000,true,1,2,3,4,5,6,7,8,9,10,'XI','XII')";
String selectSql = "select * from " + tableName;
String dropSql = "drop table " + tableName;
UtilsTools.ExecuteUpdate(conn, dropTb);
UtilsTools.ExecuteUpdate(conn, createTb);
UtilsTools.ExecuteUpdate(conn, insertSql);
_res = UtilsTools.ExecuteQuery(conn, selectSql);
ResultSet actualResult = new ResultSet(_res);
List<TDengineMeta> actualMeta = actualResult.GetResultMeta();
for (int i = 0; i < actualMeta.Count; i++)
{
Assert.Equal(expectResMeta[i].name, actualMeta[i].name);
Assert.Equal(expectResMeta[i].type, actualMeta[i].type);
Assert.Equal(expectResMeta[i].size, actualMeta[i].size);
}
}
}
}
using System;
using Test.UtilsTools;
using TDengineDriver;
using System.Collections.Generic;
using Xunit;
using Test.UtilsTools.ResultSet;
namespace Cases
{
public class FetchFieldCases
{
/// <author>xiaolei</author>
/// <Name>FetchFieldCases.TestFetchFieldJsonTag</Name>
/// <describe>test taos_fetch_fields(), check the meta data</describe>
/// <filename>TaosFeild.cs</filename>
/// <result>pass or failed </result>
[Fact(DisplayName = "FetchFieldCases.TestFetchFieldJsonTag()")]
public void TestFetchFieldJsonTag()
{
IntPtr conn = UtilsTools.TDConnection();
IntPtr _res = IntPtr.Zero;
string tableName = "fetchfeilds";
var expectResMeta = new List<TDengineMeta> {
UtilsTools.ConstructTDengineMeta("ts", "timestamp"),
UtilsTools.ConstructTDengineMeta("b", "bool"),
UtilsTools.ConstructTDengineMeta("v1", "tinyint"),
UtilsTools.ConstructTDengineMeta("v2", "smallint"),
UtilsTools.ConstructTDengineMeta("v4", "int"),
UtilsTools.ConstructTDengineMeta("v8", "bigint"),
UtilsTools.ConstructTDengineMeta("f4", "float"),
UtilsTools.ConstructTDengineMeta("f8", "double"),
UtilsTools.ConstructTDengineMeta("u1", "tinyint unsigned"),
UtilsTools.ConstructTDengineMeta("u2", "smallint unsigned"),
UtilsTools.ConstructTDengineMeta("u4", "int unsigned"),
UtilsTools.ConstructTDengineMeta("u8", "bigint unsigned"),
UtilsTools.ConstructTDengineMeta("bin", "binary(200)"),
UtilsTools.ConstructTDengineMeta("blob", "nchar(200)"),
UtilsTools.ConstructTDengineMeta("jsontag", "json"),
};
var expectResData = new List<String> { "1637064040000", "true", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "XI", "XII", "{\"k1\": \"v1\"}" };
String dropTb = "drop table if exists " + tableName;
String createTb = "create stable " + tableName
+ " (ts timestamp" +
",b bool" +
",v1 tinyint" +
",v2 smallint" +
",v4 int" +
",v8 bigint" +
",f4 float" +
",f8 double" +
",u1 tinyint unsigned" +
",u2 smallint unsigned" +
",u4 int unsigned" +
",u8 bigint unsigned" +
",bin binary(200)" +
",blob nchar(200)" +
")" +
"tags" +
"(jsontag json);";
String insertSql = "insert into " + tableName + "_t1 using " + tableName +
" tags('{\"k1\": \"v1\"}') " +
"values(1637064040000,true,1,2,3,4,5,6,7,8,9,10,'XI','XII')";
String selectSql = "select * from " + tableName;
String dropSql = "drop table " + tableName;
UtilsTools.ExecuteUpdate(conn, dropTb);
UtilsTools.ExecuteUpdate(conn, createTb);
UtilsTools.ExecuteUpdate(conn, insertSql);
_res = UtilsTools.ExecuteQuery(conn, selectSql);
ResultSet actualResult = new ResultSet(_res);
List<TDengineMeta> actualMeta = actualResult.GetResultMeta();
for (int i = 0; i < actualMeta.Count; i++)
{
Assert.Equal(expectResMeta[i].name, actualMeta[i].name);
Assert.Equal(expectResMeta[i].type, actualMeta[i].type);
Assert.Equal(expectResMeta[i].size, actualMeta[i].size);
}
}
}
}
......@@ -13,6 +13,7 @@ namespace Test.UtilsTools
static string password = "taosdata";
static string db = "";
static short port = 0;
//get a tdengine connection
public static IntPtr TDConnection()
{
TDengine.Options((int)TDengineInitOption.TDDB_OPTION_CONFIGDIR, GetConfigPath());
......@@ -24,6 +25,7 @@ namespace Test.UtilsTools
UtilsTools.ExecuteUpdate(conn, "use csharp");
return conn;
}
//get taos.cfg file based on different os
public static string GetConfigPath()
{
string configDir = "" ;
......@@ -340,7 +342,8 @@ namespace Test.UtilsTools
dataRaw.Add(v7.ToString());
break;
case TDengineDataType.TSDB_DATA_TYPE_BINARY:
string v8 = Marshal.PtrToStringAnsi(data, colLengthArr[fields]);
// string v8 = Marshal.PtrToStringAnsi(data, colLengthArr[fields]);
string v8 = Marshal.PtrToStringUTF8(data, colLengthArr[fields]);
dataRaw.Add(v8);
break;
case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP:
......@@ -348,7 +351,8 @@ namespace Test.UtilsTools
dataRaw.Add(v9.ToString());
break;
case TDengineDataType.TSDB_DATA_TYPE_NCHAR:
string v10 = Marshal.PtrToStringAnsi(data, colLengthArr[fields]);
// string v10 = Marshal.PtrToStringAnsi(data, colLengthArr[fields]);
string v10 = Marshal.PtrToStringUTF8(data, colLengthArr[fields]);
dataRaw.Add(v10);
break;
case TDengineDataType.TSDB_DATA_TYPE_UTINYINT:
......@@ -383,6 +387,89 @@ namespace Test.UtilsTools
return dataRaw;
}
// Generate insert sql for the with the coldata and tag data
public static string ConstructInsertSql(string table,string stable,List<Object> colData,List<Object> tagData,int numOfRows)
{
int numofFileds = colData.Count / numOfRows;
StringBuilder insertSql;
if (stable == "")
{
insertSql = new StringBuilder($"insert into {table} values(");
}
else
{
insertSql = new StringBuilder($"insert into {table} using {stable} tags(");
for (int j = 0; j < tagData.Count; j++)
{
if (tagData[j] is String)
{
insertSql.Append('\'');
insertSql.Append(tagData[j]);
insertSql.Append('\'');
}
else
{
insertSql.Append(tagData[j]);
}
if (j + 1 != tagData.Count)
{
insertSql.Append(',');
}
}
insertSql.Append(")values(");
}
for (int i = 0; i < colData.Count; i++)
{
if (colData[i] is String)
{
insertSql.Append('\'');
insertSql.Append(colData[i]);
insertSql.Append('\'');
}
else
{
insertSql.Append(colData[i]);
}
if ((i + 1) % numofFileds == 0 && (i + 1) != colData.Count)
{
insertSql.Append(")(");
}
else if ((i + 1) == colData.Count)
{
insertSql.Append(')');
}
else
{
insertSql.Append(',');
}
}
insertSql.Append(';');
//Console.WriteLine(insertSql.ToString());
return insertSql.ToString();
}
public static List<object> CombineColAndTagData(List<object> colData,List<object> tagData, int numOfRows)
{
var list = new List<Object>();
for (int i = 0; i < colData.Count; i++)
{
list.Add(colData[i]);
if ((i + 1) % (colData.Count / numOfRows) == 0)
{
for (int j = 0; j < tagData.Count; j++)
{
list.Add(tagData[j]);
}
}
}
return list;
}
}
}
......@@ -763,12 +763,12 @@ namespace TDengineDriver.Test
{
int bufferType = 8;
String buffer = "qwertyuiopasdghjklzxcvbnm<>?:\"{}+_)(*&^%$#@!~QWERTYUIOP[]\\ASDFGHJKL;'ZXCVBNM,./`1234567890-=";
int bufferLength = System.Text.Encoding.Default.GetBytes(buffer).Length;
int length = System.Text.Encoding.Default.GetBytes(buffer).Length;
int bufferLength = System.Text.Encoding.UTF8.GetBytes(buffer).Length;
int length = System.Text.Encoding.UTF8.GetBytes(buffer).Length;
TDengineDriver.TAOS_BIND bind = TaosBind.BindBinary("qwertyuiopasdghjklzxcvbnm<>?:\"{}+_)(*&^%$#@!~QWERTYUIOP[]\\ASDFGHJKL;'ZXCVBNM,./`1234567890-=");
int BindLengPtr = Marshal.ReadInt32(bind.length);
string bindBuffer = Marshal.PtrToStringAnsi(bind.buffer);
string bindBuffer = Marshal.PtrToStringUTF8(bind.buffer);
Assert.Equal(bind.buffer_type, bufferType);
Assert.Equal(bindBuffer, buffer);
......@@ -789,12 +789,12 @@ namespace TDengineDriver.Test
{
int bufferType = 8;
String buffer = "一二两三四五六七八九十廿毛另壹贰叁肆伍陆柒捌玖拾佰仟万亿元角分零整1234567890`~!@#$%^&*()_+[]{};':<>?,./";
int bufferLength = System.Text.Encoding.Default.GetBytes(buffer).Length;
int length = System.Text.Encoding.Default.GetBytes(buffer).Length;
int bufferLength = System.Text.Encoding.UTF8.GetBytes(buffer).Length;
int length = System.Text.Encoding.UTF8.GetBytes(buffer).Length;
TDengineDriver.TAOS_BIND bind = TaosBind.BindBinary("一二两三四五六七八九十廿毛另壹贰叁肆伍陆柒捌玖拾佰仟万亿元角分零整1234567890`~!@#$%^&*()_+[]{};':<>?,./");
int BindLengPtr = Marshal.ReadInt32(bind.length);
string bindBuffer = Marshal.PtrToStringAnsi(bind.buffer);
string bindBuffer = Marshal.PtrToStringUTF8(bind.buffer);
Assert.Equal(bind.buffer_type, bufferType);
Assert.Equal(bindBuffer, buffer);
......@@ -815,12 +815,12 @@ namespace TDengineDriver.Test
{
int bufferType = 8;
String buffer = "一二两三四五六七八九十廿毛另壹贰叁肆伍陆柒捌玖拾佰仟万亿元角分零整1234567890`~!@#$%^&*()_+[]{};':<>?,./qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM";
int bufferLength = System.Text.Encoding.Default.GetBytes(buffer).Length;
int length = System.Text.Encoding.Default.GetBytes(buffer).Length;
int bufferLength = System.Text.Encoding.UTF8.GetBytes(buffer).Length;
int length = System.Text.Encoding.UTF8.GetBytes(buffer).Length;
TDengineDriver.TAOS_BIND bind = TaosBind.BindBinary("一二两三四五六七八九十廿毛另壹贰叁肆伍陆柒捌玖拾佰仟万亿元角分零整1234567890`~!@#$%^&*()_+[]{};':<>?,./qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM");
int BindLengPtr = Marshal.ReadInt32(bind.length);
string bindBuffer = Marshal.PtrToStringAnsi(bind.buffer);
string bindBuffer = Marshal.PtrToStringUTF8(bind.buffer);
Assert.Equal(bind.buffer_type, bufferType);
Assert.Equal(bindBuffer, buffer);
......@@ -841,12 +841,12 @@ namespace TDengineDriver.Test
{
int bufferType = 10;
String buffer = "qwertyuiopasdghjklzxcvbnm<>?:\"{}+_)(*&^%$#@!~QWERTYUIOP[]\\ASDFGHJKL;'ZXCVBNM,./`1234567890-=";
int bufferLength = System.Text.Encoding.Default.GetBytes(buffer).Length;
int length = System.Text.Encoding.Default.GetBytes(buffer).Length;
int bufferLength = System.Text.Encoding.UTF8.GetBytes(buffer).Length;
int length = System.Text.Encoding.UTF8.GetBytes(buffer).Length;
TDengineDriver.TAOS_BIND bind = TaosBind.BindNchar("qwertyuiopasdghjklzxcvbnm<>?:\"{}+_)(*&^%$#@!~QWERTYUIOP[]\\ASDFGHJKL;'ZXCVBNM,./`1234567890-=");
int BindLengPtr = Marshal.ReadInt32(bind.length);
string bindBuffer = Marshal.PtrToStringAnsi(bind.buffer);
string bindBuffer = Marshal.PtrToStringUTF8(bind.buffer);
Assert.Equal(bind.buffer_type, bufferType);
Assert.Equal(bindBuffer, buffer);
......@@ -867,12 +867,12 @@ namespace TDengineDriver.Test
{
int bufferType = 10;
String buffer = "一二两三四五六七八九十廿毛另壹贰叁肆伍陆柒捌玖拾佰仟万亿元角分零整1234567890`~!@#$%^&*()_+[]{};':<>?,./";
int bufferLength = System.Text.Encoding.Default.GetBytes(buffer).Length;
int length = System.Text.Encoding.Default.GetBytes(buffer).Length;
int bufferLength = System.Text.Encoding.UTF8.GetBytes(buffer).Length;
int length = System.Text.Encoding.UTF8.GetBytes(buffer).Length;
TDengineDriver.TAOS_BIND bind = TaosBind.BindNchar("一二两三四五六七八九十廿毛另壹贰叁肆伍陆柒捌玖拾佰仟万亿元角分零整1234567890`~!@#$%^&*()_+[]{};':<>?,./");
int BindLengPtr = Marshal.ReadInt32(bind.length);
string bindBuffer = Marshal.PtrToStringAnsi(bind.buffer);
string bindBuffer = Marshal.PtrToStringUTF8(bind.buffer);
Assert.Equal(bind.buffer_type, bufferType);
Assert.Equal(bindBuffer, buffer);
......@@ -893,12 +893,12 @@ namespace TDengineDriver.Test
{
int bufferType = 10;
String buffer = "一二两三四五六七八九十廿毛另壹贰叁肆伍陆柒捌玖拾佰仟万亿元角分零整1234567890`~!@#$%^&*()_+[]{};':<>?,./qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM";
int bufferLength = System.Text.Encoding.Default.GetBytes(buffer).Length;
int length = System.Text.Encoding.Default.GetBytes(buffer).Length;
int bufferLength = System.Text.Encoding.UTF8.GetBytes(buffer).Length;
int length = System.Text.Encoding.UTF8.GetBytes(buffer).Length;
TDengineDriver.TAOS_BIND bind = TaosBind.BindNchar("一二两三四五六七八九十廿毛另壹贰叁肆伍陆柒捌玖拾佰仟万亿元角分零整1234567890`~!@#$%^&*()_+[]{};':<>?,./qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM");
int BindLengPtr = Marshal.ReadInt32(bind.length);
string bindBuffer = Marshal.PtrToStringAnsi(bind.buffer);
string bindBuffer = Marshal.PtrToStringUTF8(bind.buffer);
Assert.Equal(bind.buffer_type, bufferType);
Assert.Equal(bindBuffer, buffer);
......
......@@ -13,3 +13,5 @@ taosdemo/bin/
taosdemo/obj/
jsonTag/bin/
jsonTag/obj/
insertCn/bin/
insertCn/obj/
\ No newline at end of file
using System;
using Test.UtilsTools;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using Test.UtilsTools.ResultSet;
namespace insertCn
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
IntPtr conn = UtilsTools.TDConnection();
string dbName = "insert_cn_to_nchar_sample_dotnet";
string createDB = $"create database if not exists {dbName};";
string dropDB = $"drop database if exists {dbName};";
string useDB = $"use {dbName};";
string table = "t1";
string stable = "stb";
UtilsTools.ExecuteUpdate(conn,createDB);
UtilsTools.ExecuteUpdate(conn,useDB);
Console.WriteLine("=====================ntable====================");
TestNtable(conn,table);
Console.WriteLine("=====================stable====================");
TestStable(conn,stable);
UtilsTools.ExecuteUpdate(conn,dropDB);
UtilsTools.CloseConnection(conn);
}
static void TestStable(IntPtr conn,string stable)
{
string createSql = $"create table if not exists {stable} (ts timestamp," +
$"v4 int," +
$"blob nchar(200)," +
$"locate nchar(200)," +
$"country binary(200)," +
$"city binary(50)" +
$")tags(" +
$"id int," +
$"name nchar(50)," +
$"addr nchar(200)," +
$"en_name binary(200));";
String dropTb = "drop table if exists " + stable;
String table = stable + "_subtable_1";
var colData = new List<Object>{1637064040000,1,"涛思数据","保利广场","Beijing","China",
1637064041000,2,"涛思数据taosdata","保利广场baoli","Beijing","China",
1637064042000,3,"TDegnine涛思数据","time广场","NewYork","US",
1637064043000,4,"4涛思数据","4广场南部","London","UK",
1637064044000,5,"涛思数据5","!广场路中部123","Tokyo","JP",
1637064045000,6,"taos涛思数据6","青年广场123号!","Washin","DC",
1637064046000,7,"7涛思数据taos","asdf#壮年广场%#endregion","NewYork","US",
1637064047000,8,"8&涛思数据taos","incluse阿斯顿发","NewYork","US",
1637064048000,9,"&涛思数据taos9","123黑化肥werq会挥……&¥%发!afsdfa","NewYork","US",
};
var tagData = new List<Object>{1,"涛思数据","中国北方&南方长江黄河!49wq","tdengine"};
string insertSql = UtilsTools.ConstructInsertSql(table, stable, colData, tagData, 9);
string selectSql = $"select * from {stable};";
List<Object> insertData = UtilsTools.CombineColAndTagData(colData,tagData,9);
UtilsTools.ExecuteUpdate(conn,dropTb);
UtilsTools.ExecuteUpdate(conn,createSql);
UtilsTools.ExecuteUpdate(conn,insertSql);
IntPtr res = UtilsTools.ExecuteQuery(conn,selectSql);
ResultSet resultSet = new ResultSet(res);
List<Object> queryResult = resultSet.GetResultData();
//display
int fieldsCount = resultSet.GetFieldsNum();
for(int i = 0 ; i<queryResult.Count;i++){
Console.Write(queryResult[i].ToString());
Console.Write("\t");
if((i+1)%fieldsCount == 0)
{
Console.WriteLine("");
}
}
if(insertData.Count == queryResult.Count)
{
Console.WriteLine("insert data count = retrieve data count");
for(int i = 0 ; i<queryResult.Count;i++)
{
if(!queryResult[i].Equals(insertData[i]))
{
Console.Write("[Unequal Data]");
Console.WriteLine("InsertData:{0},QueryData:{1}",queryResult[i],insertData[i]);
}
}
}
}
static void TestNtable(IntPtr conn,string tableName)
{
var colData = new List<Object>{1637064040000,1,"涛思数据","保利广场","Beijing","China",
1637064041000,2,"涛思数据taosdata","保利广场baoli","Beijing","China",
1637064042000,3,"TDegnine涛思数据","time广场","NewYork","US",
1637064043000,4,"4涛思数据","4广场南部","London","UK",
1637064044000,5,"涛思数据5","!广场路中部123","Tokyo","JP",
1637064045000,6,"taos涛思数据6","青年广场123号!","Washin","DC",
1637064046000,7,"7涛思数据taos","asdf#壮年广场%#endregion","NewYork","US",
1637064047000,8,"8&涛思数据taos","incluse阿斯顿发","NewYork","US",
1637064048000,9,"&涛思数据taos9","123黑化肥werq会挥……&¥%发!afsdfa","NewYork","US",
};
String dropTb = "drop table if exists " + tableName;
String createTb = $"create table if not exists {tableName} (ts timestamp,v4 int,blob nchar(200),location nchar(200),city binary(100),coutry nchar(200));";
String insertSql = UtilsTools.ConstructInsertSql(tableName, "", colData, null, 9);
String selectSql = "select * from " + tableName;
UtilsTools.ExecuteUpdate(conn, dropTb);
UtilsTools.ExecuteUpdate(conn, createTb);
UtilsTools.ExecuteUpdate(conn, insertSql);
IntPtr res = UtilsTools.ExecuteQuery(conn, selectSql);
ResultSet resultSet = new ResultSet(res);
List<Object> queryResult = resultSet.GetResultData();
int fieldsCount = resultSet.GetFieldsNum();
//display
for(int i = 0 ; i<queryResult.Count;i++){
Console.Write(queryResult[i].ToString());
Console.Write("\t");
if((i+1)%fieldsCount == 0)
{
Console.WriteLine("");
}
}
if(colData.Count == queryResult.Count)
{
Console.WriteLine("insert data count = retrieve data count");
for(int i = 0 ; i<queryResult.Count;i++)
{
if(!queryResult[i].Equals(colData[i]))
{
Console.Write("[Unequal Data]");
Console.WriteLine("InsertData:{0},QueryData:{1}",queryResult[i],colData[i]);
}
}
}
}
}
}
/*
* 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
{
public 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
TSDB_DATA_TYPE_JSONTAG = 15 //4096 bytes
}
public enum TDengineInitOption
{
TSDB_OPTION_LOCALE = 0,
TSDB_OPTION_CHARSET = 1,
TSDB_OPTION_TIMEZONE = 2,
TDDB_OPTION_CONFIGDIR = 3,
TDDB_OPTION_SHELL_ACTIVITY_TIMER = 4
}
enum TaosField
{
STRUCT_SIZE = 68,
NAME_LENGTH = 65,
TYPE_OFFSET = 65,
BYTES_OFFSET = 66,
}
public 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 "BINARY";
case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP:
return "TIMESTAMP";
case TDengineDataType.TSDB_DATA_TYPE_NCHAR:
return "NCHAR";
case TDengineDataType.TSDB_DATA_TYPE_JSONTAG:
return "JSON";
default:
return "undefine";
}
}
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct TAOS_BIND
{
// column type
public int buffer_type;
// one column value
public IntPtr buffer;
// unused
public Int32 buffer_length;
// actual value length in buffer
public IntPtr length;
// indicates the column value is null or not
public IntPtr is_null;
// unused
public int is_unsigned;
// unused
public IntPtr error;
public Int64 u;
public uint allocated;
}
[StructLayout(LayoutKind.Sequential)]
public struct TAOS_MULTI_BIND
{
// column type
public int buffer_type;
// array, one or more lines column value
public IntPtr buffer;
//length of element in TAOS_MULTI_BIND.buffer (for binary and nchar it is the longest element's length)
public ulong buffer_length;
//array, actual data length for each value
public IntPtr length;
//array, indicates each column value is null or not
public IntPtr is_null;
// line number, or the values number in buffer
public int num;
}
public 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);
static extern private IntPtr Query(IntPtr conn, IntPtr byteArr);
static public IntPtr Query(IntPtr conn,string command)
{
IntPtr res = IntPtr.Zero;
IntPtr commandBuffer = Marshal.StringToCoTaskMemUTF8(command);
res = Query(conn,commandBuffer);
return res;
}
[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 * (int)TaosField.STRUCT_SIZE;
TDengineMeta meta = new TDengineMeta();
meta.name = Marshal.PtrToStringAnsi(fieldsPtr + offset);
meta.type = Marshal.ReadByte(fieldsPtr + offset + (int)TaosField.TYPE_OFFSET);
meta.size = Marshal.ReadInt16(fieldsPtr + offset + (int)TaosField.BYTES_OFFSET);
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 of restultset
[DllImport("taos", EntryPoint = "taos_result_precision", CallingConvention = CallingConvention.Cdecl)]
static extern public int ResultPrecision(IntPtr taos);
//stmt APIs:
/// <summary>
/// init a TAOS_STMT object for later use.
/// </summary>
/// <param name="taos">a valid taos connection</param>
/// <returns>
/// Not NULL returned for success, NULL for failure. And it should be freed with taos_stmt_close.
/// </returns>
[DllImport("taos", EntryPoint = "taos_stmt_init", CallingConvention = CallingConvention.Cdecl)]
static extern public IntPtr StmtInit(IntPtr taos);
/// <summary>
/// prepare a sql statement,'sql' should be a valid INSERT/SELECT statement.
/// </summary>
/// <param name="stmt">could be the value returned by 'StmtInit', that may be a valid object or NULL.</param>
/// <param name="sql">sql string,used to bind parameters with</param>
/// <param name="length">no used</param>
/// <returns>0 for success, non-zero for failure.</returns>
[DllImport("taos", EntryPoint = "taos_stmt_prepare", CallingConvention = CallingConvention.Cdecl)]
static extern public int StmtPrepare(IntPtr stmt, string sql);
/// <summary>
/// For INSERT only. Used to bind table name as a parmeter for the input stmt object.
/// </summary>
/// <param name="stmt">could be the value returned by 'StmtInit', that may be a valid object or NULL.</param>
/// <param name="name">table name you want to bind</param>
/// <returns>0 for success, non-zero for failure.</returns>
[DllImport("taos", EntryPoint = "taos_stmt_set_tbname", CallingConvention = CallingConvention.Cdecl)]
static extern public int StmtSetTbname(IntPtr stmt, string name);
/// <summary>
/// For INSERT only.
/// Set a table name for binding table name as parameter. Only used for binding all tables
/// in one stable, user application must call 'loadTableInfo' API to load all table
/// meta before calling this API. If the table meta is not cached locally, it will return error.
/// </summary>
/// <param name="stmt">could be the value returned by 'StmtInit', that may be a valid object or NULL.</param>
/// <param name="name">table name which is belong to an stable</param>
/// <returns>0 for success, non-zero for failure.</returns>
[DllImport("taos", EntryPoint = "taos_stmt_set_sub_tbname", CallingConvention = CallingConvention.Cdecl)]
static extern public int StmtSetSubTbname(IntPtr stmt, string name);
/// <summary>
/// For INSERT only.
/// set a table name for binding table name as parameter and tag values for all tag parameters.
/// </summary>
/// <param name="stmt">could be the value returned by 'StmtInit', that may be a valid object or NULL.</param>
/// <param name="name">use to set table name</param>
/// <param name="tags">
/// is an array contains all tag values,each item in the array represents a tag column's value.
/// the item number and sequence should keep consistence with that in stable tag definition.
/// </param>
/// <returns>0 for success, non-zero for failure.</returns>
[DllImport("taos", EntryPoint = "taos_stmt_set_tbname_tags", CallingConvention = CallingConvention.Cdecl)]
static extern public int StmtSetTbnameTags(IntPtr stmt, string name, TAOS_BIND[] tags);
/// <summary>
/// For both INSERT and SELECT.
/// bind a whole line data.
/// The usage of structure TAOS_BIND is the same with MYSQL_BIND in MySQL.
/// </summary>
/// <param name="stmt">could be the value returned by 'StmtInit', that may be a valid object or NULL.</param>
/// <param name="bind">
/// points to an array contains the whole line data.
/// the item number and sequence should keep consistence with columns in sql statement.
/// </param>
/// <returns>0 for success, non-zero for failure.</returns>
[DllImport("taos", EntryPoint = "taos_stmt_bind_param", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
static extern public int StmtBindParam(IntPtr stmt, TAOS_BIND[] bind);
/// <summary>
/// bind a single column's data, INTERNAL used and for INSERT only.
/// </summary>
/// <param name="stmt">could be the value returned by 'StmtInit', that may be a valid object or NULL.</param>
/// <param name="bind">points to a column's data which could be the one or more lines. </param>
/// <param name="colIdx">the column's index in prepared sql statement, it starts from 0.</param>
/// <returns>0 for success, non-zero for failure.</returns>
[DllImport("taos", EntryPoint = "taos_stmt_bind_single_param_batch", CallingConvention = CallingConvention.Cdecl)]
static extern public int StmtBindSingleParamBatch(IntPtr stmt, ref TAOS_MULTI_BIND bind, int colIdx);
/// <summary>
/// for INSERT only
/// bind one or multiple lines data. The parameter 'bind'
/// </summary>
/// <param name="stmt">could be the value returned by 'StmtInit', that may be a valid object or NULL.</param>
/// <param name="bind">
/// points to an array contains one or more lines data.Each item in array represents a column's value(s),
/// the item number and sequence should keep consistence with columns in sql statement.
/// </param>
/// <returns>0 for success, non-zero for failure.</returns>
[DllImport("taos", EntryPoint = "taos_stmt_bind_param_batch", CallingConvention = CallingConvention.Cdecl)]
static extern public int StmtBindParamBatch(IntPtr stmt, [In, Out] TAOS_MULTI_BIND[] bind);
/// <summary>
/// For INSERT only.
/// add all current bound parameters to batch process. Must be called after each call to
/// StmtBindParam/StmtBindSingleParamBatch, or all columns binds for one or more lines
/// with StmtBindSingleParamBatch. User application can call any bind parameter
/// API again to bind more data lines after calling to this API.
/// </summary>
/// <param name="stmt">could be the value returned by 'StmtInit', that may be a valid object or NULL.</param>
/// <returns>0 for success, non-zero for failure.</returns>
[DllImport("taos", EntryPoint = "taos_stmt_add_batch", CallingConvention = CallingConvention.Cdecl)]
static extern public int StmtAddBatch(IntPtr stmt);
/// <summary>
/// actually execute the INSERT/SELECT sql statement.
/// User application can continue to bind new data after calling to this API.
/// </summary>
/// <param name="stmt">could be the value returned by 'StmtInit', that may be a valid object or NULL.</param>
/// <returns></returns>
[DllImport("taos", EntryPoint = "taos_stmt_execute", CallingConvention = CallingConvention.Cdecl)]
static extern public int StmtExecute(IntPtr stmt);
/// <summary>
/// For SELECT only,getting the query result. User application should free it with API 'FreeResult' at the end.
/// </summary>
/// <param name="stmt">could be the value returned by 'StmtInit', that may be a valid object or NULL.</param>
/// <returns>Not NULL for success, NULL for failure.</returns>
[DllImport("taos", EntryPoint = "taos_stmt_use_result", CallingConvention = CallingConvention.Cdecl)]
static extern public IntPtr StmtUseResult(IntPtr stmt);
/// <summary>
/// close STMT object and free resources.
/// </summary>
/// <param name="stmt">could be the value returned by 'StmtInit', that may be a valid object or NULL.</param>
/// <returns>0 for success, non-zero for failure.</returns>
[DllImport("taos", EntryPoint = "taos_stmt_close", CallingConvention = CallingConvention.Cdecl)]
static extern public int StmtClose(IntPtr stmt);
[DllImport("taos", EntryPoint = "taos_load_table_info", CallingConvention = CallingConvention.Cdecl)]
/// <summary>
/// user application must call this API to load all tables meta,
/// </summary>
/// <param name="taos">taos connection</param>
/// <param name="tableList">tablelist</param>
/// <returns></returns>
static extern private int LoadTableInfoDll(IntPtr taos, string tableList);
/// <summary>
/// user application call this API to load all tables meta,this method call the native
/// method LoadTableInfoDll.
/// this method must be called before StmtSetSubTbname(IntPtr stmt, string name);
/// </summary>
/// <param name="taos">taos connection</param>
/// <param name="tableList">tables need to load meta info are form in an array</param>
/// <returns></returns>
static public int LoadTableInfo(IntPtr taos, string[] tableList)
{
string listStr = string.Join(",", tableList);
return LoadTableInfoDll(taos, listStr);
}
/// <summary>
/// get detail error message when got failure for any stmt API call. If not failure, the result
/// returned in this API is unknown.
/// </summary>
/// <param name="stmt">could be the value returned by 'StmtInit', that may be a valid object or NULL.</param>
/// <returns>piont the error message</returns>
[DllImport("taos", EntryPoint = "taos_stmt_errstr", CallingConvention = CallingConvention.Cdecl)]
static extern private IntPtr StmtErrPtr(IntPtr stmt);
/// <summary>
/// get detail error message when got failure for any stmt API call. If not failure, the result
/// returned in this API is unknown.
/// </summary>
/// <param name="stmt">could be the value returned by 'StmtInit', that may be a valid object or NULL.</param>
/// <returns>error string</returns>
static public string StmtErrorStr(IntPtr stmt)
{
IntPtr stmtErrPrt = StmtErrPtr(stmt);
return Marshal.PtrToStringAnsi(stmtErrPrt);
}
[DllImport("taos", EntryPoint = "taos_fetch_lengths", CallingConvention = CallingConvention.Cdecl)]
static extern public IntPtr FetchLengths(IntPtr taos);
}
}
<Project Sdk="Microsoft.NET.Sdk">
<!-- <ItemGroup>
<ProjectReference Include="..\src\TDengineDriver\TDengineDriver.csproj" />
</ItemGroup> -->
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
</Project>
using System;
using TDengineDriver;
using System.Runtime.InteropServices;
using System.Text;
using System.Collections.Generic;
namespace Test.UtilsTools.ResultSet
{
public class ResultSet
{
private List<TDengineMeta> resultMeta;
private List<Object> resultData;
// private bool isValidResult = false;
public ResultSet(IntPtr res)
{
resultMeta = UtilsTools.GetResField(res);
resultData = UtilsTools.GetResData(res);
}
public ResultSet(List<TDengineMeta> metas, List<Object> datas)
{
resultMeta = metas;
resultData = datas;
}
public List<Object> GetResultData()
{
return resultData;
}
public List<TDengineMeta> GetResultMeta()
{
return resultMeta;
}
public int GetFieldsNum()
{
return resultMeta.Count;
}
}
}
\ No newline at end of file
using System;
using TDengineDriver;
using System.Runtime.InteropServices;
using System.Text;
using System.Collections.Generic;
namespace Test.UtilsTools
{
public class UtilsTools
{
static string ip = "127.0.0.1";
static string user = "root";
static string password = "taosdata";
static string db = "";
static short port = 0;
//get a tdengine connection
public static IntPtr TDConnection()
{
TDengine.Options((int)TDengineInitOption.TDDB_OPTION_CONFIGDIR, GetConfigPath());
TDengine.Options((int)TDengineInitOption.TDDB_OPTION_SHELL_ACTIVITY_TIMER, "60");
TDengine.Init();
IntPtr conn = TDengine.Connect(ip, user, password, db, port);
return conn;
}
//get taos.cfg file based on different os
public static string GetConfigPath()
{
string configDir = "" ;
if(OperatingSystem.IsOSPlatform("Windows"))
{
configDir = "C:/TDengine/cfg";
}
else if(OperatingSystem.IsOSPlatform("Linux"))
{
configDir = "/etc/taos";
}
else if(OperatingSystem.IsOSPlatform("macOS"))
{
configDir = "/etc/taos";
}
return configDir;
}
public static IntPtr ExecuteQuery(IntPtr conn, String sql)
{
IntPtr res = TDengine.Query(conn, sql);
if (!IsValidResult(res))
{
Console.Write(sql.ToString() + " failure, ");
ExitProgram();
}
else
{
Console.WriteLine(sql.ToString() + " success");
}
return res;
}
public static IntPtr ExecuteErrorQuery(IntPtr conn, String sql)
{
IntPtr res = TDengine.Query(conn, sql);
if (!IsValidResult(res))
{
Console.Write(sql.ToString() + " failure, ");
ExitProgram();
}
else
{
Console.WriteLine(sql.ToString() + " success");
}
return res;
}
public static void ExecuteUpdate(IntPtr conn, String sql)
{
IntPtr res = TDengine.Query(conn, sql);
if (!IsValidResult(res))
{
Console.Write(sql.ToString() + " failure, ");
ExitProgram();
}
else
{
Console.WriteLine(sql.ToString() + " success");
}
TDengine.FreeResult(res);
}
// public static List<List<string>> GetResultSet(IntPtr res)
// {
// List<List<string>> result = new List<List<string>>();
// List<string> colName = new List<string>();
// List<Object> dataRaw = new List<Object>();
// if (!IsValidResult(res))
// {
// ExitProgram();
// }
// List<TDengineMeta> metas = GetResField(res);
// result.Add(colName);
// dataRaw = QueryRes(res, metas);
// result.Add(dataRaw);
// if (TDengine.ErrorNo(res) != 0)
// {
// Console.Write("Query is not complete, Error {0:G}", TDengine.ErrorNo(res), TDengine.Error(res));
// }
// return result;
// }
public static bool IsValidResult(IntPtr res)
{
if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0))
{
if (res != IntPtr.Zero)
{
Console.Write("reason: " + TDengine.Error(res));
return false;
}
Console.WriteLine("");
return false;
}
return true;
}
public static void CloseConnection(IntPtr conn)
{
if (conn != IntPtr.Zero)
{
if (TDengine.Close(conn) == 0)
{
Console.WriteLine("close connection sucess");
}
else
{
Console.WriteLine("close Connection failed");
}
}
TDengine.Cleanup();
}
public static List<TDengineMeta> GetResField(IntPtr res)
{
List<TDengineMeta> metas = TDengine.FetchFields(res);
return metas;
}
public static void AssertEqual(string expectVal, string actualVal)
{
if (expectVal == actualVal)
{
Console.WriteLine("{0}=={1} pass", expectVal, actualVal);
}
else
{
Console.WriteLine("{0}=={1} failed", expectVal, actualVal);
ExitProgram();
}
}
public static void ExitProgram()
{
TDengine.Cleanup();
System.Environment.Exit(0);
}
public static List<Object> GetResData(IntPtr res)
{
List<Object> dataRaw = new List<Object>();
if (!IsValidResult(res))
{
ExitProgram();
}
List<TDengineMeta> metas = GetResField(res);
dataRaw = QueryRes(res, metas);
return dataRaw;
}
public static TDengineMeta ConstructTDengineMeta(string name, string type)
{
TDengineMeta _meta = new TDengineMeta();
_meta.name = name;
char[] separators = new char[] { '(', ')' };
string[] subs = type.Split(separators, StringSplitOptions.RemoveEmptyEntries);
switch (subs[0].ToUpper())
{
case "BOOL":
_meta.type = 1;
_meta.size = 1;
break;
case "TINYINT":
_meta.type = 2;
_meta.size = 1;
break;
case "SMALLINT":
_meta.type = 3;
_meta.size = 2;
break;
case "INT":
_meta.type = 4;
_meta.size = 4;
break;
case "BIGINT":
_meta.type = 5;
_meta.size = 8;
break;
case "TINYINT UNSIGNED":
_meta.type = 11;
_meta.size = 1;
break;
case "SMALLINT UNSIGNED":
_meta.type = 12;
_meta.size = 2;
break;
case "INT UNSIGNED":
_meta.type = 13;
_meta.size = 4;
break;
case "BIGINT UNSIGNED":
_meta.type = 14;
_meta.size = 8;
break;
case "FLOAT":
_meta.type = 6;
_meta.size = 4;
break;
case "DOUBLE":
_meta.type = 7;
_meta.size = 8;
break;
case "BINARY":
_meta.type = 8;
_meta.size = short.Parse(subs[1]);
break;
case "TIMESTAMP":
_meta.type = 9;
_meta.size = 8;
break;
case "NCHAR":
_meta.type = 10;
_meta.size = short.Parse(subs[1]);
break;
case "JSON":
_meta.type = 15;
_meta.size = 4096;
break;
default:
_meta.type = byte.MaxValue;
_meta.size = 0;
break;
}
return _meta;
}
private static List<Object> QueryRes(IntPtr res, List<TDengineMeta> metas)
{
IntPtr rowdata;
long queryRows = 0;
List<Object> dataRaw = new List<Object>();
int fieldCount = metas.Count;
while ((rowdata = TDengine.FetchRows(res)) != IntPtr.Zero)
{
queryRows++;
IntPtr colLengthPtr = TDengine.FetchLengths(res);
int[] colLengthArr = new int[fieldCount];
Marshal.Copy(colLengthPtr, colLengthArr, 0, fieldCount);
for (int fields = 0; fields < fieldCount; ++fields)
{
TDengineMeta meta = metas[fields];
int offset = IntPtr.Size * fields;
IntPtr data = Marshal.ReadIntPtr(rowdata, offset);
if (data == IntPtr.Zero)
{
dataRaw.Add("NULL");
continue;
}
switch ((TDengineDataType)meta.type)
{
case TDengineDataType.TSDB_DATA_TYPE_BOOL:
bool v1 = Marshal.ReadByte(data) == 0 ? false : true;
dataRaw.Add(v1);
break;
case TDengineDataType.TSDB_DATA_TYPE_TINYINT:
sbyte v2 = (sbyte)Marshal.ReadByte(data);
dataRaw.Add(v2);
break;
case TDengineDataType.TSDB_DATA_TYPE_SMALLINT:
short v3 = Marshal.ReadInt16(data);
dataRaw.Add(v3);
break;
case TDengineDataType.TSDB_DATA_TYPE_INT:
int v4 = Marshal.ReadInt32(data);
dataRaw.Add(v4);
break;
case TDengineDataType.TSDB_DATA_TYPE_BIGINT:
long v5 = Marshal.ReadInt64(data);
dataRaw.Add(v5);
break;
case TDengineDataType.TSDB_DATA_TYPE_FLOAT:
float v6 = (float)Marshal.PtrToStructure(data, typeof(float));
dataRaw.Add(v6);
break;
case TDengineDataType.TSDB_DATA_TYPE_DOUBLE:
double v7 = (double)Marshal.PtrToStructure(data, typeof(double));
dataRaw.Add(v7);
break;
case TDengineDataType.TSDB_DATA_TYPE_BINARY:
// string v8 = Marshal.PtrToStringAnsi(data, colLengthArr[fields]);
string v8 = Marshal.PtrToStringUTF8(data, colLengthArr[fields]);
dataRaw.Add(v8);
break;
case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP:
long v9 = Marshal.ReadInt64(data);
dataRaw.Add(v9);
break;
case TDengineDataType.TSDB_DATA_TYPE_NCHAR:
// string v10 = Marshal.PtrToStringAnsi(data, colLengthArr[fields]);
string v10 = Marshal.PtrToStringUTF8(data, colLengthArr[fields]);
dataRaw.Add(v10);
break;
case TDengineDataType.TSDB_DATA_TYPE_UTINYINT:
byte v12 = Marshal.ReadByte(data);
dataRaw.Add(v12);
break;
case TDengineDataType.TSDB_DATA_TYPE_USMALLINT:
ushort v13 = (ushort)Marshal.ReadInt16(data);
dataRaw.Add(v13);
break;
case TDengineDataType.TSDB_DATA_TYPE_UINT:
uint v14 = (uint)Marshal.ReadInt32(data);
dataRaw.Add(v14);
break;
case TDengineDataType.TSDB_DATA_TYPE_UBIGINT:
ulong v15 = (ulong)Marshal.ReadInt64(data);
dataRaw.Add(v15);
break;
default:
dataRaw.Add("unknown value");
break;
}
}
}
if (TDengine.ErrorNo(res) != 0)
{
Console.Write("Query is not complete, Error {0:G}", TDengine.ErrorNo(res), TDengine.Error(res));
}
TDengine.FreeResult(res);
Console.WriteLine("");
return dataRaw;
}
// Generate insert sql for the with the coldata and tag data
public static string ConstructInsertSql(string table,string stable,List<Object> colData,List<Object> tagData,int numOfRows)
{
int numofFileds = colData.Count / numOfRows;
StringBuilder insertSql;
if (stable == "")
{
insertSql = new StringBuilder($"insert into {table} values(");
}
else
{
insertSql = new StringBuilder($"insert into {table} using {stable} tags(");
for (int j = 0; j < tagData.Count; j++)
{
if (tagData[j] is String)
{
insertSql.Append('\'');
insertSql.Append(tagData[j]);
insertSql.Append('\'');
}
else
{
insertSql.Append(tagData[j]);
}
if (j + 1 != tagData.Count)
{
insertSql.Append(',');
}
}
insertSql.Append(")values(");
}
for (int i = 0; i < colData.Count; i++)
{
if (colData[i] is String)
{
insertSql.Append('\'');
insertSql.Append(colData[i]);
insertSql.Append('\'');
}
else
{
insertSql.Append(colData[i]);
}
if ((i + 1) % numofFileds == 0 && (i + 1) != colData.Count)
{
insertSql.Append(")(");
}
else if ((i + 1) == colData.Count)
{
insertSql.Append(')');
}
else
{
insertSql.Append(',');
}
}
insertSql.Append(';');
//Console.WriteLine(insertSql.ToString());
return insertSql.ToString();
}
public static List<object> CombineColAndTagData(List<object> colData,List<object> tagData, int numOfRows)
{
var list = new List<Object>();
for (int i = 0; i < colData.Count; i++)
{
list.Add(colData[i]);
if ((i + 1) % (colData.Count / numOfRows) == 0)
{
for (int j = 0; j < tagData.Count; j++)
{
list.Add(tagData[j]);
}
}
}
return list;
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册