From 2224d29956b01e32c02ab77cba91911c66b98de4 Mon Sep 17 00:00:00 2001 From: Juan Martinez Ramirez Date: Wed, 18 Sep 2024 17:15:53 -0600 Subject: [PATCH 1/3] Add basic implementation of GetEnumerator using DbEnumerator class --- Snowflake.Data/Client/SnowflakeDbDataReader.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Snowflake.Data/Client/SnowflakeDbDataReader.cs b/Snowflake.Data/Client/SnowflakeDbDataReader.cs index b7bc1615e..7d624bd80 100755 --- a/Snowflake.Data/Client/SnowflakeDbDataReader.cs +++ b/Snowflake.Data/Client/SnowflakeDbDataReader.cs @@ -189,10 +189,7 @@ public override double GetDouble(int ordinal) return resultSet.GetDouble(ordinal); } - public override IEnumerator GetEnumerator() - { - throw new NotImplementedException(); - } + public override IEnumerator GetEnumerator() => new DbEnumerator(this, closeReader: false); public override Type GetFieldType(int ordinal) { From 3b111156f5937bd319dd9a0b5e74bab8fc528786 Mon Sep 17 00:00:00 2001 From: Juan Martinez Ramirez Date: Fri, 27 Sep 2024 15:12:22 -0600 Subject: [PATCH 2/3] Added testing --- .../SFDbDataReaderGetEnumeratorIT.cs | 180 ++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100755 Snowflake.Data.Tests/IntegrationTests/SFDbDataReaderGetEnumeratorIT.cs diff --git a/Snowflake.Data.Tests/IntegrationTests/SFDbDataReaderGetEnumeratorIT.cs b/Snowflake.Data.Tests/IntegrationTests/SFDbDataReaderGetEnumeratorIT.cs new file mode 100755 index 000000000..82deac5b3 --- /dev/null +++ b/Snowflake.Data.Tests/IntegrationTests/SFDbDataReaderGetEnumeratorIT.cs @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2012-2019 Snowflake Computing Inc. All rights reserved. + */ + +using System; +using System.Linq; +using System.Data.Common; +using System.Data; +using System.Globalization; +using System.Text; +using NUnit.Framework; +using Snowflake.Data.Client; +using Snowflake.Data.Core; +using Snowflake.Data.Tests.Util; + +namespace Snowflake.Data.Tests.IntegrationTests +{ + [TestFixture(ResultFormat.ARROW)] + [TestFixture(ResultFormat.JSON)] + class SFDbDataReaderGetEnumeratorIT : SFBaseTest + { + protected override string TestName => base.TestName + _resultFormat; + + private readonly ResultFormat _resultFormat; + + public SFDbDataReaderGetEnumeratorIT(ResultFormat resultFormat) + { + _resultFormat = resultFormat; + } + + [Test] + public void TestGetEnumerator() + { + using (var conn = CreateAndOpenConnection()) + { + CreateAndPopulateTestTable(conn, out var cmd); + + string selectCommandText = $"select * from {TableName}"; + IDbCommand selectCmd = conn.CreateCommand(); + selectCmd.CommandText = selectCommandText; + DbDataReader reader = selectCmd.ExecuteReader() as DbDataReader; + + var enumerator = reader.GetEnumerator(); + Assert.IsTrue(enumerator.MoveNext()); + Assert.AreEqual(1, (enumerator.Current as DbDataRecord).GetInt64(0)); + Assert.IsTrue(enumerator.MoveNext()); + Assert.AreEqual(2, (enumerator.Current as DbDataRecord).GetInt64(0)); + Assert.IsTrue(enumerator.MoveNext()); + Assert.AreEqual(3, (enumerator.Current as DbDataRecord).GetInt64(0)); + Assert.IsFalse(enumerator.MoveNext()); + + reader.Close(); + + DropTestTableAndCloseConnection(conn); + } + } + + [Test] + public void TestGetEnumeratorShouldBeEmptyWhenNotRowsReturned() + { + using (var conn = CreateAndOpenConnection()) + { + CreateAndPopulateTestTable(conn, out var cmd); + + string selectCommandText = $"select * from {TableName} WHERE cola > 10"; + IDbCommand selectCmd = conn.CreateCommand(); + selectCmd.CommandText = selectCommandText; + DbDataReader reader = selectCmd.ExecuteReader() as DbDataReader; + + var enumerator = reader.GetEnumerator(); + Assert.IsFalse(enumerator.MoveNext()); + Assert.IsNull(enumerator.Current); + + reader.Close(); + DropTestTableAndCloseConnection(conn); + } + } + + [Test] + public void TestGetEnumeratorWithCastMethod() + { + using (var conn = CreateAndOpenConnection()) + { + CreateAndPopulateTestTable(conn, out var cmd); + + string selectCommandText = $"select * from {TableName}"; + IDbCommand selectCmd = conn.CreateCommand(); + selectCmd.CommandText = selectCommandText; + DbDataReader reader = selectCmd.ExecuteReader() as DbDataReader; + + var dataRecords = reader.Cast().ToList(); + Assert.AreEqual(3, dataRecords.Count); + + reader.Close(); + + DropTestTableAndCloseConnection(conn); + } + } + + [Test] + public void TestGetEnumeratorForEachShouldNotEnterWhenResultsIsEmpty() + { + using (var conn = CreateAndOpenConnection()) + { + CreateAndPopulateTestTable(conn, out var cmd); + + string selectCommandText = $"select * from {TableName} WHERE cola > 10"; + IDbCommand selectCmd = conn.CreateCommand(); + selectCmd.CommandText = selectCommandText; + DbDataReader reader = selectCmd.ExecuteReader() as DbDataReader; + + foreach (var record in reader) + { + Assert.Fail("Should not enter when results is empty"); + } + + reader.Close(); + DropTestTableAndCloseConnection(conn); + } + } + + [Test] + public void TestGetEnumeratorShouldThrowNonSupportedExceptionWhenReset() + { + using (var conn = CreateAndOpenConnection()) + { + CreateAndPopulateTestTable(conn, out var cmd); + + string selectCommandText = $"select * from {TableName}"; + IDbCommand selectCmd = conn.CreateCommand(); + selectCmd.CommandText = selectCommandText; + DbDataReader reader = selectCmd.ExecuteReader() as DbDataReader; + + var enumerator = reader.GetEnumerator(); + Assert.IsTrue(enumerator.MoveNext()); + + Assert.Throws(() => enumerator.Reset()); + + reader.Close(); + + DropTestTableAndCloseConnection(conn); + } + } + + private void DropTestTableAndCloseConnection(DbConnection conn) + { + IDbCommand cmd = conn.CreateCommand(); + cmd.CommandText = $"drop table if exists {TableName}"; + var count = cmd.ExecuteNonQuery(); + Assert.AreEqual(0, count); + + CloseConnection(conn); + } + + private void CreateAndPopulateTestTable(DbConnection conn, out IDbCommand cmd) + { + CreateOrReplaceTable(conn, TableName, new []{"cola NUMBER"}); + + cmd = conn.CreateCommand(); + + string insertCommand = $"insert into {TableName} values (1),(2),(3)"; + cmd.CommandText = insertCommand; + cmd.ExecuteNonQuery(); + } + + private DbConnection CreateAndOpenConnection() + { + var conn = new SnowflakeDbConnection(ConnectionString); + conn.Open(); + SessionParameterAlterer.SetResultFormat(conn, _resultFormat); + return conn; + } + + private void CloseConnection(DbConnection conn) + { + SessionParameterAlterer.RestoreResultFormat(conn); + conn.Close(); + } + } +} From 408dc906322c21f0499c9309e7ab528c11200f3b Mon Sep 17 00:00:00 2001 From: Juan Martinez Ramirez Date: Mon, 7 Oct 2024 10:08:06 -0600 Subject: [PATCH 3/3] Apply PR suggestions --- .../SFDbDataReaderGetEnumeratorIT.cs | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Snowflake.Data.Tests/IntegrationTests/SFDbDataReaderGetEnumeratorIT.cs b/Snowflake.Data.Tests/IntegrationTests/SFDbDataReaderGetEnumeratorIT.cs index 82deac5b3..88e25256e 100755 --- a/Snowflake.Data.Tests/IntegrationTests/SFDbDataReaderGetEnumeratorIT.cs +++ b/Snowflake.Data.Tests/IntegrationTests/SFDbDataReaderGetEnumeratorIT.cs @@ -33,7 +33,7 @@ public void TestGetEnumerator() { using (var conn = CreateAndOpenConnection()) { - CreateAndPopulateTestTable(conn, out var cmd); + CreateAndPopulateTestTable(conn); string selectCommandText = $"select * from {TableName}"; IDbCommand selectCmd = conn.CreateCommand(); @@ -42,11 +42,11 @@ public void TestGetEnumerator() var enumerator = reader.GetEnumerator(); Assert.IsTrue(enumerator.MoveNext()); - Assert.AreEqual(1, (enumerator.Current as DbDataRecord).GetInt64(0)); + Assert.AreEqual(3, (enumerator.Current as DbDataRecord).GetInt64(0)); Assert.IsTrue(enumerator.MoveNext()); - Assert.AreEqual(2, (enumerator.Current as DbDataRecord).GetInt64(0)); + Assert.AreEqual(5, (enumerator.Current as DbDataRecord).GetInt64(0)); Assert.IsTrue(enumerator.MoveNext()); - Assert.AreEqual(3, (enumerator.Current as DbDataRecord).GetInt64(0)); + Assert.AreEqual(8, (enumerator.Current as DbDataRecord).GetInt64(0)); Assert.IsFalse(enumerator.MoveNext()); reader.Close(); @@ -60,7 +60,7 @@ public void TestGetEnumeratorShouldBeEmptyWhenNotRowsReturned() { using (var conn = CreateAndOpenConnection()) { - CreateAndPopulateTestTable(conn, out var cmd); + CreateAndPopulateTestTable(conn); string selectCommandText = $"select * from {TableName} WHERE cola > 10"; IDbCommand selectCmd = conn.CreateCommand(); @@ -81,7 +81,7 @@ public void TestGetEnumeratorWithCastMethod() { using (var conn = CreateAndOpenConnection()) { - CreateAndPopulateTestTable(conn, out var cmd); + CreateAndPopulateTestTable(conn); string selectCommandText = $"select * from {TableName}"; IDbCommand selectCmd = conn.CreateCommand(); @@ -102,7 +102,7 @@ public void TestGetEnumeratorForEachShouldNotEnterWhenResultsIsEmpty() { using (var conn = CreateAndOpenConnection()) { - CreateAndPopulateTestTable(conn, out var cmd); + CreateAndPopulateTestTable(conn); string selectCommandText = $"select * from {TableName} WHERE cola > 10"; IDbCommand selectCmd = conn.CreateCommand(); @@ -124,7 +124,7 @@ public void TestGetEnumeratorShouldThrowNonSupportedExceptionWhenReset() { using (var conn = CreateAndOpenConnection()) { - CreateAndPopulateTestTable(conn, out var cmd); + CreateAndPopulateTestTable(conn); string selectCommandText = $"select * from {TableName}"; IDbCommand selectCmd = conn.CreateCommand(); @@ -152,13 +152,13 @@ private void DropTestTableAndCloseConnection(DbConnection conn) CloseConnection(conn); } - private void CreateAndPopulateTestTable(DbConnection conn, out IDbCommand cmd) + private void CreateAndPopulateTestTable(DbConnection conn) { CreateOrReplaceTable(conn, TableName, new []{"cola NUMBER"}); - cmd = conn.CreateCommand(); + var cmd = conn.CreateCommand(); - string insertCommand = $"insert into {TableName} values (1),(2),(3)"; + string insertCommand = $"insert into {TableName} values (3),(5),(8)"; cmd.CommandText = insertCommand; cmd.ExecuteNonQuery(); }