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

[TD-13710]<test>:csharp connector add test cases for query async (#10673)

* [TD-13710]<test>:csharp connector add test cases for query async

* [TD-13710]<test>:uncomment database fixture dispose
上级 069894d4
using TDengineDriver;
using Test.UtilsTools;
using System;
using System.Runtime.InteropServices;
using Xunit;
using System.Collections.Generic;
using Test.UtilsTools.DataSource;
using Test.UtilsTools.ResultSet;
using Xunit.Abstractions;
using Test.Fixture;
using Test.Case.Attributes;
namespace Cases
{
[TestCaseOrderer("XUnit.Case.Orderers.TestExeOrderer", "Cases.ExeOrder")]
[Collection("Database collection")]
public class QueryAsyncCases
{
DatabaseFixture database;
private readonly ITestOutputHelper output;
public QueryAsyncCases(DatabaseFixture fixture, ITestOutputHelper output)
{
this.database = fixture;
this.output = output;
}
/// <author>xiaolei</author>
/// <Name>QueryAsyncCases.QueryAsyncCases</Name>
/// <describe>Test query without condition</describe>
/// <filename>QueryAsync.cs</filename>
/// <result>pass or failed </result>
[Fact(DisplayName = "QueryAsyncCases.QueryWithoutCondition()"),TestExeOrder(1),Trait("Category", "QueryAWithoutCondition")]
public void QueryWithoutCondition()
{
IntPtr conn = database.conn;
IntPtr _res = IntPtr.Zero;
var tableName = "query_a_without_condition";
var createSql = $"create table if not exists {tableName}(ts timestamp,bl bool,i8 tinyint,i16 smallint,i32 int,i64 bigint,bnr binary(50),nchr nchar(50))tags(t_i32 int,t_bnr binary(50),t_nchr nchar(50))";
var dropSql = $"drop table if exists {tableName}";
var colData = new List<Object>{1646150410100,true,1,11,1111,11111111,"value one","值壹",
1646150410200,true,2,22,2222,22222222,"value two","值贰",
1646150410300,false,3,33,3333,33333333,"value three","值三",
};
var tagData = new List<Object> { 1, "tag_one", "标签壹" };
String insertSql = UtilsTools.ConstructInsertSql(tableName + "_s01", tableName, colData, tagData, 3);
List<TDengineMeta> expectResMeta = DataSource.GetMetaFromDLL(createSql);
List<Object> expectResData = UtilsTools.CombineColAndTagData(colData, tagData, 3);
var querySql = $"select * from {tableName}";
UtilsTools.ExecuteUpdate(conn, dropSql);
UtilsTools.ExecuteUpdate(conn, createSql);
UtilsTools.ExecuteUpdate(conn, insertSql);
QueryAsyncCallback fq = new QueryAsyncCallback(QueryCallback);
TDengine.QueryAsync(conn, querySql, fq, IntPtr.Zero);
void QueryCallback(IntPtr param, IntPtr taosRes, int code)
{
if (code == 0 && taosRes != IntPtr.Zero)
{
FetchRowAsyncCallback fetchRowAsyncCallback = new FetchRowAsyncCallback(FetchCallback);
TDengine.FetchRowAsync(taosRes, fetchRowAsyncCallback, param);
}
else
{
Console.WriteLine($"async query data failed, failed code {code}");
}
}
void FetchCallback(IntPtr param, IntPtr taosRes, int numOfRows)
{
if (numOfRows > 0)
{
ResultSet actualResult = new ResultSet(taosRes);
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++)
{
// Console.WriteLine("{0},{1},{2}", i, expectResData[i], actualResData[i]);
Assert.Equal(expectResData[i].ToString(), actualResData[i]);
}
TDengine.FetchRowAsync(taosRes, FetchCallback, param);
}
else
{
if (numOfRows == 0)
{
Console.WriteLine("async retrieve complete.");
}
else
{
Console.WriteLine($"FetchRowAsync callback error, error code {numOfRows}");
}
TDengine.FreeResult(taosRes);
}
}
}
/// <author>xiaolei</author>
/// <Name>QueryAsyncCases.QueryWithCondition</Name>
/// <describe>Test query with condition</describe>
/// <filename>QueryAsync.cs</filename>
/// <result>pass or failed </result>
[Fact(DisplayName = "QueryAsyncCases.QueryWithCondition()"),TestExeOrder(2),Trait("Category", "QueryAWithCondition")]
public void QueryWithCondition()
{
IntPtr conn = database.conn;
IntPtr _res = IntPtr.Zero;
var tableName = "query_a_with_condition";
var createSql = $"create table if not exists {tableName}(ts timestamp,bl bool,i8 tinyint,i16 smallint,i32 int,i64 bigint,bnr binary(50),nchr nchar(50))tags(t_i32 int,t_bnr binary(50),t_nchr nchar(50))";
var dropSql = $"drop table if exists {tableName}";
var colData = new List<Object>{1646150410100,true,1,11,1111,11111111,"value one","值壹",
1646150410200,true,2,22,2222,22222222,"value two","值贰",
1646150410300,false,3,33,3333,33333333,"value three","值三",
};
var colDataActual = colData.GetRange(8, 8);
var tagData = new List<Object> { 1, "tag_one", "标签壹" };
String insertSql = UtilsTools.ConstructInsertSql(tableName + "_s01", tableName, colData, tagData, 3);
List<TDengineMeta> expectResMeta = DataSource.GetMetaFromDLL(createSql);
List<Object> expectResData = UtilsTools.CombineColAndTagData(colDataActual, tagData, 1);
colDataActual.ForEach((item) => { Console.Write("{0}\t", item); });
var querySql = $"select * from {tableName} where bl=true and t_bnr='tag_one' and i8>1 and t_nchr = '标签壹'";
UtilsTools.ExecuteUpdate(conn, dropSql);
UtilsTools.ExecuteUpdate(conn, createSql);
UtilsTools.ExecuteUpdate(conn, insertSql);
QueryAsyncCallback fq = new QueryAsyncCallback(QueryCallback);
TDengine.QueryAsync(conn, querySql, fq, IntPtr.Zero);
void QueryCallback(IntPtr param, IntPtr taosRes, int code)
{
if (code == 0 && taosRes != IntPtr.Zero)
{
FetchRowAsyncCallback fetchRowAsyncCallback = new FetchRowAsyncCallback(FetchCallback);
TDengine.FetchRowAsync(taosRes, fetchRowAsyncCallback, param);
}
else
{
Console.WriteLine($"async query data failed, failed code {code}");
}
}
void FetchCallback(IntPtr param, IntPtr taosRes, int numOfRows)
{
if (numOfRows > 0)
{
ResultSet actualResult = new ResultSet(taosRes);
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++)
{
// Console.WriteLine("{0},{1},{2}", i, expectResData[i], actualResData[i]);
Assert.Equal(expectResData[i].ToString(), actualResData[i]);
}
TDengine.FetchRowAsync(taosRes, FetchCallback, param);
}
else
{
if (numOfRows == 0)
{
Console.WriteLine("async retrieve complete.");
}
else
{
Console.WriteLine($"FetchRowAsync callback error, error code {numOfRows}");
}
TDengine.FreeResult(taosRes);
}
}
}
/// <author>xiaolei</author>
/// <Name>QueryAsyncCases.QueryWithJsonCondition</Name>
/// <describe>Test query with condition</describe>
/// <filename>QueryAsync.cs</filename>
/// <result>pass or failed </result>
[Fact(DisplayName = "QueryAsyncCases.QueryWithJsonCondition()"),TestExeOrder(3),Trait("Category", "QueryAWithJsonCondition")]
public void QueryWithJsonCondition()
{
IntPtr conn = database.conn;
IntPtr _res = IntPtr.Zero;
var tableName = "query_a_json_condition";
var createSql = $"create table if not exists {tableName}(ts timestamp,bl bool,i8 tinyint,i16 smallint,i32 int,i64 bigint,bnr binary(50),nchr nchar(50))tags(jtag json)";
var dropSql = $"drop table if exists {tableName}";
var colData1 = new List<Object>{1646150410100,true,1,11,1111,11111111,"value one","值壹",
1646150410200,true,2,22,2222,22222222,"value two","值贰",
1646150410300,false,3,33,3333,33333333,"value three","值三",
};
var colData2 = new List<Object>{1646150410400,false,4,44,4444,44444444,"value three","值肆",
1646150410500,true,5,55,5555,55555555,"value one","值伍",
1646150410600,true,6,66,6666,66666666,"value two","值陆",
};
var tagData1 = new List<Object> { "{\"t_bnr\":\"tag1\",\"t_i32\":1,\"t_nchr\":\"标签壹\"}" };
var tagData2 = new List<Object> { "{\"t_bnr\":\"tag2\",\"t_i32\":2,\"t_nchar\":\"标签贰\"}" };
var querySql = $"select * from {tableName} where jtag->'t_bnr'='tag1';";
String insertSql1 = UtilsTools.ConstructInsertSql(tableName + "_s01", tableName, colData1, tagData1, 3);
String insertSql2 = UtilsTools.ConstructInsertSql(tableName + "_s02", tableName, colData1, tagData2, 3);
List<TDengineMeta> expectResMeta = DataSource.GetMetaFromDLL(createSql);
List<Object> expectResData = UtilsTools.CombineColAndTagData(colData1, tagData1, 3);
UtilsTools.ExecuteUpdate(conn, dropSql);
UtilsTools.ExecuteUpdate(conn, createSql);
UtilsTools.ExecuteUpdate(conn, insertSql1);
UtilsTools.ExecuteUpdate(conn, insertSql2);
QueryAsyncCallback fq = new QueryAsyncCallback(QueryCallback);
TDengine.QueryAsync(conn, querySql, fq, IntPtr.Zero);
void QueryCallback(IntPtr param, IntPtr taosRes, int code)
{
if (code == 0 && taosRes != IntPtr.Zero)
{
FetchRowAsyncCallback fetchRowAsyncCallback = new FetchRowAsyncCallback(FetchCallback);
TDengine.FetchRowAsync(taosRes, fetchRowAsyncCallback, param);
}
else
{
Console.WriteLine($"async query data failed, failed code {code}");
}
}
void FetchCallback(IntPtr param, IntPtr taosRes, int numOfRows)
{
if (numOfRows > 0)
{
ResultSet actualResult = new ResultSet(taosRes);
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++)
{
// Console.WriteLine("{0},{1},{2}", i, expectResData[i], actualResData[i]);
Assert.Equal(expectResData[i].ToString(), actualResData[i]);
}
TDengine.FetchRowAsync(taosRes, FetchCallback, param);
}
else
{
if (numOfRows == 0)
{
Console.WriteLine("async retrieve complete.");
}
else
{
Console.WriteLine($"FetchRowAsync callback error, error code {numOfRows}");
}
TDengine.FreeResult(taosRes);
}
}
}
}
}
using System;
using System.Configuration;
using System.Data.SqlClient;
using System.Runtime.InteropServices;
using TDengineDriver;
namespace Test.Fixture
{
public class DatabaseFixture : IDisposable
{
public IntPtr conn { get; set; }
private string user = "root";
private string password = "taosdata";
private string ip = "127.0.0.1";
private short port = 0;
private string db = "xunit_test_fixture";
public DatabaseFixture()
{
conn = TDengine.Connect(ip, user, password, "", port);
IntPtr res;
if (conn != IntPtr.Zero)
{
if ((res = TDengine.Query(conn, $"create database if not exists {db} keep 3650")) != IntPtr.Zero)
{
if ((res = TDengine.Query(conn, $"use {db}")) != IntPtr.Zero)
{
Console.WriteLine("Get connection success");
}
else
{
throw new Exception(TDengine.Error(res));
}
}
else
{
throw new Exception(TDengine.Error(res));
}
}
else
{
throw new Exception("Get TDConnection failed");
}
}
// public IntPtr TDConnection { get; }
public void Dispose()
{
// IntPtr res;
// if (conn != IntPtr.Zero)
// {
// if ((res = TDengine.Query(conn, $"drop database if exists {db}")) != IntPtr.Zero)
// {
// if (TDengine.Close(conn) == 0)
// {
// Console.WriteLine("close connection success");
// }
// else
// {
// throw new Exception("close connection failed");
// }
// }
// else
// {
// throw new Exception(TDengine.Error(res));
// }
// }
// else
// {
// throw new Exception("connection if already null");
// }
}
}
}
using Xunit;
using Test.Fixture;
[CollectionDefinition("Database collection")]
public class DatabaseCollection : ICollectionFixture<DatabaseFixture>
{
// This class has no code, and is never created. Its purpose is simply
// to be the place to apply [CollectionDefinition] and all the
// ICollectionFixture<> interfaces.
}
\ No newline at end of file
using System;
namespace Test.Case.Attributes
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class TestExeOrderAttribute : Attribute
{
public int ExeOrder { get; private set; }
public TestExeOrderAttribute(int exeOrder) => ExeOrder = exeOrder;
}
}
\ No newline at end of file
using System.Collections.Generic;
using System.Linq;
using Xunit.Abstractions;
using Xunit.Sdk;
using Test.Case.Attributes;
namespace XUnit.Case.Orderers
{
public class TestExeOrderer : ITestCaseOrderer
{
public IEnumerable<TTestCase> OrderTestCases<TTestCase>(
IEnumerable<TTestCase> testCases) where TTestCase : ITestCase
{
string assemblyName = typeof(TestExeOrderAttribute).AssemblyQualifiedName!;
var sortedMethods = new SortedDictionary<int, List<TTestCase>>();
foreach (TTestCase testCase in testCases)
{
int exeOrder = testCase.TestMethod.Method
.GetCustomAttributes(assemblyName)
.FirstOrDefault()
?.GetNamedArgument<int>(nameof(TestExeOrderAttribute.ExeOrder)) ?? 0;
GetOrCreate(sortedMethods, exeOrder).Add(testCase);
}
foreach (TTestCase testCase in
sortedMethods.Keys.SelectMany(
exeOrder => sortedMethods[exeOrder].OrderBy(
testCase => testCase.TestMethod.Method.Name)))
{
yield return testCase;
}
}
private static TValue GetOrCreate<TKey, TValue>(
IDictionary<TKey, TValue> dictionary, TKey key)
where TKey : struct
where TValue : new() =>
dictionary.TryGetValue(key, out TValue? result)
? result
: (dictionary[key] = new TValue());
}
}
\ No newline at end of file
...@@ -3,6 +3,7 @@ using TDengineDriver; ...@@ -3,6 +3,7 @@ using TDengineDriver;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
using System.Collections.Generic; using System.Collections.Generic;
using Xunit.Abstractions;
namespace Test.UtilsTools namespace Test.UtilsTools
{ {
public class UtilsTools public class UtilsTools
...@@ -28,20 +29,20 @@ namespace Test.UtilsTools ...@@ -28,20 +29,20 @@ namespace Test.UtilsTools
//get taos.cfg file based on different os //get taos.cfg file based on different os
public static string GetConfigPath() public static string GetConfigPath()
{ {
string configDir = "" ; string configDir = "";
if(OperatingSystem.IsOSPlatform("Windows")) if (OperatingSystem.IsOSPlatform("Windows"))
{ {
configDir = "C:/TDengine/cfg"; configDir = "C:/TDengine/cfg";
} }
else if(OperatingSystem.IsOSPlatform("Linux")) else if (OperatingSystem.IsOSPlatform("Linux"))
{ {
configDir = "/etc/taos"; configDir = "/etc/taos";
} }
else if(OperatingSystem.IsOSPlatform("macOS")) else if (OperatingSystem.IsOSPlatform("macOS"))
{ {
configDir = "/etc/taos"; configDir = "/usr/local/etc/taos";
} }
return configDir; return configDir;
} }
public static IntPtr ExecuteQuery(IntPtr conn, String sql) public static IntPtr ExecuteQuery(IntPtr conn, String sql)
...@@ -102,23 +103,16 @@ namespace Test.UtilsTools ...@@ -102,23 +103,16 @@ namespace Test.UtilsTools
int fieldCount = metas.Count; int fieldCount = metas.Count;
IntPtr rowdata; IntPtr rowdata;
// StringBuilder builder = new StringBuilder();
List<string> datas = QueryRes(res, metas); List<string> datas = QueryRes(res, metas);
Console.Write(" DisplayRes ---");
for (int i = 0; i < metas.Count; i++) for (int i = 0; i < metas.Count; i++)
{ {
for (int j = 0; j < datas.Count; j++) for (int j = 0; j < datas.Count; j++)
{ {
Console.Write(" {0} ---", datas[i * j + i]); Console.Write(" {0} \t|", datas[j]);
} }
Console.WriteLine(""); Console.WriteLine("");
} }
// 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("");
} }
public static List<List<string>> GetResultSet(IntPtr res) public static List<List<string>> GetResultSet(IntPtr res)
...@@ -197,14 +191,8 @@ namespace Test.UtilsTools ...@@ -197,14 +191,8 @@ namespace Test.UtilsTools
} }
public static List<String> GetResData(IntPtr res) public static List<String> GetResData(IntPtr res)
{ {
List<string> colName = new List<string>(); List<string> dataRaw = GetResDataWithoutFree(res);
List<string> dataRaw = new List<string>(); FreeResult(res);
if (!IsValidResult(res))
{
ExitProgram();
}
List<TDengineMeta> metas = GetResField(res);
dataRaw = QueryRes(res, metas);
return dataRaw; return dataRaw;
} }
...@@ -288,107 +276,23 @@ namespace Test.UtilsTools ...@@ -288,107 +276,23 @@ namespace Test.UtilsTools
private static List<string> QueryRes(IntPtr res, List<TDengineMeta> metas) private static List<string> QueryRes(IntPtr res, List<TDengineMeta> metas)
{ {
IntPtr rowdata; IntPtr taosRow;
long queryRows = 0;
List<string> dataRaw = new List<string>(); List<string> dataRaw = new List<string>();
int fieldCount = metas.Count; int fieldCount = metas.Count;
while ((rowdata = TDengine.FetchRows(res)) != IntPtr.Zero) while ((taosRow = TDengine.FetchRows(res)) != IntPtr.Zero)
{ {
queryRows++; dataRaw.AddRange(FetchRow(taosRow, res));
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.ToString());
break;
case TDengineDataType.TSDB_DATA_TYPE_TINYINT:
sbyte v2 = (sbyte)Marshal.ReadByte(data);
dataRaw.Add(v2.ToString());
break;
case TDengineDataType.TSDB_DATA_TYPE_SMALLINT:
short v3 = Marshal.ReadInt16(data);
dataRaw.Add(v3.ToString());
break;
case TDengineDataType.TSDB_DATA_TYPE_INT:
int v4 = Marshal.ReadInt32(data);
dataRaw.Add(v4.ToString());
break;
case TDengineDataType.TSDB_DATA_TYPE_BIGINT:
long v5 = Marshal.ReadInt64(data);
dataRaw.Add(v5.ToString());
break;
case TDengineDataType.TSDB_DATA_TYPE_FLOAT:
float v6 = (float)Marshal.PtrToStructure(data, typeof(float));
dataRaw.Add(v6.ToString());
break;
case TDengineDataType.TSDB_DATA_TYPE_DOUBLE:
double v7 = (double)Marshal.PtrToStructure(data, typeof(double));
dataRaw.Add(v7.ToString());
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.ToString());
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.ToString());
break;
case TDengineDataType.TSDB_DATA_TYPE_USMALLINT:
ushort v13 = (ushort)Marshal.ReadInt16(data);
dataRaw.Add(v13.ToString());
break;
case TDengineDataType.TSDB_DATA_TYPE_UINT:
uint v14 = (uint)Marshal.ReadInt32(data);
dataRaw.Add(v14.ToString());
break;
case TDengineDataType.TSDB_DATA_TYPE_UBIGINT:
ulong v15 = (ulong)Marshal.ReadInt64(data);
dataRaw.Add(v15.ToString());
break;
default:
dataRaw.Add("unknown value");
break;
}
}
} }
if (TDengine.ErrorNo(res) != 0) if (TDengine.ErrorNo(res) != 0)
{ {
Console.Write("Query is not complete, Error {0:G}", TDengine.ErrorNo(res), TDengine.Error(res)); Console.Write("Query is not complete, Error {0:G}", TDengine.ErrorNo(res), TDengine.Error(res));
} }
TDengine.FreeResult(res);
Console.WriteLine(""); Console.WriteLine("");
return dataRaw; return dataRaw;
} }
// Generate insert sql for the with the coldata and tag data // 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) public static string ConstructInsertSql(string table, string stable, List<Object> colData, List<Object> tagData, int numOfRows)
{ {
int numofFileds = colData.Count / numOfRows; int numofFileds = colData.Count / numOfRows;
StringBuilder insertSql; StringBuilder insertSql;
...@@ -453,8 +357,8 @@ namespace Test.UtilsTools ...@@ -453,8 +357,8 @@ namespace Test.UtilsTools
return insertSql.ToString(); return insertSql.ToString();
} }
public static List<object> CombineColAndTagData(List<object> colData,List<object> tagData, int numOfRows) public static List<object> CombineColAndTagData(List<object> colData, List<object> tagData, int numOfRows)
{ {
var list = new List<Object>(); var list = new List<Object>();
for (int i = 0; i < colData.Count; i++) for (int i = 0; i < colData.Count; i++)
...@@ -470,6 +374,137 @@ namespace Test.UtilsTools ...@@ -470,6 +374,137 @@ namespace Test.UtilsTools
} }
return list; return list;
} }
/// <summary>
/// Using this method to free TAOS_RES,otherwise will lead memory
/// leak.Notice do not call this method while subscribe/consume until
/// end of the program.
/// </summary>
/// <param name="res">TAOS_RES, the resultset usually is return by taos_query()</param>
public static void FreeResult(IntPtr res)
{
TDengine.FreeResult(res);
}
/// <summary>
/// Using to parse TAOS_ROW.
/// </summary>
/// <param name="taosRow">This is TAOS_RES pointer</param>
/// <param name="taosRes"> This is TAOS_ROW pointer</param>
/// <returns></returns>
public static List<string> FetchRow(IntPtr taosRow, IntPtr taosRes)
{
List<TDengineMeta> metaList = TDengine.FetchFields(taosRes);
int numOfFiled = TDengine.FieldCount(taosRes);
List<String> dataRaw = new List<string>();
IntPtr colLengthPrt = TDengine.FetchLengths(taosRes);
int[] colLengthArr = new int[numOfFiled];
Marshal.Copy(colLengthPrt, colLengthArr, 0, numOfFiled);
for (int i = 0; i < numOfFiled; i++)
{
TDengineMeta meta = metaList[i];
IntPtr data = Marshal.ReadIntPtr(taosRow, IntPtr.Size * i);
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.ToString());
break;
case TDengineDataType.TSDB_DATA_TYPE_TINYINT:
sbyte v2 = (sbyte)Marshal.ReadByte(data);
dataRaw.Add(v2.ToString());
break;
case TDengineDataType.TSDB_DATA_TYPE_SMALLINT:
short v3 = Marshal.ReadInt16(data);
dataRaw.Add(v3.ToString());
break;
case TDengineDataType.TSDB_DATA_TYPE_INT:
int v4 = Marshal.ReadInt32(data);
dataRaw.Add(v4.ToString());
break;
case TDengineDataType.TSDB_DATA_TYPE_BIGINT:
long v5 = Marshal.ReadInt64(data);
dataRaw.Add(v5.ToString());
break;
case TDengineDataType.TSDB_DATA_TYPE_FLOAT:
float v6 = (float)Marshal.PtrToStructure(data, typeof(float));
dataRaw.Add(v6.ToString());
break;
case TDengineDataType.TSDB_DATA_TYPE_DOUBLE:
double v7 = (double)Marshal.PtrToStructure(data, typeof(double));
dataRaw.Add(v7.ToString());
break;
case TDengineDataType.TSDB_DATA_TYPE_BINARY:
string v8 = Marshal.PtrToStringUTF8(data, colLengthArr[i]);
dataRaw.Add(v8);
break;
case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP:
long v9 = Marshal.ReadInt64(data);
dataRaw.Add(v9.ToString());
break;
case TDengineDataType.TSDB_DATA_TYPE_NCHAR:
string v10 = Marshal.PtrToStringUTF8(data, colLengthArr[i]);
dataRaw.Add(v10);
break;
case TDengineDataType.TSDB_DATA_TYPE_UTINYINT:
byte v12 = Marshal.ReadByte(data);
dataRaw.Add(v12.ToString());
break;
case TDengineDataType.TSDB_DATA_TYPE_USMALLINT:
ushort v13 = (ushort)Marshal.ReadInt16(data);
dataRaw.Add(v13.ToString());
break;
case TDengineDataType.TSDB_DATA_TYPE_UINT:
uint v14 = (uint)Marshal.ReadInt32(data);
dataRaw.Add(v14.ToString());
break;
case TDengineDataType.TSDB_DATA_TYPE_UBIGINT:
ulong v15 = (ulong)Marshal.ReadInt64(data);
dataRaw.Add(v15.ToString());
break;
case TDengineDataType.TSDB_DATA_TYPE_JSONTAG:
string v16 = Marshal.PtrToStringUTF8(data, colLengthArr[i]);
dataRaw.Add(v16);
break;
default:
dataRaw.Add("nonsupport data type value");
break;
}
}
return dataRaw;
}
/// <summary>
/// Get the result data from TAO_RES but this interface will
/// not free the TAO_RES at the end. Remember to free the TAOS_RES
/// when you need to do so.
/// </summary>
/// <param name="res"> This is a TAOS_RES pointer.</param>
/// <returns></returns>
public static List<String> GetResDataWithoutFree(IntPtr res)
{
List<string> colName = new List<string>();
List<string> dataRaw = new List<string>();
if (!IsValidResult(res))
{
ExitProgram();
}
List<TDengineMeta> metas = GetResField(res);
dataRaw = QueryRes(res, metas);
return dataRaw;
}
} }
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册