From b83699bc8f8525afda8b2fef5b57fe907c068eec Mon Sep 17 00:00:00 2001 From: xiaolei li <85657333+xleili@users.noreply.github.com> Date: Thu, 23 Dec 2021 11:46:04 +0800 Subject: [PATCH] =?UTF-8?q?[TD-12102]:csharp=20support=20fetch=5Fleng?= =?UTF-8?q?ths,fix=20fetch=5Frow=20binray=20ret=E2=80=A6=20(#9107)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [TD-12102]:csharp support fetch_lengths,fix fetch_row binray retrieve error * submit testcase * fix method name to FetchLengths, update test case to assert value * fix format * ci 2nd --- .../C#/src/TDengineDriver/TDengineDriver.cs | 3 + src/connector/C#/src/test/Cases/Cases.csproj | 4 + .../C#/src/test/Cases/FetchLength.cs | 44 ++++++ src/connector/C#/src/test/Cases/Program.cs | 131 ++++++++--------- src/connector/C#/src/test/Cases/Utils.cs | 132 +++++++++++++++++- .../C#/src/test/XUnitTest/XUnitTest.csproj | 6 +- 6 files changed, 252 insertions(+), 68 deletions(-) create mode 100644 src/connector/C#/src/test/Cases/FetchLength.cs diff --git a/src/connector/C#/src/TDengineDriver/TDengineDriver.cs b/src/connector/C#/src/TDengineDriver/TDengineDriver.cs index 42bba43852..15e0ca0841 100644 --- a/src/connector/C#/src/TDengineDriver/TDengineDriver.cs +++ b/src/connector/C#/src/TDengineDriver/TDengineDriver.cs @@ -398,5 +398,8 @@ namespace TDengineDriver IntPtr stmtErrPrt = StmtErrPtr(stmt); return Marshal.PtrToStringAnsi(stmtErrPrt); } + + [DllImport("taos", EntryPoint = "taos_fetch_lengths", CallingConvention = CallingConvention.Cdecl)] + static extern public IntPtr FetchLengths(IntPtr taos); } } diff --git a/src/connector/C#/src/test/Cases/Cases.csproj b/src/connector/C#/src/test/Cases/Cases.csproj index f2ae6938fb..57c0dd8f7d 100644 --- a/src/connector/C#/src/test/Cases/Cases.csproj +++ b/src/connector/C#/src/test/Cases/Cases.csproj @@ -9,4 +9,8 @@ net5.0 + + true + ..\doc\FunctionTest.XML + diff --git a/src/connector/C#/src/test/Cases/FetchLength.cs b/src/connector/C#/src/test/Cases/FetchLength.cs new file mode 100644 index 0000000000..b5c5c4ecad --- /dev/null +++ b/src/connector/C#/src/test/Cases/FetchLength.cs @@ -0,0 +1,44 @@ +using System; +using Test.UtilsTools; +using System.Collections.Generic; + +namespace Cases +{ + + public class FetchLengthCase + { + /// xiaolei + /// TestRetrieveBinary + /// TD-12103 C# connector fetch_row with binary data retrieving error + /// FetchLength.cs + /// pass or failed + public void TestRetrieveBinary(IntPtr conn) + { + string sql1 = "create stable stb1 (ts timestamp, name binary(10)) tags(n int);"; + string sql2 = "insert into tb1 using stb1 tags(1) values(now, 'log');"; + string sql3 = "insert into tb2 using stb1 tags(2) values(now, 'test');"; + string sql4 = "insert into tb3 using stb1 tags(3) values(now, 'db02');"; + string sql5 = "insert into tb4 using stb1 tags(4) values(now, 'db3');"; + + string sql6 = "select distinct(name) from stb1;";// + + UtilsTools.ExecuteQuery(conn, sql1); + UtilsTools.ExecuteQuery(conn, sql2); + UtilsTools.ExecuteQuery(conn, sql3); + UtilsTools.ExecuteQuery(conn, sql4); + UtilsTools.ExecuteQuery(conn, sql5); + + IntPtr resPtr = IntPtr.Zero; + resPtr = UtilsTools.ExecuteQuery(conn, sql6); + List> result = UtilsTools.GetResultSet(resPtr); + + List colname = result[0]; + List data = result[1]; + UtilsTools.AssertEqual("db3", data[0]); + UtilsTools.AssertEqual("log", data[1]); + UtilsTools.AssertEqual("db02", data[2]); + UtilsTools.AssertEqual("test", data[3]); + + } + } +} diff --git a/src/connector/C#/src/test/Cases/Program.cs b/src/connector/C#/src/test/Cases/Program.cs index a1b47f3890..89f878e994 100644 --- a/src/connector/C#/src/test/Cases/Program.cs +++ b/src/connector/C#/src/test/Cases/Program.cs @@ -1,64 +1,67 @@ -using System; -using Test.UtilsTools; -using Cases; - -namespace Cases.EntryPoint -{ - class Program - { - - static void Main(string[] args) - { - IntPtr conn = IntPtr.Zero; - IntPtr stmt = IntPtr.Zero; - IntPtr res = IntPtr.Zero; - - conn = UtilsTools.TDConnection("127.0.0.1", "root", "taosdata", "", 0); - UtilsTools.ExecuteQuery(conn, "drop database if exists csharp"); - UtilsTools.ExecuteQuery(conn, "create database if not exists csharp keep 3650"); - UtilsTools.ExecuteQuery(conn, "use csharp"); - - Console.WriteLine("====================StableColumnByColumn==================="); - StableColumnByColumn columnByColumn = new StableColumnByColumn(); - columnByColumn.Test(conn, "stablecolumnbycolumn"); - Console.WriteLine("====================StmtStableQuery==================="); - StmtStableQuery stmtStableQuery = new StmtStableQuery(); - stmtStableQuery.Test(conn, "stablecolumnbycolumn"); - - Console.WriteLine("====================StableMutipleLine==================="); - StableMutipleLine mutipleLine = new StableMutipleLine(); - mutipleLine.Test(conn, "stablemutipleline"); - - //================================================================================ - - Console.WriteLine("====================NtableSingleLine==================="); - NtableSingleLine ntableSingleLine = new NtableSingleLine(); - ntableSingleLine.Test(conn, "stablesingleline"); - - Console.WriteLine("====================NtableMutipleLine==================="); - NtableMutipleLine ntableMutipleLine = new NtableMutipleLine(); - ntableMutipleLine.Test(conn, "ntablemutipleline"); - Console.WriteLine("====================StmtNtableQuery==================="); - StmtNtableQuery stmtNtableQuery = new StmtNtableQuery(); - stmtNtableQuery.Test(conn, "ntablemutipleline"); - - Console.WriteLine("====================NtableColumnByColumn==================="); - NtableColumnByColumn ntableColumnByColumn = new NtableColumnByColumn(); - ntableColumnByColumn.Test(conn, "ntablecolumnbycolumn"); - - Console.WriteLine("====================fetchfeilds==================="); - FetchFields fetchFields = new FetchFields(); - fetchFields.Test(conn,"fetchfeilds"); - - Console.WriteLine("===================JsonTagTest===================="); - JsonTagTest jsonTagTest = new JsonTagTest(); - jsonTagTest.Test(conn); - - // UtilsTools.ExecuteQuery(conn, "drop database if exists csharp"); - UtilsTools.CloseConnection(conn); - UtilsTools.ExitProgram(); - - - } - } -} +using System; +using Test.UtilsTools; +using Cases; + +namespace Cases.EntryPoint +{ + class Program + { + + static void Main(string[] args) + { + IntPtr conn = IntPtr.Zero; + IntPtr stmt = IntPtr.Zero; + IntPtr res = IntPtr.Zero; + + conn = UtilsTools.TDConnection("127.0.0.1", "root", "taosdata", "", 0); + UtilsTools.ExecuteQuery(conn, "drop database if exists csharp"); + UtilsTools.ExecuteQuery(conn, "create database if not exists csharp keep 3650"); + UtilsTools.ExecuteQuery(conn, "use csharp"); + + Console.WriteLine("====================StableColumnByColumn==================="); + StableColumnByColumn columnByColumn = new StableColumnByColumn(); + columnByColumn.Test(conn, "stablecolumnbycolumn"); + Console.WriteLine("====================StmtStableQuery==================="); + StmtStableQuery stmtStableQuery = new StmtStableQuery(); + stmtStableQuery.Test(conn, "stablecolumnbycolumn"); + + Console.WriteLine("====================StableMutipleLine==================="); + StableMutipleLine mutipleLine = new StableMutipleLine(); + mutipleLine.Test(conn, "stablemutipleline"); + + //================================================================================ + + Console.WriteLine("====================NtableSingleLine==================="); + NtableSingleLine ntableSingleLine = new NtableSingleLine(); + ntableSingleLine.Test(conn, "stablesingleline"); + + Console.WriteLine("====================NtableMutipleLine==================="); + NtableMutipleLine ntableMutipleLine = new NtableMutipleLine(); + ntableMutipleLine.Test(conn, "ntablemutipleline"); + Console.WriteLine("====================StmtNtableQuery==================="); + StmtNtableQuery stmtNtableQuery = new StmtNtableQuery(); + stmtNtableQuery.Test(conn, "ntablemutipleline"); + + Console.WriteLine("====================NtableColumnByColumn==================="); + NtableColumnByColumn ntableColumnByColumn = new NtableColumnByColumn(); + ntableColumnByColumn.Test(conn, "ntablecolumnbycolumn"); + + Console.WriteLine("====================fetchfeilds==================="); + FetchFields fetchFields = new FetchFields(); + fetchFields.Test(conn, "fetchfeilds"); + + Console.WriteLine("===================JsonTagTest===================="); + JsonTagTest jsonTagTest = new JsonTagTest(); + jsonTagTest.Test(conn); + + Console.WriteLine("====================fetchLengthCase==================="); + FetchLengthCase fetchLengthCase = new FetchLengthCase(); + fetchLengthCase.TestRetrieveBinary(conn); + + UtilsTools.ExecuteQuery(conn, "drop database if exists csharp"); + UtilsTools.CloseConnection(conn); + UtilsTools.ExitProgram(); + + } + } +} diff --git a/src/connector/C#/src/test/Cases/Utils.cs b/src/connector/C#/src/test/Cases/Utils.cs index a549d75b16..7877601e0a 100644 --- a/src/connector/C#/src/test/Cases/Utils.cs +++ b/src/connector/C#/src/test/Cases/Utils.cs @@ -35,7 +35,6 @@ namespace Test.UtilsTools else { Console.WriteLine(sql.ToString() + " success"); - } return res; } @@ -83,9 +82,13 @@ namespace Test.UtilsTools IntPtr rowdata; StringBuilder builder = new StringBuilder(); + 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]; @@ -131,7 +134,7 @@ namespace Test.UtilsTools builder.Append(v7); break; case TDengineDataType.TSDB_DATA_TYPE_BINARY: - string v8 = Marshal.PtrToStringAnsi(data); + string v8 = Marshal.PtrToStringAnsi(data, colLengthArr[fields]); builder.Append(v8); break; case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP: @@ -139,7 +142,7 @@ namespace Test.UtilsTools builder.Append(v9); break; case TDengineDataType.TSDB_DATA_TYPE_NCHAR: - string v10 = Marshal.PtrToStringAnsi(data); + string v10 = Marshal.PtrToStringAnsi(data, colLengthArr[fields]); builder.Append(v10); break; case TDengineDataType.TSDB_DATA_TYPE_JSONTAG: @@ -164,6 +167,117 @@ namespace Test.UtilsTools TDengine.FreeResult(res); Console.WriteLine(""); } + public static List> GetResultSet(IntPtr res) + { + List> result = new List>(); + List colName = new List(); + List dataRaw = new List(); + long queryRows = 0; + if (!IsValidResult(res)) + { + ExitProgram(); + } + + int fieldCount = TDengine.FieldCount(res); + List metas = TDengine.FetchFields(res); + + for (int j = 0; j < metas.Count; j++) + { + TDengineMeta meta = (TDengineMeta)metas[j]; + colName.Add(meta.name); + } + result.Add(colName); + + IntPtr rowdata; + 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.ToString()); + break; + case TDengineDataType.TSDB_DATA_TYPE_TINYINT: + byte v2 = 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]); + 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]); + dataRaw.Add(v10); + break; + } + } + + } + result.Add(dataRaw); + + 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 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) @@ -183,6 +297,18 @@ namespace Test.UtilsTools List 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(); diff --git a/src/connector/C#/src/test/XUnitTest/XUnitTest.csproj b/src/connector/C#/src/test/XUnitTest/XUnitTest.csproj index 97d13e5e9e..997a9d6fe0 100644 --- a/src/connector/C#/src/test/XUnitTest/XUnitTest.csproj +++ b/src/connector/C#/src/test/XUnitTest/XUnitTest.csproj @@ -2,10 +2,14 @@ net5.0 - false + + true + ..\doc\UnitTest.XML + + runtime; build; native; contentfiles; analyzers; buildtransitive -- GitLab