From 4cf68d3a126cdddd9ab15f720b662fbb30977e81 Mon Sep 17 00:00:00 2001 From: jiacy-jcy Date: Fri, 24 Dec 2021 10:28:29 +0800 Subject: [PATCH] [test/TD-10790](connector):test case for C#stmt --- .../c#/TDengineDriver/TDengineDriver.cs | 399 +++++++++++ .../c#/TDengineDriver/TDengineDriver.csproj | 9 + .../c#/TDengineDriver/TaosBind.cs | 332 +++++++++ .../c#/TDengineDriver/TaosMultiBind.cs | 616 ++++++++++++++++ .../c#/stmtfunction/stmtfunction.cs | 668 ++++++++++++++++++ .../c#/stmtfunction/stmtfunction.csproj | 14 + 6 files changed, 2038 insertions(+) create mode 100644 tests/system-test/3-connectors/c#/TDengineDriver/TDengineDriver.cs create mode 100644 tests/system-test/3-connectors/c#/TDengineDriver/TDengineDriver.csproj create mode 100644 tests/system-test/3-connectors/c#/TDengineDriver/TaosBind.cs create mode 100644 tests/system-test/3-connectors/c#/TDengineDriver/TaosMultiBind.cs create mode 100644 tests/system-test/3-connectors/c#/stmtfunction/stmtfunction.cs create mode 100644 tests/system-test/3-connectors/c#/stmtfunction/stmtfunction.csproj diff --git a/tests/system-test/3-connectors/c#/TDengineDriver/TDengineDriver.cs b/tests/system-test/3-connectors/c#/TDengineDriver/TDengineDriver.cs new file mode 100644 index 0000000000..1bfb8eae07 --- /dev/null +++ b/tests/system-test/3-connectors/c#/TDengineDriver/TDengineDriver.cs @@ -0,0 +1,399 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ + +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 + } + + 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 "STRING"; + case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP: + return "TIMESTAMP"; + case TDengineDataType.TSDB_DATA_TYPE_NCHAR: + return "NCHAR"; + 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); + + [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 FetchFields(IntPtr res) + { + // const int fieldSize = 68; + + List metas = new List(); + 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: + /// + /// init a TAOS_STMT object for later use. + /// + /// a valid taos connection + /// + /// Not NULL returned for success, NULL for failure. And it should be freed with taos_stmt_close. + /// + [DllImport("taos", EntryPoint = "taos_stmt_init", CallingConvention = CallingConvention.Cdecl)] + static extern public IntPtr StmtInit(IntPtr taos); + + /// + /// prepare a sql statement,'sql' should be a valid INSERT/SELECT statement. + /// + /// could be the value returned by 'StmtInit', that may be a valid object or NULL. + /// sql string,used to bind parameters with + /// no used + /// 0 for success, non-zero for failure. + [DllImport("taos", EntryPoint = "taos_stmt_prepare", CallingConvention = CallingConvention.Cdecl)] + static extern public int StmtPrepare(IntPtr stmt, string sql); + + /// + /// For INSERT only. Used to bind table name as a parmeter for the input stmt object. + /// + /// could be the value returned by 'StmtInit', that may be a valid object or NULL. + /// table name you want to bind + /// 0 for success, non-zero for failure. + [DllImport("taos", EntryPoint = "taos_stmt_set_tbname", CallingConvention = CallingConvention.Cdecl)] + static extern public int StmtSetTbname(IntPtr stmt, string name); + + /// + /// 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. + /// + /// could be the value returned by 'StmtInit', that may be a valid object or NULL. + /// table name which is belong to an stable + /// 0 for success, non-zero for failure. + [DllImport("taos", EntryPoint = "taos_stmt_set_sub_tbname", CallingConvention = CallingConvention.Cdecl)] + static extern public int StmtSetSubTbname(IntPtr stmt, string name); + + /// + /// For INSERT only. + /// set a table name for binding table name as parameter and tag values for all tag parameters. + /// + /// could be the value returned by 'StmtInit', that may be a valid object or NULL. + /// use to set table name + /// + /// 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. + /// + /// 0 for success, non-zero for failure. + [DllImport("taos", EntryPoint = "taos_stmt_set_tbname_tags", CallingConvention = CallingConvention.Cdecl)] + static extern public int StmtSetTbnameTags(IntPtr stmt, string name, TAOS_BIND[] tags); + + /// + /// For both INSERT and SELECT. + /// bind a whole line data. + /// The usage of structure TAOS_BIND is the same with MYSQL_BIND in MySQL. + /// + /// could be the value returned by 'StmtInit', that may be a valid object or NULL. + /// + /// points to an array contains the whole line data. + /// the item number and sequence should keep consistence with columns in sql statement. + /// + /// 0 for success, non-zero for failure. + [DllImport("taos", EntryPoint = "taos_stmt_bind_param", CallingConvention = CallingConvention.Cdecl, SetLastError = true)] + static extern public int StmtBindParam(IntPtr stmt, TAOS_BIND[] bind); + + /// + /// bind a single column's data, INTERNAL used and for INSERT only. + /// + /// could be the value returned by 'StmtInit', that may be a valid object or NULL. + /// points to a column's data which could be the one or more lines. + /// the column's index in prepared sql statement, it starts from 0. + /// 0 for success, non-zero for failure. + [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); + + /// + /// for INSERT only + /// bind one or multiple lines data. The parameter 'bind' + /// + /// could be the value returned by 'StmtInit', that may be a valid object or NULL. + /// + /// 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. + /// + /// 0 for success, non-zero for failure. + [DllImport("taos", EntryPoint = "taos_stmt_bind_param_batch", CallingConvention = CallingConvention.Cdecl)] + static extern public int StmtBindParamBatch(IntPtr stmt, [In, Out] TAOS_MULTI_BIND[] bind); + + /// + /// 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. + /// + /// could be the value returned by 'StmtInit', that may be a valid object or NULL. + /// 0 for success, non-zero for failure. + [DllImport("taos", EntryPoint = "taos_stmt_add_batch", CallingConvention = CallingConvention.Cdecl)] + static extern public int StmtAddBatch(IntPtr stmt); + + /// + /// actually execute the INSERT/SELECT sql statement. + /// User application can continue to bind new data after calling to this API. + /// + /// could be the value returned by 'StmtInit', that may be a valid object or NULL. + /// + [DllImport("taos", EntryPoint = "taos_stmt_execute", CallingConvention = CallingConvention.Cdecl)] + static extern public int StmtExecute(IntPtr stmt); + + /// + /// For SELECT only,getting the query result. User application should free it with API 'FreeResult' at the end. + /// + /// could be the value returned by 'StmtInit', that may be a valid object or NULL. + /// Not NULL for success, NULL for failure. + [DllImport("taos", EntryPoint = "taos_stmt_use_result", CallingConvention = CallingConvention.Cdecl)] + static extern public IntPtr StmtUseResult(IntPtr stmt); + + /// + /// close STMT object and free resources. + /// + /// could be the value returned by 'StmtInit', that may be a valid object or NULL. + /// 0 for success, non-zero for failure. + [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)] + /// + /// user application must call this API to load all tables meta, + /// + /// taos connection + /// tablelist + /// + static extern private int LoadTableInfoDll(IntPtr taos, string tableList); + + /// + /// 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); + /// + /// taos connection + /// tables need to load meta info are form in an array + /// + static public int LoadTableInfo(IntPtr taos, string[] tableList) + { + string listStr = string.Join(",", tableList); + return LoadTableInfoDll(taos, listStr); + } + + /// + /// get detail error message when got failure for any stmt API call. If not failure, the result + /// returned in this API is unknown. + /// + /// could be the value returned by 'StmtInit', that may be a valid object or NULL. + /// piont the error message + [DllImport("taos", EntryPoint = "taos_stmt_errstr", CallingConvention = CallingConvention.Cdecl)] + static extern private IntPtr StmtErrPtr(IntPtr stmt); + + /// + /// get detail error message when got failure for any stmt API call. If not failure, the result + /// returned in this API is unknown. + /// + /// could be the value returned by 'StmtInit', that may be a valid object or NULL. + /// error string + static public string StmtErrorStr(IntPtr stmt) + { + IntPtr stmtErrPrt = StmtErrPtr(stmt); + return Marshal.PtrToStringAnsi(stmtErrPrt); + } + } +} diff --git a/tests/system-test/3-connectors/c#/TDengineDriver/TDengineDriver.csproj b/tests/system-test/3-connectors/c#/TDengineDriver/TDengineDriver.csproj new file mode 100644 index 0000000000..a7bd7e9a5c --- /dev/null +++ b/tests/system-test/3-connectors/c#/TDengineDriver/TDengineDriver.csproj @@ -0,0 +1,9 @@ + + + + net5.0 + enable + enable + + + diff --git a/tests/system-test/3-connectors/c#/TDengineDriver/TaosBind.cs b/tests/system-test/3-connectors/c#/TDengineDriver/TaosBind.cs new file mode 100644 index 0000000000..694dcd900b --- /dev/null +++ b/tests/system-test/3-connectors/c#/TDengineDriver/TaosBind.cs @@ -0,0 +1,332 @@ +using System; +using System.Runtime.InteropServices; + + +namespace TDengineDriver +{ + /// + /// this class used to get an instance of struct of TAO_BIND or TAOS_MULTI_BIND + /// And the instance is corresponding with TDengine data type. For example, calling + /// "bindBinary" will return a TAOS_BIND object that is corresponding with TDengine's + /// binary type. + /// + public class TaosBind + { + public static TAOS_BIND BindBool(bool val) + { + TAOS_BIND bind = new TAOS_BIND(); + byte[] boolByteArr = BitConverter.GetBytes(val); + int boolByteArrSize = Marshal.SizeOf(boolByteArr[0]) * boolByteArr.Length; + IntPtr bo = Marshal.AllocHGlobal(1); + Marshal.Copy(boolByteArr, 0, bo, boolByteArr.Length); + + int length = sizeof(Boolean); + IntPtr lengPtr = Marshal.AllocHGlobal(sizeof(int)); + Marshal.WriteInt32(lengPtr, length); + + bind.buffer_type = (int)TDengineDataType.TSDB_DATA_TYPE_BOOL; + bind.buffer = bo; + bind.buffer_length = length; + bind.length = lengPtr; + bind.is_null = IntPtr.Zero; + + return bind; + } + public static TAOS_BIND BindTinyInt(sbyte val) + { + TAOS_BIND bind = new TAOS_BIND(); + + byte[] tinyIntByteArr = BitConverter.GetBytes(val); + int tinyIntByteArrSize = Marshal.SizeOf(tinyIntByteArr[0]) * tinyIntByteArr.Length; + IntPtr uManageTinyInt = Marshal.AllocHGlobal(tinyIntByteArrSize); + Marshal.Copy(tinyIntByteArr, 0, uManageTinyInt, tinyIntByteArr.Length); + + int length = sizeof(sbyte); + IntPtr lengPtr = Marshal.AllocHGlobal(sizeof(int)); + Marshal.WriteInt32(lengPtr, length); + + bind.buffer_type = (int)TDengineDataType.TSDB_DATA_TYPE_TINYINT; + bind.buffer = uManageTinyInt; + bind.buffer_length = length; + bind.length = lengPtr; + bind.is_null = IntPtr.Zero; + return bind; + + } + + public static TAOS_BIND BindSmallInt(short val) + { + + TAOS_BIND bind = new TAOS_BIND(); + IntPtr uManageSmallInt = Marshal.AllocHGlobal(sizeof(short)); + Marshal.WriteInt16(uManageSmallInt, val); + + int length = sizeof(short); + IntPtr lengPtr = Marshal.AllocHGlobal(sizeof(int)); + Marshal.WriteInt32(lengPtr, length); + + bind.buffer_type = (int)TDengineDataType.TSDB_DATA_TYPE_SMALLINT; + bind.buffer = uManageSmallInt; + bind.buffer_length = length; + bind.length = lengPtr; + bind.is_null = IntPtr.Zero; + + return bind; + } + + public static TAOS_BIND BindInt(int val) + { + TAOS_BIND bind = new TAOS_BIND(); + IntPtr uManageInt = Marshal.AllocHGlobal(sizeof(int)); + Marshal.WriteInt32(uManageInt, val); + + int length = sizeof(int); + IntPtr lengPtr = Marshal.AllocHGlobal(sizeof(int)); + Marshal.WriteInt32(lengPtr, length); + + bind.buffer_type = (int)TDengineDataType.TSDB_DATA_TYPE_INT; + bind.buffer = uManageInt; + bind.buffer_length = length; + bind.length = lengPtr; + bind.is_null = IntPtr.Zero; + + return bind; + } + + public static TAOS_BIND BindBigInt(long val) + { + + TAOS_BIND bind = new TAOS_BIND(); + IntPtr uManageBigInt = Marshal.AllocHGlobal(sizeof(long)); + Marshal.WriteInt64(uManageBigInt, val); + + int length = sizeof(long); + IntPtr lengPtr = Marshal.AllocHGlobal(sizeof(int)); + Marshal.WriteInt32(lengPtr, length); + + bind.buffer_type = (int)TDengineDataType.TSDB_DATA_TYPE_BIGINT; + bind.buffer = uManageBigInt; + bind.buffer_length = length; + bind.length = lengPtr; + bind.is_null = IntPtr.Zero; + + return bind; + } + + public static TAOS_BIND BindUTinyInt(byte val) + { + TAOS_BIND bind = new TAOS_BIND(); + + IntPtr uManageTinyInt = Marshal.AllocHGlobal(sizeof(byte)); + Marshal.WriteByte(uManageTinyInt, val); + + int length = sizeof(byte); + IntPtr lengPtr = Marshal.AllocHGlobal(sizeof(int)); + Marshal.WriteInt32(lengPtr, length); + + bind.buffer_type = (int)TDengineDataType.TSDB_DATA_TYPE_UTINYINT; + bind.buffer = uManageTinyInt; + bind.buffer_length = length; + bind.length = lengPtr; + bind.is_null = IntPtr.Zero; + + return bind; + } + + public static TAOS_BIND BindUSmallInt(UInt16 val) + { + TAOS_BIND bind = new TAOS_BIND(); + + byte[] uSmallIntByteArr = BitConverter.GetBytes(val); + int usmallSize = Marshal.SizeOf(uSmallIntByteArr[0]) * uSmallIntByteArr.Length; + IntPtr uManageUnsignSmallInt = Marshal.AllocHGlobal(usmallSize); + Marshal.Copy(uSmallIntByteArr, 0, uManageUnsignSmallInt, uSmallIntByteArr.Length); + + int length = sizeof(UInt16); + IntPtr lengPtr = Marshal.AllocHGlobal(sizeof(int)); + Marshal.WriteInt32(lengPtr, length); + + bind.buffer_type = (int)TDengineDataType.TSDB_DATA_TYPE_USMALLINT; + bind.buffer = uManageUnsignSmallInt; + bind.buffer_length = length; + bind.length = lengPtr; + bind.is_null = IntPtr.Zero; + + return bind; + } + + public static TAOS_BIND BindUInt(uint val) + { + TAOS_BIND bind = new TAOS_BIND(); + + byte[] uManageIntByteArr = BitConverter.GetBytes(val); + int usmallSize = Marshal.SizeOf(uManageIntByteArr[0]) * uManageIntByteArr.Length; + IntPtr uManageInt = Marshal.AllocHGlobal(usmallSize); + Marshal.Copy(uManageIntByteArr, 0, uManageInt, uManageIntByteArr.Length); + + int length = sizeof(uint); + IntPtr lengPtr = Marshal.AllocHGlobal(sizeof(int)); + Marshal.WriteInt32(lengPtr, length); + + bind.buffer_type = (int)TDengineDataType.TSDB_DATA_TYPE_UINT; + bind.buffer = uManageInt; + bind.buffer_length = length; + bind.length = lengPtr; + bind.is_null = IntPtr.Zero; + + return bind; + } + + public static TAOS_BIND BindUBigInt(ulong val) + { + TAOS_BIND bind = new TAOS_BIND(); + + byte[] uManageBigIntByteArr = BitConverter.GetBytes(val); + int usmallSize = Marshal.SizeOf(uManageBigIntByteArr[0]) * uManageBigIntByteArr.Length; + IntPtr uManageBigInt = Marshal.AllocHGlobal(usmallSize); + Marshal.Copy(uManageBigIntByteArr, 0, uManageBigInt, uManageBigIntByteArr.Length); + + int length = sizeof(ulong); + IntPtr lengPtr = Marshal.AllocHGlobal(sizeof(int)); + Marshal.WriteInt32(lengPtr, length); + + bind.buffer_type = (int)TDengineDataType.TSDB_DATA_TYPE_UBIGINT; + bind.buffer = uManageBigInt; + bind.buffer_length = length; + bind.length = lengPtr; + bind.is_null = IntPtr.Zero; + + return bind; + } + + public static TAOS_BIND BindFloat(float val) + { + TAOS_BIND bind = new TAOS_BIND(); + + byte[] floatByteArr = BitConverter.GetBytes(val); + int floatByteArrSize = Marshal.SizeOf(floatByteArr[0]) * floatByteArr.Length; + IntPtr uManageFloat = Marshal.AllocHGlobal(floatByteArrSize); + Marshal.Copy(floatByteArr, 0, uManageFloat, floatByteArr.Length); + + int length = sizeof(float); + IntPtr lengPtr = Marshal.AllocHGlobal(sizeof(int)); + Marshal.WriteInt32(lengPtr, length); + + bind.buffer_type = (int)TDengineDataType.TSDB_DATA_TYPE_FLOAT; + bind.buffer = uManageFloat; + bind.buffer_length = length; + bind.length = lengPtr; + bind.is_null = IntPtr.Zero; + + return bind; + } + + public static TAOS_BIND BindDouble(Double val) + { + TAOS_BIND bind = new TAOS_BIND(); + + byte[] doubleByteArr = BitConverter.GetBytes(val); + int doubleByteArrSize = Marshal.SizeOf(doubleByteArr[0]) * doubleByteArr.Length; + IntPtr uManageDouble = Marshal.AllocHGlobal(doubleByteArrSize); + Marshal.Copy(doubleByteArr, 0, uManageDouble, doubleByteArr.Length); + + int length = sizeof(Double); + IntPtr lengPtr = Marshal.AllocHGlobal(sizeof(int)); + Marshal.WriteInt32(lengPtr, length); + + bind.buffer_type = (int)TDengineDataType.TSDB_DATA_TYPE_DOUBLE; + bind.buffer = uManageDouble; + bind.buffer_length = length; + bind.length = lengPtr; + bind.is_null = IntPtr.Zero; + + return bind; + } + + public static TAOS_BIND BindBinary(String val) + { + + TAOS_BIND bind = new TAOS_BIND(); + IntPtr umanageBinary = Marshal.StringToHGlobalAnsi(val); + + int leng = val.Length; + IntPtr lenPtr = Marshal.AllocHGlobal(sizeof(ulong)); + Marshal.WriteInt64(lenPtr, leng); + + bind.buffer_type = (int)TDengineDataType.TSDB_DATA_TYPE_BINARY; + bind.buffer = umanageBinary; + bind.buffer_length = leng; + bind.length = lenPtr; + bind.is_null = IntPtr.Zero; + + return bind; + } + public static TAOS_BIND BindNchar(String val) + { + TAOS_BIND bind = new TAOS_BIND(); + IntPtr umanageNchar = (IntPtr)Marshal.StringToHGlobalAnsi(val); + + int leng = val.Length; + IntPtr lenPtr = Marshal.AllocHGlobal(sizeof(ulong)); + Marshal.WriteInt64(lenPtr, leng); + + bind.buffer_type = (int)TDengineDataType.TSDB_DATA_TYPE_NCHAR; + bind.buffer = umanageNchar; + bind.buffer_length = leng; + bind.length = lenPtr; + bind.is_null = IntPtr.Zero; + + return bind; + } + + public static TAOS_BIND BindNil() + { + TAOS_BIND bind = new TAOS_BIND(); + + int isNull = 1;//IntPtr.Size; + IntPtr lenPtr = Marshal.AllocHGlobal(sizeof(int)); + Marshal.WriteInt32(lenPtr, isNull); + + bind.buffer_type = (int)TDengineDataType.TSDB_DATA_TYPE_NULL; + bind.is_null = lenPtr; + return bind; + } + + public static TAOS_BIND BindTimestamp(long ts) + { + + TAOS_BIND bind = new TAOS_BIND(); + IntPtr uManageTs = Marshal.AllocHGlobal(sizeof(long)); + Marshal.WriteInt64(uManageTs, ts); + + int length = sizeof(long); + IntPtr lengPtr = Marshal.AllocHGlobal(4); + Marshal.WriteInt32(lengPtr, length); + + bind.buffer_type = (int)TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP; + bind.buffer = uManageTs; + bind.buffer_length = length; + bind.length = lengPtr; + bind.is_null = IntPtr.Zero; + + return bind; + + } + + public static void FreeTaosBind(TAOS_BIND[] binds) + { + foreach (TAOS_BIND bind in binds) + { + Marshal.FreeHGlobal(bind.buffer); + Marshal.FreeHGlobal(bind.length); + if (bind.is_null != IntPtr.Zero) + { + // Console.WriteLine(bind.is_null); + Marshal.FreeHGlobal(bind.is_null); + } + + } + } + } + +} \ No newline at end of file diff --git a/tests/system-test/3-connectors/c#/TDengineDriver/TaosMultiBind.cs b/tests/system-test/3-connectors/c#/TDengineDriver/TaosMultiBind.cs new file mode 100644 index 0000000000..e01558caeb --- /dev/null +++ b/tests/system-test/3-connectors/c#/TDengineDriver/TaosMultiBind.cs @@ -0,0 +1,616 @@ +using System; +using System.Text; +using System.Runtime.InteropServices; + + +namespace TDengineDriver +{ + public class TaosMultiBind + { + public static TAOS_MULTI_BIND MultiBindBool(bool?[] arr) + { + TAOS_MULTI_BIND multiBind = new TAOS_MULTI_BIND(); + int elementCount = arr.Length; + //the size of buffer array element + int typeSize = sizeof(bool); + //size of int + int intSize = sizeof(int); + int byteSize = sizeof(byte); + + //TAOS_MULTI_BIND.buffer + IntPtr unmanagedBoolArr = Marshal.AllocHGlobal(elementCount * typeSize); + //TAOS_MULTI_BIND.length + IntPtr lengthArr = Marshal.AllocHGlobal(intSize * elementCount); + //TAOS_MULTI_BIND.is_null + IntPtr nullArr = Marshal.AllocHGlobal(byteSize * elementCount); + + for (int i = 0; i < elementCount; i++) + { + //set TAOS_MULTI_BIND.buffer + Marshal.WriteByte(unmanagedBoolArr, typeSize * i, Convert.ToByte(arr[i] ?? false)); + //set TAOS_MULTI_BIND.length + Marshal.WriteInt32(lengthArr, intSize * i, typeSize); + //set TAOS_MULTI_BIND.is_null + Marshal.WriteByte(nullArr, byteSize * i, Convert.ToByte(arr[i].Equals(null) ? 1 : 0)); + } + //config TAOS_MULTI_BIND + multiBind.buffer_type = (int)TDengineDataType.TSDB_DATA_TYPE_BOOL; + multiBind.buffer = unmanagedBoolArr; + multiBind.buffer_length = (ulong)typeSize; + multiBind.length = lengthArr; + multiBind.is_null = nullArr; + multiBind.num = elementCount; + + return multiBind; + } + public static TAOS_MULTI_BIND MultiBindTinyInt(sbyte?[] arr) + { + TAOS_MULTI_BIND multiBind = new TAOS_MULTI_BIND(); + int elementCount = arr.Length; + //the size of buffer array element + int typeSize = sizeof(byte); + int byteSize = sizeof(byte); + //size of int + int intSize = sizeof(int); + + //TAOS_MULTI_BIND.buffer + IntPtr unmanagedTintIntArr = Marshal.AllocHGlobal(elementCount); + //TAOS_MULTI_BIND.length + IntPtr lengthArr = Marshal.AllocHGlobal(intSize * elementCount); + //TAOS_MULTI_BIND.is_null + IntPtr nullArr = Marshal.AllocHGlobal(intSize * elementCount); + + for (int i = 0; i < elementCount; i++) + { + Byte[] toByteArr = BitConverter.GetBytes(arr[i] ?? sbyte.MinValue); + + //set TAOS_MULTI_BIND.buffer + Marshal.WriteByte(unmanagedTintIntArr, typeSize * i, toByteArr[0]); + //set TAOS_MULTI_BIND.length + Marshal.WriteInt32(lengthArr, intSize * i, typeSize); + //set TAOS_MULTI_BIND.is_null + Marshal.WriteByte(nullArr, byteSize * i, Convert.ToByte(arr[i].Equals(null) ? 1 : 0)); + } + + //config TAOS_MULTI_BIND + multiBind.buffer_type = (int)TDengineDataType.TSDB_DATA_TYPE_TINYINT; + multiBind.buffer = unmanagedTintIntArr; + multiBind.buffer_length = (ulong)typeSize; + multiBind.length = lengthArr; + multiBind.is_null = nullArr; + multiBind.num = elementCount; + + return multiBind; + } + public static TAOS_MULTI_BIND MultiBindSmallInt(short?[] arr) + { + TAOS_MULTI_BIND multiBind = new TAOS_MULTI_BIND(); + int elementCount = arr.Length; + //the size of buffer array element + int typeSize = sizeof(short); + //size of int + int intSize = sizeof(int); + int byteSize = sizeof(byte); + + //TAOS_MULTI_BIND.buffer + IntPtr unmanagedSmallIntArr = Marshal.AllocHGlobal(elementCount * typeSize); + //TAOS_MULTI_BIND.length + IntPtr lengthArr = Marshal.AllocHGlobal(intSize * elementCount); + //TAOS_MULTI_BIND.is_null + IntPtr nullArr = Marshal.AllocHGlobal(byteSize * elementCount); + + for (int i = 0; i < elementCount; i++) + { + //set TAOS_MULTI_BIND.buffer + Marshal.WriteInt16(unmanagedSmallIntArr, typeSize * i, arr[i] ?? short.MinValue); + //set TAOS_MULTI_BIND.length + Marshal.WriteInt32(lengthArr, intSize * i, typeSize); + //set TAOS_MULTI_BIND.is_null + Marshal.WriteByte(nullArr, byteSize * i, Convert.ToByte(arr[i].Equals(null) ? 1 : 0)); + + } + //config TAOS_MULTI_BIND + multiBind.buffer_type = (int)TDengineDataType.TSDB_DATA_TYPE_SMALLINT; + multiBind.buffer = unmanagedSmallIntArr; + multiBind.buffer_length = (ulong)typeSize; + multiBind.length = lengthArr; + multiBind.is_null = nullArr; + multiBind.num = elementCount; + + return multiBind; + } + public static TAOS_MULTI_BIND MultiBindInt(int?[] arr) + { + TAOS_MULTI_BIND multiBind = new TAOS_MULTI_BIND(); + int elementCount = arr.Length; + int typeSize = sizeof(int); + int intSize = sizeof(int); + int byteSize = sizeof(byte); + + //TAOS_MULTI_BIND.buffer + IntPtr intBuff = Marshal.AllocHGlobal(typeSize * elementCount); + //TAOS_MULTI_BIND.length + IntPtr lengthArr = Marshal.AllocHGlobal(intSize * elementCount); + //TAOS_MULTI_BIND.is_null + IntPtr nullArr = Marshal.AllocHGlobal(byteSize * elementCount); + + for (int i = 0; i < elementCount; i++) + { + //set TAOS_MULTI_BIND.buffer + Marshal.WriteInt32(intBuff, typeSize * i, arr[i] ?? int.MinValue); + //set TAOS_MULTI_BIND.length + Marshal.WriteInt32(lengthArr, intSize * i, typeSize); + //set TAOS_MULTI_BIND.is_null + Marshal.WriteByte(nullArr, byteSize * i, Convert.ToByte(arr[i].Equals(null) ? 1 : 0)); + + } + //config TAOS_MULTI_BIND + multiBind.buffer_type = (int)TDengineDataType.TSDB_DATA_TYPE_INT; + multiBind.buffer = intBuff; + multiBind.buffer_length = (ulong)typeSize; + multiBind.length = lengthArr; + multiBind.is_null = nullArr; + multiBind.num = elementCount; + + return multiBind; + } + public static TAOS_MULTI_BIND MultiBindBigint(long?[] arr) + { + TAOS_MULTI_BIND multiBind = new TAOS_MULTI_BIND(); + int elementCount = arr.Length; + int typeSize = sizeof(long); + int intSize = sizeof(int); + int byteSize = sizeof(byte); + + //TAOS_MULTI_BIND.buffer + IntPtr intBuff = Marshal.AllocHGlobal(typeSize * elementCount); + //TAOS_MULTI_BIND.length + IntPtr lengthArr = Marshal.AllocHGlobal(intSize * elementCount); + //TAOS_MULTI_BIND.is_null + IntPtr nullArr = Marshal.AllocHGlobal(byteSize * elementCount); + + for (int i = 0; i < elementCount; i++) + { + //set TAOS_MULTI_BIND.buffer + Marshal.WriteInt64(intBuff, typeSize * i, arr[i] ?? long.MinValue); + //set TAOS_MULTI_BIND.length + Marshal.WriteInt32(lengthArr, intSize * i, typeSize); + //set TAOS_MULTI_BIND.is_null + Marshal.WriteByte(nullArr, byteSize * i, Convert.ToByte(arr[i].Equals(null) ? 1 : 0)); + + + } + //config TAOS_MULTI_BIND + multiBind.buffer_type = (int)TDengineDataType.TSDB_DATA_TYPE_BIGINT; + multiBind.buffer = intBuff; + multiBind.buffer_length = (ulong)typeSize; + multiBind.length = lengthArr; + multiBind.is_null = nullArr; + multiBind.num = elementCount; + + return multiBind; + } + public static TAOS_MULTI_BIND MultiBindFloat(float?[] arr) + { + TAOS_MULTI_BIND multiBind = new TAOS_MULTI_BIND(); + int elementCount = arr.Length; + int typeSize = sizeof(float); + int intSize = sizeof(int); + int byteSize = sizeof(byte); + //used to replace null + float[] arrTmp = new float[elementCount]; + + //TAOS_MULTI_BIND.buffer + IntPtr floatBuff = Marshal.AllocHGlobal(typeSize * elementCount); + //TAOS_MULTI_BIND.length + IntPtr lengthArr = Marshal.AllocHGlobal(intSize * elementCount); + //TAOS_MULTI_BIND.is_null + IntPtr nullArr = Marshal.AllocHGlobal(byteSize * elementCount); + + + for (int i = 0; i < elementCount; i++) + { + arrTmp[i] = arr[i] ?? float.MinValue; + //set TAOS_MULTI_BIND.length + Marshal.WriteInt32(lengthArr, intSize * i, typeSize); + //set TAOS_MULTI_BIND.is_null + Marshal.WriteByte(nullArr, byteSize * i, Convert.ToByte(arr[i].Equals(null) ? 1 : 0)); + } + //set TAOS_MULTI_BIND.buffer + Marshal.Copy(arrTmp, 0, floatBuff, elementCount); + + //config TAOS_MULTI_BIND + multiBind.buffer_type = (int)TDengineDataType.TSDB_DATA_TYPE_FLOAT; + multiBind.buffer = floatBuff; + multiBind.buffer_length = (ulong)typeSize; + multiBind.length = lengthArr; + multiBind.is_null = nullArr; + multiBind.num = elementCount; + + return multiBind; + } + public static TAOS_MULTI_BIND MultiBindDouble(double?[] arr) + { + TAOS_MULTI_BIND multiBind = new TAOS_MULTI_BIND(); + int elementCount = arr.Length; + int typeSize = sizeof(double); + int intSize = sizeof(int); + int byteSize = sizeof(byte); + //used to replace null + double[] arrTmp = new double[elementCount]; + + //TAOS_MULTI_BIND.buffer + IntPtr doubleBuff = Marshal.AllocHGlobal(typeSize * elementCount); + //TAOS_MULTI_BIND.length + IntPtr lengthArr = Marshal.AllocHGlobal(intSize * elementCount); + //TAOS_MULTI_BIND.is_null + IntPtr nullArr = Marshal.AllocHGlobal(byteSize * elementCount); + + + for (int i = 0; i < elementCount; i++) + { + arrTmp[i] = arr[i] ?? double.MinValue; + //set TAOS_MULTI_BIND.length + Marshal.WriteInt32(lengthArr, intSize * i, typeSize); + //set TAOS_MULTI_BIND.is_null + Marshal.WriteByte(nullArr, byteSize * i, Convert.ToByte(arr[i].Equals(null) ? 1 : 0)); + } + //set TAOS_MULTI_BIND.buffer + Marshal.Copy(arrTmp, 0, doubleBuff, elementCount); + + //config TAOS_MULTI_BIND + multiBind.buffer_type = (int)TDengineDataType.TSDB_DATA_TYPE_DOUBLE; + multiBind.buffer = doubleBuff; + multiBind.buffer_length = (ulong)typeSize; + multiBind.length = lengthArr; + multiBind.is_null = nullArr; + multiBind.num = elementCount; + + return multiBind; + } + public static TAOS_MULTI_BIND MultiBindUTinyInt(byte?[] arr) + { + TAOS_MULTI_BIND multiBind = new TAOS_MULTI_BIND(); + int elementCount = arr.Length; + int typeSize = sizeof(byte); + int intSize = sizeof(int); + int byteSize = sizeof(byte); + //used to replace null + + //TAOS_MULTI_BIND.buffer + IntPtr uTinyIntBuff = Marshal.AllocHGlobal(typeSize * elementCount); + //TAOS_MULTI_BIND.length + IntPtr lengthArr = Marshal.AllocHGlobal(intSize * elementCount); + //TAOS_MULTI_BIND.is_null + IntPtr nullArr = Marshal.AllocHGlobal(byteSize * elementCount); + + + for (int i = 0; i < elementCount; i++) + { + //set TAOS_MULTI_BIND.buffer + Marshal.WriteByte(uTinyIntBuff, typeSize * i, arr[i] ?? byte.MaxValue); + //set TAOS_MULTI_BIND.length + Marshal.WriteInt32(lengthArr, intSize * i, typeSize); + //set TAOS_MULTI_BIND.is_null + Marshal.WriteByte(nullArr, byteSize * i, Convert.ToByte(arr[i].Equals(null) ? 1 : 0)); + } + + + //config TAOS_MULTI_BIND + multiBind.buffer_type = (int)TDengineDataType.TSDB_DATA_TYPE_UTINYINT; + multiBind.buffer = uTinyIntBuff; + multiBind.buffer_length = (ulong)typeSize; + multiBind.length = lengthArr; + multiBind.is_null = nullArr; + multiBind.num = elementCount; + + return multiBind; + } + public static TAOS_MULTI_BIND MultiBindUSmallInt(ushort?[] arr) + { + TAOS_MULTI_BIND multiBind = new TAOS_MULTI_BIND(); + int elementCount = arr.Length; + int typeSize = sizeof(ushort); + int intSize = sizeof(int); + int byteSize = sizeof(byte); + //used to replace null + + //TAOS_MULTI_BIND.buffer + IntPtr uSmallIntBuff = Marshal.AllocHGlobal(typeSize * elementCount); + //TAOS_MULTI_BIND.length + IntPtr lengthArr = Marshal.AllocHGlobal(intSize * elementCount); + //TAOS_MULTI_BIND.is_null + IntPtr nullArr = Marshal.AllocHGlobal(byteSize * elementCount); + + + for (int i = 0; i < elementCount; i++) + { + byte[] byteArr = BitConverter.GetBytes(arr[i] ?? ushort.MaxValue); + for (int j = 0; j < byteArr.Length; j++) + { + //set TAOS_MULTI_BIND.buffer + Marshal.WriteByte(uSmallIntBuff, typeSize * i + j * byteSize, byteArr[j]); + } + //set TAOS_MULTI_BIND.length + Marshal.WriteInt32(lengthArr, intSize * i, typeSize); + //set TAOS_MULTI_BIND.is_null + Marshal.WriteByte(nullArr, byteSize * i, Convert.ToByte(arr[i].Equals(null) ? 1 : 0)); + } + + + //config TAOS_MULTI_BIND + multiBind.buffer_type = (int)TDengineDataType.TSDB_DATA_TYPE_USMALLINT; + multiBind.buffer = uSmallIntBuff; + multiBind.buffer_length = (ulong)typeSize; + multiBind.length = lengthArr; + multiBind.is_null = nullArr; + multiBind.num = elementCount; + + return multiBind; + } + public static TAOS_MULTI_BIND MultiBindUInt(uint?[] arr) + { + TAOS_MULTI_BIND multiBind = new TAOS_MULTI_BIND(); + int elementCount = arr.Length; + int typeSize = sizeof(uint); + int intSize = sizeof(int); + int byteSize = sizeof(byte); + //used to replace null + + //TAOS_MULTI_BIND.buffer + IntPtr uIntBuff = Marshal.AllocHGlobal(typeSize * elementCount); + //TAOS_MULTI_BIND.length + IntPtr lengthArr = Marshal.AllocHGlobal(intSize * elementCount); + //TAOS_MULTI_BIND.is_null + IntPtr nullArr = Marshal.AllocHGlobal(byteSize * elementCount); + + + for (int i = 0; i < elementCount; i++) + { + byte[] byteArr = BitConverter.GetBytes(arr[i] ?? uint.MaxValue); + for (int j = 0; j < byteArr.Length; j++) + { + //set TAOS_MULTI_BIND.buffer + Marshal.WriteByte(uIntBuff, typeSize * i + j * byteSize, byteArr[j]); + } + //set TAOS_MULTI_BIND.length + Marshal.WriteInt32(lengthArr, intSize * i, typeSize); + //set TAOS_MULTI_BIND.is_null + Marshal.WriteByte(nullArr, byteSize * i, Convert.ToByte(arr[i].Equals(null) ? 1 : 0)); + } + + + //config TAOS_MULTI_BIND + multiBind.buffer_type = (int)TDengineDataType.TSDB_DATA_TYPE_UINT; + multiBind.buffer = uIntBuff; + multiBind.buffer_length = (ulong)typeSize; + multiBind.length = lengthArr; + multiBind.is_null = nullArr; + multiBind.num = elementCount; + + return multiBind; + } + public static TAOS_MULTI_BIND MultiBindUBigInt(ulong?[] arr) + { + TAOS_MULTI_BIND multiBind = new TAOS_MULTI_BIND(); + int elementCount = arr.Length; + int typeSize = sizeof(ulong); + int intSize = sizeof(int); + int byteSize = sizeof(byte); + //used to replace null + + //TAOS_MULTI_BIND.buffer + IntPtr uBigIntBuff = Marshal.AllocHGlobal(typeSize * elementCount); + //TAOS_MULTI_BIND.length + IntPtr lengthArr = Marshal.AllocHGlobal(intSize * elementCount); + //TAOS_MULTI_BIND.is_null + IntPtr nullArr = Marshal.AllocHGlobal(byteSize * elementCount); + + + for (int i = 0; i < elementCount; i++) + { + byte[] byteArr = BitConverter.GetBytes(arr[i] ?? ulong.MaxValue); + for (int j = 0; j < byteArr.Length; j++) + { + //set TAOS_MULTI_BIND.buffer + Marshal.WriteByte(uBigIntBuff, typeSize * i + j * byteSize, byteArr[j]); + } + //set TAOS_MULTI_BIND.length + Marshal.WriteInt32(lengthArr, intSize * i, typeSize); + //set TAOS_MULTI_BIND.is_null + Marshal.WriteByte(nullArr, byteSize * i, Convert.ToByte(arr[i].Equals(null) ? 1 : 0)); + } + + + //config TAOS_MULTI_BIND + multiBind.buffer_type = (int)TDengineDataType.TSDB_DATA_TYPE_UBIGINT; + multiBind.buffer = uBigIntBuff; + multiBind.buffer_length = (ulong)typeSize; + multiBind.length = lengthArr; + multiBind.is_null = nullArr; + multiBind.num = elementCount; + + return multiBind; + } + public static TAOS_MULTI_BIND MultiBindBinary(string[] arr) + { + TAOS_MULTI_BIND multiBind = new TAOS_MULTI_BIND(); + int elementCount = arr.Length; + int typeSize = MaxElementLength(arr); + int intSize = sizeof(int); + int byteSize = sizeof(byte); + StringBuilder arrStrBuilder = new StringBuilder(); ; + + //TAOS_MULTI_BIND.length + IntPtr lengthArr = Marshal.AllocHGlobal(intSize * elementCount); + //TAOS_MULTI_BIND.is_null + IntPtr nullArr = Marshal.AllocHGlobal(byteSize * elementCount); + + for (int i = 0; i < elementCount; i++) + { + int itemLength = 0; + // if element if not null and element length is less then typeSize + // fill the memory with default char.Since arr element memory need align. + if (!String.IsNullOrEmpty(arr[i]) && typeSize <= arr[i].Length) + { + itemLength = arr[i].Length; + arrStrBuilder.Append(arr[i]); + } + else if (!String.IsNullOrEmpty(arr[i]) && typeSize > arr[i].Length) + { + itemLength = arr[i].Length; + arrStrBuilder.Append(arr[i]); + arrStrBuilder.Append(AlignCharArr(typeSize - arr[i].Length)); + } + else + { + // if is null value,fill the memory with default values. + itemLength = 0; + arrStrBuilder.Append(AlignCharArr(typeSize)); + } + + //set TAOS_MULTI_BIND.length + Marshal.WriteInt32(lengthArr, intSize * i, itemLength); + //set TAOS_MULTI_BIND.is_null + Marshal.WriteByte(nullArr, byteSize * i, Convert.ToByte(String.IsNullOrEmpty(arr[i]) ? 1 : 0)); + } + //set TAOS_MULTI_BIND.buffer + IntPtr uBinaryBuff = (IntPtr)Marshal.StringToHGlobalAnsi(arrStrBuilder.ToString()); + + //config TAOS_MULTI_BIND + multiBind.buffer_type = (int)TDengineDataType.TSDB_DATA_TYPE_BINARY; + multiBind.buffer = uBinaryBuff; + multiBind.buffer_length = (ulong)typeSize; + multiBind.length = lengthArr; + multiBind.is_null = nullArr; + multiBind.num = elementCount; + + return multiBind; + } + + public static TAOS_MULTI_BIND MultiBindNchar(string[] arr) + { + TAOS_MULTI_BIND multiBind = new TAOS_MULTI_BIND(); + int elementCount = arr.Length; + int typeSize = MaxElementLength(arr); + int intSize = sizeof(int); + int byteSize = sizeof(byte); + StringBuilder arrStrBuilder = new StringBuilder(); ; + + //TAOS_MULTI_BIND.length + IntPtr lengthArr = Marshal.AllocHGlobal(intSize * elementCount); + //TAOS_MULTI_BIND.is_null + IntPtr nullArr = Marshal.AllocHGlobal(byteSize * elementCount); + + for (int i = 0; i < elementCount; i++) + { + int itemLength = 0; + // if element if not null and element length is less then typeSize + // fill the memory with default char.Since arr element memory need align. + if (!String.IsNullOrEmpty(arr[i]) && typeSize <= arr[i].Length) + { + itemLength = arr[i].Length; + arrStrBuilder.Append(arr[i]); + } + else if (!String.IsNullOrEmpty(arr[i]) && typeSize > arr[i].Length) + { + itemLength = arr[i].Length; + arrStrBuilder.Append(arr[i]); + arrStrBuilder.Append(AlignCharArr(typeSize - arr[i].Length)); + } + else + { + // if is null value,fill the memory with default values. + itemLength = 0; + arrStrBuilder.Append(AlignCharArr(typeSize)); + } + + //set TAOS_MULTI_BIND.length + Marshal.WriteInt32(lengthArr, intSize * i, itemLength); + //set TAOS_MULTI_BIND.is_null + Marshal.WriteByte(nullArr, byteSize * i, Convert.ToByte(String.IsNullOrEmpty(arr[i]) ? 1 : 0)); + } + //set TAOS_MULTI_BIND.buffer + IntPtr uNcharBuff = (IntPtr)Marshal.StringToHGlobalAnsi(arrStrBuilder.ToString()); + + //config TAOS_MULTI_BIND + multiBind.buffer_type = (int)TDengineDataType.TSDB_DATA_TYPE_NCHAR; + multiBind.buffer = uNcharBuff; + multiBind.buffer_length = (ulong)typeSize; + multiBind.length = lengthArr; + multiBind.is_null = nullArr; + multiBind.num = elementCount; + + return multiBind; + } + + public static TAOS_MULTI_BIND MultiBindTimestamp(long[] arr) + { + TAOS_MULTI_BIND multiBind = new TAOS_MULTI_BIND(); + int elementCount = arr.Length; + int typeSize = sizeof(long); + int intSize = sizeof(int); + int byteSize = sizeof(byte); + //TAOS_MULTI_BIND.buffer + IntPtr unmanagedTsArr = Marshal.AllocHGlobal(typeSize * elementCount); + //TAOS_MULTI_BIND.length + IntPtr lengthArr = Marshal.AllocHGlobal(intSize * elementCount); + //TAOS_MULTI_BIND.is_null + IntPtr nullArr = Marshal.AllocHGlobal(byteSize * elementCount); + + for (int i = 0; i < elementCount; i++) + { + //set TAOS_MULTI_BIND.buffer + Marshal.WriteInt64(unmanagedTsArr, typeSize * i, arr[i]); + //set TAOS_MULTI_BIND.length + Marshal.WriteInt32(lengthArr, intSize * i, typeSize); + //set TAOS_MULTI_BIND.is_null + Marshal.WriteByte(nullArr, byteSize * i, 0); + } + + //config TAOS_MULTI_BIND + multiBind.buffer_type = (int)TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP; + multiBind.buffer = unmanagedTsArr; + multiBind.buffer_length = (ulong)typeSize; + multiBind.length = lengthArr; + multiBind.is_null = nullArr; + multiBind.num = elementCount; + + return multiBind; + } + + public static void FreeTaosBind(TAOS_MULTI_BIND[] mBinds) + { + foreach (TAOS_MULTI_BIND bind in mBinds) + { + Marshal.FreeHGlobal(bind.buffer); + Marshal.FreeHGlobal(bind.length); + Marshal.FreeHGlobal(bind.is_null); + } + } + + private static char[] AlignCharArr(int offSet) + { + char[] alignChar = new char[offSet]; + for (int i = 0; i < offSet; i++) + { + alignChar[i] = char.MinValue; + } + return alignChar; + } + + private static int MaxElementLength(String[] strArr) + { + int max = 0; + for (int i = 0; i < strArr.Length; i++) + { + if (!String.IsNullOrEmpty(strArr[i]) && max < strArr[i].Length) + { + max = strArr[i].Length; + } + } + return max; + } + } + +} \ No newline at end of file diff --git a/tests/system-test/3-connectors/c#/stmtfunction/stmtfunction.cs b/tests/system-test/3-connectors/c#/stmtfunction/stmtfunction.cs new file mode 100644 index 0000000000..5a4da65ce7 --- /dev/null +++ b/tests/system-test/3-connectors/c#/stmtfunction/stmtfunction.cs @@ -0,0 +1,668 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * 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 . + */ +using System; +using System.Text; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Collections; +namespace TDengineDriver +{ + public class stmtfunction + { + //connection parameters + private string host = "127.0.0.1"; + private string configDir = "/etc/taos"; + private string user = "root"; + private string passwd = "taosdata"; + private short port = 6030; + + private IntPtr conn = IntPtr.Zero; + private IntPtr stmt = IntPtr.Zero; + + //prepare the tags value + //Integer + public TAOS_BIND[] InitBindArr1() + { + TAOS_BIND[] binds = new TAOS_BIND[4]; + + binds[0] = TaosBind.BindTinyInt(-2); + binds[1] = TaosBind.BindSmallInt(short.MaxValue); + binds[2] = TaosBind.BindInt(int.MaxValue); + binds[3] = TaosBind.BindBigInt(Int64.MaxValue); + + return binds; + } + + //unsigned Integer + public TAOS_BIND[] InitBindArr2() + { + TAOS_BIND[] binds = new TAOS_BIND[4]; + + binds[0] = TaosBind.BindUTinyInt(byte.MaxValue - 1); + binds[1] = TaosBind.BindUSmallInt(UInt16.MaxValue - 1); + binds[2] = TaosBind.BindUInt(uint.MinValue + 1); + binds[3] = TaosBind.BindUBigInt(UInt64.MinValue + 1); + + return binds; + } + + //float and double + public TAOS_BIND[] InitBindArr3() + { + TAOS_BIND[] binds = new TAOS_BIND[6]; + + binds[0] = TaosBind.BindFloat(11.11F); + binds[1] = TaosBind.BindFloat(float.MinValue+1); + binds[2] = TaosBind.BindFloat(float.MaxValue-1); + binds[3] = TaosBind.BindDouble(22.22D); + binds[4] = TaosBind.BindDouble(double.MinValue+1); + binds[5] = TaosBind.BindDouble(double.MaxValue-1); + + + return binds; + } + + //binary and nchar + public TAOS_BIND[] InitBindArr4() + { + TAOS_BIND[] binds = new TAOS_BIND[2]; + string a = "abcdABCD123`~!@#$%^&*()-=+_[]{}:;\",.<>/?\\\\'"; + string b = "abcdABCD123`~!@#$%^&*()-=+_[]{}:;\",.<>/?taos涛思"; + + //Console.WriteLine(a); + //Console.WriteLine(b); + binds[0] = TaosBind.BindBinary(a); + binds[1] = TaosBind.BindNchar(b); + + return binds; + } + + //prepare the column values + //Integer + public TAOS_MULTI_BIND[] InitMultBindArr1() + { + TAOS_MULTI_BIND[] mBinds = new TAOS_MULTI_BIND[5]; + long[] tsArr = new long[5] { 1637064040000, 1637064041000, 1637064042000, 1637064043000, 1637064044000 }; + sbyte?[] tinyIntArr = new sbyte?[5] { -127, 0, null, 8, 127 }; + short?[] shortArr = new short?[5] { short.MinValue + 1, -200, null, 100, short.MaxValue }; + int?[] intArr = new int?[5] { -200, -100, null, 0, 300 }; + long?[] longArr = new long?[5] { long.MinValue + 1, -2000, null, 1000, long.MaxValue }; + + mBinds[0] = TaosMultiBind.MultiBindTimestamp(tsArr); + mBinds[1] = TaosMultiBind.MultiBindTinyInt(tinyIntArr); + mBinds[2] = TaosMultiBind.MultiBindSmallInt(shortArr); + mBinds[3] = TaosMultiBind.MultiBindInt(intArr); + mBinds[4] = TaosMultiBind.MultiBindBigint(longArr); + + return mBinds; + } + //Unsigned Integer + public TAOS_MULTI_BIND[] InitMultBindArr2() + { + TAOS_MULTI_BIND[] mBinds = new TAOS_MULTI_BIND[5]; + long[] tsArr = new long[5] { 1637064040000, 1637064041000, 1637064042000, 1637064043000, 1637064044000 }; + byte?[] uTinyIntArr = new byte?[5] { byte.MinValue, 0, null, 89, byte.MaxValue - 1 }; + ushort?[] uShortArr = new ushort?[5] { ushort.MinValue, 0, null, 400, ushort.MaxValue - 1 }; + uint?[] uIntArr = new uint?[5] { uint.MinValue, 0, null, 2001, uint.MaxValue - 1 }; + ulong?[] uLongArr = new ulong?[5] { ulong.MinValue, 0, null, 1000, long.MaxValue - 1 }; + + mBinds[0] = TaosMultiBind.MultiBindTimestamp(tsArr); + mBinds[1] = TaosMultiBind.MultiBindUTinyInt(uTinyIntArr); + mBinds[2] = TaosMultiBind.MultiBindUSmallInt(uShortArr); + mBinds[3] = TaosMultiBind.MultiBindUInt(uIntArr); + mBinds[4] = TaosMultiBind.MultiBindUBigInt(uLongArr); + + return mBinds; + } + //float and double + public TAOS_MULTI_BIND[] InitMultBindArr3() + { + TAOS_MULTI_BIND[] mBinds = new TAOS_MULTI_BIND[3]; + long[] tsArr = new long[5] { 1637064040000, 1637064041000, 1637064042000, 1637064043000, 1637064044000 }; + float?[] floatArr = new float?[5] { float.MinValue + 1, -12.1F, null, 0F, float.MaxValue }; + double?[] doubleArr = new double?[5] { double.MinValue + 1, -19.112D, null, 0D, double.MaxValue }; + + mBinds[0] = TaosMultiBind.MultiBindTimestamp(tsArr); + mBinds[1] = TaosMultiBind.MultiBindFloat(floatArr); + mBinds[2] = TaosMultiBind.MultiBindDouble(doubleArr); + + + return mBinds; + } + //binary and nchar + public TAOS_MULTI_BIND[] InitMultBindArr4() + { + TAOS_MULTI_BIND[] mBinds = new TAOS_MULTI_BIND[3]; + long[] tsArr = new long[3] { 1637064040000, 1637064041000, 1637064042000}; + string[] binaryArr = new string[3] { "abcdABCD123`~!@#$%^&*()-=+_[]{}:;\",.<>/?", String.Empty, null}; + string[] ncharArr = new string[3] { "abcdABCD123`~!@#$%^&*()-=+_[]{}:;\",.<>/?涛思", null, string.Empty }; + + mBinds[0] = TaosMultiBind.MultiBindTimestamp(tsArr); + mBinds[1] = TaosMultiBind.MultiBindBinary(binaryArr); + mBinds[2] = TaosMultiBind.MultiBindNchar(ncharArr); + + return mBinds; + } + + static void Main(string[] args) + { + stmtfunction test = new stmtfunction(); + Console.WriteLine("---------------------------------------------------------------"); + Console.WriteLine("Start Stmtfunction case1 insert Testing..."); + Console.WriteLine("---------------------------------------------------------------"); + //Init and connect TDengine + test.InitTDengine(); + test.ConnectTDengine(); + //create database + test.executeQuery("drop database if exists csharptest"); + test.executeQuery("create database if not exists csharptest "); + test.executeQuery("use csharptest"); + test.executeQuery("drop table if exists stmttest"); + //case1:tinyint,smallint,int,bigint + string createTable1 = "create stable stmttest1 (ts timestamp,c1 tinyint,c2 smallint,c3 int,c4 bigint) tags(t1 tinyint,t2 smallint,t3 int,t4 bigint)"; + test.executeQuery(createTable1); + test.StmtInit(); + test.StmtPrepare("insert into ? using stmttest1 tags(?,?,?,?) values(?,?,?,?,?)"); + TAOS_BIND[] Ibinds = test.InitBindArr1(); + TAOS_MULTI_BIND[] Imbinds = test.InitMultBindArr1(); + test.SetTableNameTags("t1",Ibinds); + test.BindParamBatch(Imbinds); + test.AddBatch(); + test.StmtExecute(); + TaosBind.FreeTaosBind(Ibinds); + TaosMultiBind.FreeTaosBind(Imbinds); + test.StmtClose(); + //select + Console.WriteLine("---------------------------------------------------------------"); + Console.WriteLine("start Stmtfunction case1 select Testing..."); + Console.WriteLine("---------------------------------------------------------------"); + test.StmtInit(); + test.StmtPrepare("select * from t1 where c1>? and c2 >?"); + TAOS_BIND[] queryCondition1 = new TAOS_BIND[2]; + queryCondition1[0] = TaosBind.BindTinyInt(0); + queryCondition1[1] = TaosBind.BindInt(100); + test.BindParam(queryCondition1); + test.StmtExecute(); + test.StmtUseResult(); + test.StmtClose(); + TaosBind.FreeTaosBind(queryCondition1); + Console.WriteLine("---------------------------------------------------------------"); + Console.WriteLine("Stop Stmtfunction case1 Testing..."); + Console.WriteLine("---------------------------------------------------------------"); + + // //case2:utinyint,usmallint,uint,ubigint + string createTable2 = "create stable stmttest2 (ts timestamp,c1 tinyint unsigned,c2 smallint unsigned,c3 int unsigned,c4 bigint unsigned)" + +" tags(t1 tinyint unsigned,t2 smallint unsigned,t3 int unsigned,t4 bigint unsigned)"; + test.executeQuery(createTable2); + test.StmtInit(); + test.StmtPrepare("insert into ? using stmttest2 tags(?,?,?,?) values(?,?,?,?,?)"); + TAOS_BIND[] Ubinds = test.InitBindArr2(); + TAOS_MULTI_BIND[] Umbinds = test.InitMultBindArr2(); + test.SetTableNameTags("t2",Ubinds); + test.BindParamBatch(Umbinds); + test.AddBatch(); + test.StmtExecute(); + TaosBind.FreeTaosBind(Ubinds); + TaosMultiBind.FreeTaosBind(Umbinds); + test.StmtClose(); + //select + Console.WriteLine("---------------------------------------------------------------"); + Console.WriteLine("start Stmtfunction case2 select Testing..."); + Console.WriteLine("---------------------------------------------------------------"); + test.StmtInit(); + test.StmtPrepare("select * from t2 where c1>? and c3 >?"); + TAOS_BIND[] queryCondition2 = new TAOS_BIND[2]; + queryCondition2[0] = TaosBind.BindUTinyInt(80); + queryCondition2[1] = TaosBind.BindUInt(1000); + test.BindParam(queryCondition2); + test.StmtExecute(); + test.StmtUseResult(); + test.StmtClose(); + TaosBind.FreeTaosBind(queryCondition2); + Console.WriteLine("---------------------------------------------------------------"); + Console.WriteLine("Stop Stmtfunction case2 Testing..."); + Console.WriteLine("---------------------------------------------------------------"); + + + // //case3:float,double + string createTable3 = "create stable stmttest3 (ts timestamp,c1 float,c2 double)" + +" tags(t1 float,t2 float,t3 float,t4 double,t5 double,t6 double)"; + test.executeQuery(createTable3); + test.StmtInit(); + test.StmtPrepare("insert into ? using stmttest3 tags(?,?,?,?,?,?) values(?,?,?)"); + TAOS_BIND[] fdbinds = test.InitBindArr3(); + TAOS_MULTI_BIND[] fdmbinds = test.InitMultBindArr3(); + test.SetTableNameTags("t3",fdbinds); + test.BindParamBatch(fdmbinds); + test.AddBatch(); + test.StmtExecute(); + TaosBind.FreeTaosBind(fdbinds); + TaosMultiBind.FreeTaosBind(fdmbinds); + test.StmtClose(); + //select + Console.WriteLine("---------------------------------------------------------------"); + Console.WriteLine("start Stmtfunction case3 select Testing..."); + Console.WriteLine("---------------------------------------------------------------"); + test.StmtInit(); + test.StmtPrepare("select * from t3 where c1>? and c2 >?"); + TAOS_BIND[] queryCondition3 = new TAOS_BIND[2]; + queryCondition3[0] = TaosBind.BindFloat(80); + queryCondition3[1] = TaosBind.BindDouble(1000); + test.BindParam(queryCondition3); + test.StmtExecute(); + test.StmtUseResult(); + test.StmtClose(); + TaosBind.FreeTaosBind(queryCondition3); + Console.WriteLine("---------------------------------------------------------------"); + Console.WriteLine("Stop Stmtfunction case3 Testing..."); + Console.WriteLine("---------------------------------------------------------------"); + + + //case4:binary,nchar + string createTable4 = "create stable stmttest4 (ts timestamp,c1 binary(50),c2 nchar(50))tags(t1 binary(50),t2 nchar(50))"; + //Console.WriteLine(createTable4); + test.executeQuery(createTable4); + test.StmtInit(); + test.StmtPrepare("insert into ? using stmttest4 tags(?,?) values(?,?,?)"); + TAOS_BIND[] bnbinds = test.InitBindArr4(); + TAOS_MULTI_BIND[] bnmbinds = test.InitMultBindArr4(); + test.SetTableNameTags("t4",bnbinds); + test.BindParamBatch(bnmbinds); + test.AddBatch(); + test.StmtExecute(); + TaosBind.FreeTaosBind(bnbinds); + TaosMultiBind.FreeTaosBind(bnmbinds); + test.StmtClose(); + //select + Console.WriteLine("---------------------------------------------------------------"); + Console.WriteLine("start Stmtfunction case4 select Testing..."); + Console.WriteLine("---------------------------------------------------------------"); + test.StmtInit(); + test.StmtPrepare("select * from t4 where c1 match ?"); + TAOS_BIND[] queryCondition4 = new TAOS_BIND[1]; + queryCondition4[0] = TaosBind.BindBinary("\"^a\""); + + test.BindParam(queryCondition4); + test.StmtExecute(); + test.StmtUseResult(); + test.StmtClose(); + TaosBind.FreeTaosBind(queryCondition4); + Console.WriteLine("---------------------------------------------------------------"); + Console.WriteLine("Stop Stmtfunction case4 Testing..."); + Console.WriteLine("---------------------------------------------------------------"); + test.CloseConnection(); + + ExitProgram(); + + } + + //Start here are the framework functions + public void InitTDengine() + { + TDengine.Options((int)TDengineInitOption.TDDB_OPTION_CONFIGDIR, this.configDir); + TDengine.Options((int)TDengineInitOption.TDDB_OPTION_SHELL_ACTIVITY_TIMER, "60"); + Console.WriteLine("init..."); + TDengine.Init(); + Console.WriteLine("get connection starting..."); + } + + public void ConnectTDengine() + { + string db = ""; + this.conn = TDengine.Connect(host, this.user, this.passwd, db, this.port); + if (this.conn == IntPtr.Zero) + { + Console.WriteLine("connection failed: " + this.host); + ExitProgramFailed(); + } + else + { + Console.WriteLine("[ OK ] Connection established."); + } + } + public void StmtInit() + { + this.stmt = TDengine.StmtInit(conn); + if (this.stmt == IntPtr.Zero) + { + Console.WriteLine("Init stmt failed"); + ExitProgramFailed(); + } + else + { + Console.WriteLine("Init stmt success"); + } + } + public void StmtPrepare(string sql) + { + int res = TDengine.StmtPrepare(this.stmt, sql); + if (res == 0) + { + Console.WriteLine("stmt prepare success"); + } + else + { + Console.WriteLine("stmt prepare failed " + TDengine.StmtErrorStr(stmt)); + ExitProgramFailed(); + } + } + public void SetTableName(String tableName) + { + int res = TDengine.StmtSetTbname(this.stmt, tableName); + Console.WriteLine("setTableName():" + res); + if (res == 0) + { + Console.WriteLine("set_tbname success"); + } + else + { + Console.Write("set_tbname failed, " + TDengine.StmtErrorStr(stmt)); + StmtClose(); + ExitProgramFailed(); + } + } + public void executeQuery(String sql) + { + IntPtr res = TDengine.Query(conn, sql); + if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0)) + { + Console.Write(sql.ToString() + " failure, "); + if (res != IntPtr.Zero) + { + Console.Write("reason: " + TDengine.Error(res)); + } + Console.WriteLine(""); + ExitProgramFailed(); + } + else + { + Console.WriteLine(sql.ToString() + " success"); + } + TDengine.FreeResult(res); + } + public void SetTableNameTags(String tableName, TAOS_BIND[] tags) + { + int res = TDengine.StmtSetTbnameTags(this.stmt, tableName, tags); + if (res == 0) + { + Console.WriteLine("set tbname && tags success"); + + } + else + { + Console.Write("set tbname && tags failed, " + TDengine.StmtErrorStr(stmt)); + StmtClose(); + ExitProgramFailed(); + } + } + public void SetSubTableName(string name) + { + int res = TDengine.StmtSetSubTbname(this.stmt, name); + if (res == 0) + { + Console.WriteLine("set subtable name success"); + } + else + { + Console.Write("set subtable name failed, " + TDengine.StmtErrorStr(stmt)); + StmtClose(); + ExitProgramFailed(); + } + + } + + public void BindParam(TAOS_BIND[] binds) + { + Console.WriteLine("in bindParam()"); + + int res = TDengine.StmtBindParam(this.stmt, binds); + if (res == 0) + { + Console.WriteLine("bind para success"); + } + else + { + Console.Write("bind para failed, " + TDengine.StmtErrorStr(stmt)); + StmtClose(); + ExitProgramFailed(); + } + } + + public void BindSingleParamBatch(TAOS_MULTI_BIND bind, int index) + { + int res = TDengine.StmtBindSingleParamBatch(this.stmt,ref bind, index); + if (res == 0) + { + Console.WriteLine("single bind batch success"); + } + else + { + Console.Write("single bind batch failed: " + TDengine.StmtErrorStr(stmt)); + StmtClose(); + ExitProgramFailed(); + } + } + + public void BindParamBatch(TAOS_MULTI_BIND[] bind) + { + int res = TDengine.StmtBindParamBatch(this.stmt, bind); + if (res == 0) + { + Console.WriteLine("bind parameter batch success"); + } + else + { + Console.WriteLine("bind parameter batch failed, " + TDengine.StmtErrorStr(stmt)); + StmtClose(); + ExitProgramFailed(); + } + } + + public void AddBatch() + { + int res = TDengine.StmtAddBatch(this.stmt); + if (res == 0) + { + Console.WriteLine("stmt add batch success"); + } + else + { + Console.Write("stmt add batch failed,reason: " + TDengine.StmtErrorStr(stmt)); + StmtClose(); + ExitProgramFailed(); + } + } + public void StmtExecute() + { + int res = TDengine.StmtExecute(this.stmt); + if (res == 0) + { + Console.WriteLine("Execute stmt success"); + } + else + { + Console.Write("Execute stmt failed,reason: " + TDengine.StmtErrorStr(stmt)); + StmtClose(); + ExitProgramFailed(); + } + } + public void StmtClose() + { + int res = TDengine.StmtClose(this.stmt); + if (res == 0) + { + Console.WriteLine("close stmt success"); + } + else + { + Console.WriteLine("close stmt failed, " + TDengine.StmtErrorStr(stmt)); + StmtClose(); + ExitProgramFailed(); + } + } + public void CloseConnection() + { + if (this.conn != IntPtr.Zero) + { + if (TDengine.Close(this.conn) == 0) + { + Console.WriteLine("close connection sucess"); + } + else + { + Console.WriteLine("close Connection failed"); + ExitProgramFailed(); + } + } + } + + //select only + public void StmtUseResult() + { + IntPtr res = TDengine.StmtUseResult(this.stmt); + if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0)) + { + if (res != IntPtr.Zero) + { + Console.Write("reason: " + TDengine.Error(res)); + } + Console.WriteLine(""); + StmtClose(); + CloseConnection(); + ExitProgramFailed(); + } + else + { + Console.WriteLine("{0},query success"); + DisplayRes(res); + TDengine.FreeResult(res); + } + + } + + public void DisplayRes(IntPtr res) + { + + long queryRows = 0; + if ((res == IntPtr.Zero) || (TDengine.ErrorNo(res) != 0)) + { + if (res != IntPtr.Zero) + { + Console.Write("reason: " + TDengine.Error(res)); + } + Console.WriteLine(""); + ExitProgramFailed(); + } + + int fieldCount = TDengine.FieldCount(res); + List metas = TDengine.FetchFields(res); + for (int j = 0; j < metas.Count; j++) + { + TDengineMeta meta = (TDengineMeta)metas[j]; + } + + IntPtr rowdata; + StringBuilder builder = new StringBuilder(); + while ((rowdata = TDengine.FetchRows(res)) != IntPtr.Zero) + { + queryRows++; + for (int fields = 0; fields < fieldCount; ++fields) + { + TDengineMeta meta = metas[fields]; + int offset = IntPtr.Size * fields; + IntPtr data = Marshal.ReadIntPtr(rowdata, offset); + + builder.Append("---"); + + if (data == IntPtr.Zero) + { + builder.Append("NULL"); + continue; + } + + switch ((TDengineDataType)meta.type) + { + case TDengineDataType.TSDB_DATA_TYPE_BOOL: + bool v1 = Marshal.ReadByte(data) == 0 ? false : true; + builder.Append(v1); + break; + case TDengineDataType.TSDB_DATA_TYPE_TINYINT: + byte v2 = Marshal.ReadByte(data); + builder.Append(v2); + break; + case TDengineDataType.TSDB_DATA_TYPE_SMALLINT: + short v3 = Marshal.ReadInt16(data); + builder.Append(v3); + break; + case TDengineDataType.TSDB_DATA_TYPE_INT: + int v4 = Marshal.ReadInt32(data); + builder.Append(v4); + break; + case TDengineDataType.TSDB_DATA_TYPE_BIGINT: + long v5 = Marshal.ReadInt64(data); + builder.Append(v5); + break; + case TDengineDataType.TSDB_DATA_TYPE_FLOAT: + float v6 = (float)Marshal.PtrToStructure(data, typeof(float)); + builder.Append(v6); + break; + case TDengineDataType.TSDB_DATA_TYPE_DOUBLE: + double v7 = (double)Marshal.PtrToStructure(data, typeof(double)); + builder.Append(v7); + break; + case TDengineDataType.TSDB_DATA_TYPE_BINARY: + string v8 = Marshal.PtrToStringAnsi(data); + builder.Append(v8); + break; + case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP: + long v9 = Marshal.ReadInt64(data); + builder.Append(v9); + break; + case TDengineDataType.TSDB_DATA_TYPE_NCHAR: + string v10 = Marshal.PtrToStringAnsi(data); + builder.Append(v10); + break; + } + } + builder.Append("---"); + + if (queryRows <= 10) + { + Console.WriteLine(builder.ToString()); + } + builder.Clear(); + } + + if (TDengine.ErrorNo(res) != 0) + { + Console.Write("Query is not complete, Error {0:G}", TDengine.ErrorNo(res), TDengine.Error(res)); + } + Console.WriteLine(""); + + } + public static void ExitProgram() + { + TDengine.Cleanup(); + System.Environment.Exit(0); + } + public static void ExitProgramFailed() + { + TDengine.Cleanup(); + System.Environment.Exit(1); + } + } + + +} diff --git a/tests/system-test/3-connectors/c#/stmtfunction/stmtfunction.csproj b/tests/system-test/3-connectors/c#/stmtfunction/stmtfunction.csproj new file mode 100644 index 0000000000..32f0f9354c --- /dev/null +++ b/tests/system-test/3-connectors/c#/stmtfunction/stmtfunction.csproj @@ -0,0 +1,14 @@ + + + + + + + + Exe + net5.0 + enable + enable + + + -- GitLab