From c5acd6130c53f15147adaa3d5b34c9fdf4abdc39 Mon Sep 17 00:00:00 2001 From: PopeyeZhong <9555843@qq.com> Date: Tue, 5 Nov 2024 12:04:51 +0800 Subject: [PATCH 1/4] fix: var command = new TDengineCommand() { CommandText = "...", CommandType = CommandType.Text, }; MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit var connection = new TDengineConnection("..."); command.DbConnection = connection; 如上代码片段中最后一行代码,因为 TDengineConnection 尚未打开,所以其内部的 client 变量为空,故而导致 TDegnineCommand.DbConnection 属性设置器中的代码引发了空引用异常。 现将 TDengineCommand 类中的 DbConnection 属性的设置器中的 _connection.client.StmtInit() 调用移动到 Statement() 方法中,将 StmtInit() 方法后置到执行方法也更为合理。 --- src/Data/Client/TDengineCommand.cs | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/Data/Client/TDengineCommand.cs b/src/Data/Client/TDengineCommand.cs index a3a355e..cd4271a 100644 --- a/src/Data/Client/TDengineCommand.cs +++ b/src/Data/Client/TDengineCommand.cs @@ -1,8 +1,8 @@ using System; -using System.Collections.Generic; using System.Data; using System.Data.Common; -using System.Threading.Tasks; +using System.Collections.Generic; + using TDengine.Driver; namespace TDengine.Data.Client @@ -127,14 +127,7 @@ public override CommandType CommandType protected override DbConnection DbConnection { get => _connection; - set - { - _connection = (TDengineConnection)value; - if (_stmt == null && _connection != null) - { - _stmt = _connection.client.StmtInit(); - } - } + set => _connection = value as TDengineConnection ?? throw new ArgumentException($"The specified connection is not of type {nameof(TDengineConnection)}."); } protected override DbParameterCollection DbParameterCollection => _parameters.Value; @@ -158,7 +151,12 @@ private IRows Query() private IRows Statement() { - if (!_isPrepared) + if(_stmt == null && _connection != null) + { + _stmt = _connection.client.StmtInit(); + } + + if (!_isPrepared) { _isPrepared = true; _stmt.Prepare(_commandText); From 8a4ef7ca523044346514f2abfd6328cb0ce98c8f Mon Sep 17 00:00:00 2001 From: PopeyeZhong <9555843@qq.com> Date: Tue, 5 Nov 2024 15:20:39 +0800 Subject: [PATCH 2/4] =?UTF-8?q?feature:=20Add=20support=20for=20DbParamete?= =?UTF-8?q?r.Value=20to=20be=20DBNull.=20=E6=B7=BB=E5=8A=A0=E5=AF=B9=20DbP?= =?UTF-8?q?arameter.Value=20=E4=B8=BA=20DBNull.Value=20=E7=9A=84=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Driver/Client/Native/NativeStmt.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/Driver/Client/Native/NativeStmt.cs b/src/Driver/Client/Native/NativeStmt.cs index 33d705f..6ac277c 100644 --- a/src/Driver/Client/Native/NativeStmt.cs +++ b/src/Driver/Client/Native/NativeStmt.cs @@ -80,9 +80,7 @@ public void SetTags(object[] tags) } } - - private TAOS_MULTI_BIND[] GenerateBindList(object[] data, TaosFieldE[] fields, out IntPtr[] needFree, - bool isInsert) + private TAOS_MULTI_BIND[] GenerateBindList(object[] data, TaosFieldE[] fields, out IntPtr[] needFree, bool isInsert) { TAOS_MULTI_BIND[] binds = new TAOS_MULTI_BIND[data.Length]; var needFreePointer = new List(); @@ -92,7 +90,7 @@ private TAOS_MULTI_BIND[] GenerateBindList(object[] data, TaosFieldE[] fields, o { num = 1 }; - if (data[i] == null) + if (data[i] == null || Convert.IsDBNull(data[i])) { bind.buffer_type = (int)TDengineDataType.TSDB_DATA_TYPE_BOOL; IntPtr p = Marshal.AllocHGlobal(TDengineConstant.ByteSize); @@ -471,7 +469,6 @@ private TAOS_MULTI_BIND GenerateBindColumn(Array array, TaosFieldE field) } } - public void AddBatch() { var code = NativeMethods.StmtAddBatch(_stmt); From 6b6aeaedb0fcb3521615aac8913e81f6f8c7689f Mon Sep 17 00:00:00 2001 From: PopeyeZhong <9555843@qq.com> Date: Wed, 27 Nov 2024 09:39:00 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E4=B8=BA=20TDengineCommand=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=20SetConnection=5FDoesNotThrowException=20=E5=92=8C?= =?UTF-8?q?=20ExecuteNonQuery=5FWithDBNull=20=E4=B8=A4=E4=B8=AA=E5=8D=95?= =?UTF-8?q?=E5=85=83=E6=B5=8B=E8=AF=95=E7=94=A8=E4=BE=8B=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/Data.Tests/TDengineCommandTests.cs | 39 +++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/test/Data.Tests/TDengineCommandTests.cs b/test/Data.Tests/TDengineCommandTests.cs index 16af033..17de9c7 100644 --- a/test/Data.Tests/TDengineCommandTests.cs +++ b/test/Data.Tests/TDengineCommandTests.cs @@ -65,6 +65,45 @@ public void Dispose() } [Fact] + public void SetConnection_DoesNotThrowException() + { + using(var command = new TDengineCommand()) + { + command.CommandText = "SELECT * FROM t"; + var ex = Record.Exception(() => command.Connection = _connection); + Assert.Null(ex); + } + + using(var command = new TDengineCommand()) + { + using(var connection = new TDengineConnection("username=root;password=taosdata")) + { + command.CommandText = "SELECT * FROM t"; + var ex = Record.Exception(() => command.Connection = connection); + Assert.Null(ex); + } + } + } + + [Fact] + public void ExecuteNonQuery_WithDBNull() + { + using(var command = new TDengineCommand(_connection)) + { + command.CommandText = "create table if not exists t_dbnull (ts timestamp,v int,description nchar(100))"; + command.ExecuteNonQuery(); + command.CommandText = "INSERT INTO t_dbnull VALUES (?,?,?)"; + command.Parameters.AddWithValue(DateTime.Now); + command.Parameters.AddWithValue(123); + command.Parameters.AddWithValue(DBNull.Value); + + int affectedRows = command.ExecuteNonQuery(); + + Assert.Equal(1, affectedRows); + } + } + + [Fact] public void ExecuteNonQuery_WithValidCommand_ReturnsAffectedRows() { using (var command = new TDengineCommand(_connection)) From e5aa70aa1e8997e3706259d84e4b51ce78bd96ab Mon Sep 17 00:00:00 2001 From: PopeyeZhong <9555843@qq.com> Date: Wed, 27 Nov 2024 11:45:04 +0800 Subject: [PATCH 4/4] Formatting the codes. --- src/Data/Client/TDengineCommand.cs | 10 +++---- test/Data.Tests/TDengineCommandTests.cs | 36 +++++++++++++------------ 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/Data/Client/TDengineCommand.cs b/src/Data/Client/TDengineCommand.cs index cd4271a..60b5fb2 100644 --- a/src/Data/Client/TDengineCommand.cs +++ b/src/Data/Client/TDengineCommand.cs @@ -151,12 +151,12 @@ private IRows Query() private IRows Statement() { - if(_stmt == null && _connection != null) - { - _stmt = _connection.client.StmtInit(); - } + if(_stmt == null && _connection != null) + { + _stmt = _connection.client.StmtInit(); + } - if (!_isPrepared) + if (!_isPrepared) { _isPrepared = true; _stmt.Prepare(_commandText); diff --git a/test/Data.Tests/TDengineCommandTests.cs b/test/Data.Tests/TDengineCommandTests.cs index 17de9c7..d65e7df 100644 --- a/test/Data.Tests/TDengineCommandTests.cs +++ b/test/Data.Tests/TDengineCommandTests.cs @@ -67,41 +67,43 @@ public void Dispose() [Fact] public void SetConnection_DoesNotThrowException() { + //CASE 1: Set an already open connection. using(var command = new TDengineCommand()) { command.CommandText = "SELECT * FROM t"; var ex = Record.Exception(() => command.Connection = _connection); Assert.Null(ex); - } + } - using(var command = new TDengineCommand()) - { + //CASE 2: Set an connection that is not yet open. + using(var command = new TDengineCommand()) + { using(var connection = new TDengineConnection("username=root;password=taosdata")) { command.CommandText = "SELECT * FROM t"; var ex = Record.Exception(() => command.Connection = connection); Assert.Null(ex); } - } - } + } + } [Fact] public void ExecuteNonQuery_WithDBNull() - { - using(var command = new TDengineCommand(_connection)) - { - command.CommandText = "create table if not exists t_dbnull (ts timestamp,v int,description nchar(100))"; - command.ExecuteNonQuery(); - command.CommandText = "INSERT INTO t_dbnull VALUES (?,?,?)"; - command.Parameters.AddWithValue(DateTime.Now); - command.Parameters.AddWithValue(123); + { + using(var command = new TDengineCommand(_connection)) + { + command.CommandText = "create table if not exists t_dbnull (ts timestamp,v int,description nchar(100))"; + command.ExecuteNonQuery(); + command.CommandText = "INSERT INTO t_dbnull VALUES (?,?,?)"; + command.Parameters.AddWithValue(DateTime.Now); + command.Parameters.AddWithValue(123); command.Parameters.AddWithValue(DBNull.Value); - int affectedRows = command.ExecuteNonQuery(); + int affectedRows = command.ExecuteNonQuery(); - Assert.Equal(1, affectedRows); - } - } + Assert.Equal(1, affectedRows); + } + } [Fact] public void ExecuteNonQuery_WithValidCommand_ReturnsAffectedRows()