Browse Source

Added implementation and unit tests for GetFieldValue, GetStream and GetTextReader methods in DbDataReader class.

Used https://github.com/matthid/mono/commit/51e808b3836e9ba32901762ea23941ee60b2746d as reference.
Mika Aalto 11 years ago
parent
commit
ccd93fc95a

+ 4 - 2
mcs/class/System.Data/System.Data-tests-net_4_5.csproj

@@ -55,6 +55,8 @@
     <Compile Include="Test\System.Data.Common\DbDataAdapterTest.cs" />
     <Compile Include="Test\System.Data.Common\DBDataPermissionAttributeTest.cs" />
     <Compile Include="Test\System.Data.Common\DBDataPermissionTest.cs" />
+    <Compile Include="Test\System.Data.Common\DbDataReaderMock.cs" />
+    <Compile Include="Test\System.Data.Common\DbDataReaderTest.cs" />
     <Compile Include="Test\System.Data.Common\DbProviderFactoriesConfigurationHandlerTest.cs" />
     <Compile Include="Test\System.Data.Common\DbTransactionTest.cs" />
     <Compile Include="Test\System.Data.Odbc\OdbcCommandBuilderTest.cs" />
@@ -169,7 +171,8 @@
     <Compile Include="Test\System.Data\XmlExportOfTypedDataSetTest.cs" />
     <Compile Include="Test\System.Xml\XmlDataDocumentTest.cs" />
     <Compile Include="Test\System.Xml\XmlDataDocumentTest2.cs" />
-    <Compile Include="Mono.Data.SqlExpressions\Parser.cs" />
  </ItemGroup>
+    <Compile Include="Mono.Data.SqlExpressions\Parser.cs" />
+  </ItemGroup>
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.
   <Target Name="BeforeBuild">
@@ -235,4 +238,3 @@
     <Folder Include="Properties\" />
   </ItemGroup>
 </Project>
-

+ 18 - 5
mcs/class/System.Data/System.Data.Common/DbDataReader.cs

@@ -191,7 +191,7 @@ namespace System.Data.Common {
 #if NET_4_5
 		public virtual T GetFieldValue<T> (int i)
 		{
-			return (T) GetValue(i);
+			return (T) GetValue (i);
 		}
 
 		public Task<T> GetFieldValueAsync<T> (int ordinal)
@@ -222,16 +222,29 @@ namespace System.Data.Common {
 			return IsDBNullAsync (ordinal, CancellationToken.None);
 		}
 
-		[MonoTODO]
 		public virtual Stream GetStream (int i)
 		{
-			throw new NotImplementedException ();
+
+			long offset = 0L;
+			byte [] buffer = new byte [1024 * 8];
+			long read;
+			MemoryStream memoryStream = new MemoryStream ();
+			while ((read = this.GetBytes (i, offset, buffer, 0, buffer.Length)) > 0) {
+				memoryStream.Write (buffer, 0, (int) read);
+				offset += read;
+			}
+			memoryStream.Seek (0, SeekOrigin.Begin);
+			return memoryStream;
 		}
 		
-		[MonoTODO]
 		public virtual TextReader GetTextReader (int i)
 		{
-			throw new NotImplementedException ();	
+			String value;
+			if (IsDBNull (i))
+				value = string.Empty;
+			else
+				value = this.GetString (i);
+			return new StringReader (value);
 		}
 
 		public virtual Task<bool> IsDBNullAsync (int ordinal, CancellationToken cancellationToken)

+ 2 - 0
mcs/class/System.Data/System.Data_test.dll.sources

@@ -91,6 +91,8 @@ System.Data.Common/DBDataPermissionTest.cs
 System.Data.Common/DbCommandBuilderTest.cs
 System.Data.Common/DbConnectionStringBuilderTest.cs
 System.Data.Common/DbDataAdapterTest.cs
+System.Data.Common/DbDataReaderMock.cs
+System.Data.Common/DbDataReaderTest.cs
 System.Data.Common/DbProviderFactoriesConfigurationHandlerTest.cs
 System.Data.Common/DbTransactionTest.cs
 System.Data.Odbc/OdbcCommandBuilderTest.cs

+ 225 - 0
mcs/class/System.Data/Test/System.Data.Common/DbDataReaderMock.cs

@@ -0,0 +1,225 @@
+// DbDataReaderMock.cs - Helper class for DbDataReader tests
+//
+// Author: 
+//	Mika Aalto ([email protected])
+//
+// Copyright (C) 2014 Mika Aalto
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if NET_2_0
+
+using System;
+using System.Data;
+using System.Data.Common;
+using System.IO;
+
+namespace Test.System.Data.Common
+{
+	internal class DbDataReaderMock : DbDataReader
+	{
+		int currentRowIndex = -1;
+		DataTable testDataTable;
+
+		public DbDataReaderMock ()
+		{
+			testDataTable = new DataTable ();
+		}
+
+		public DbDataReaderMock (DataTable testData)
+		{
+			if (testData == null) {
+				throw new ArgumentNullException ("testData");
+			}
+
+			testDataTable = testData;
+		}
+
+		public override void Close ()
+		{
+			testDataTable.Clear ();
+		}
+
+		public override int Depth {
+			get { throw new NotImplementedException (); }
+		}
+
+		public override int FieldCount {
+			get { throw new NotImplementedException (); }
+		}
+
+		public override bool GetBoolean (int ordinal)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public override byte GetByte (int ordinal)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public override long GetBytes (int ordinal, long dataOffset, byte[] buffer, int bufferOffset, int length)
+		{
+			object value = GetValue (ordinal);
+			if (value == DBNull.Value) {
+				return 0;
+			}
+
+			byte[] data = (byte[])value;
+			long bytesToRead = Math.Min (data.Length - dataOffset, length);
+			Buffer.BlockCopy (data, (int)dataOffset, buffer, bufferOffset, (int)bytesToRead);
+			return bytesToRead;
+		}
+
+		public override char GetChar (int ordinal)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public override long GetChars (int ordinal, long dataOffset, char[] buffer, int bufferOffset, int length)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public override string GetDataTypeName (int ordinal)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public override DateTime GetDateTime (int ordinal)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public override decimal GetDecimal (int ordinal)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public override double GetDouble (int ordinal)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public override global::System.Collections.IEnumerator GetEnumerator ()
+		{
+			throw new NotImplementedException ();
+		}
+
+		public override Type GetFieldType (int ordinal)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public override float GetFloat (int ordinal)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public override Guid GetGuid (int ordinal)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public override short GetInt16 (int ordinal)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public override int GetInt32 (int ordinal)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public override long GetInt64 (int ordinal)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public override string GetName (int ordinal)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public override int GetOrdinal (string name)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public override DataTable GetSchemaTable ()
+		{
+			throw new NotImplementedException ();
+		}
+
+		public override string GetString (int ordinal)
+		{
+			return (string)testDataTable.Rows [currentRowIndex] [ordinal];
+		}
+
+		public override object GetValue (int ordinal)
+		{
+			return testDataTable.Rows [currentRowIndex] [ordinal];
+		}
+
+		public override int GetValues (object[] values)
+		{
+			throw new NotImplementedException ();
+		}
+
+		public override bool HasRows {
+			get { throw new NotImplementedException (); }
+		}
+
+		public override bool IsClosed {
+			get { throw new NotImplementedException (); }
+		}
+
+		public override bool IsDBNull (int ordinal)
+		{
+			return testDataTable.Rows [currentRowIndex] [ordinal] == DBNull.Value;
+		}
+
+		public override bool NextResult ()
+		{
+			throw new NotImplementedException ();
+		}
+
+		public override bool Read ()
+		{
+			currentRowIndex++;
+			return currentRowIndex < testDataTable.Rows.Count;
+		}
+
+		public override int RecordsAffected {
+			get { throw new NotImplementedException (); }
+		}
+
+		public override object this [string name] {
+			get { throw new NotImplementedException (); }
+		}
+
+		public override object this [int ordinal] {
+			get { throw new NotImplementedException (); }
+		}
+	}
+}
+
+#endif // NET_2_0

+ 163 - 0
mcs/class/System.Data/Test/System.Data.Common/DbDataReaderTest.cs

@@ -0,0 +1,163 @@
+// DbDataReaderTest.cs - NUnit Test Cases for DbDataReader class
+//
+// Author:
+//	Mika Aalto ([email protected])
+//
+// Copyright (C) 2014 Mika Aalto
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if NET_2_0
+
+using NUnit.Framework;
+using System;
+using System.Data;
+using System.Data.Common;
+using System.IO;
+
+namespace Test.System.Data.Common
+{
+	[TestFixture]
+	public class DbDataReaderTest
+	{
+		DbDataReaderMock dataReader;
+
+		[SetUp]
+		public void SetUp ()
+		{
+			//Setup test data table
+			DataTable testData = new DataTable ();
+			testData.Columns.Add ("text_col", typeof(string));
+			testData.Columns.Add ("binary_col", typeof(byte[]));
+
+			testData.Rows.Add ("row_1", new byte[] { 0xde, 0xad, 0xbe, 0xef });
+			testData.Rows.Add ("row_2", DBNull.Value);
+			testData.Rows.Add ("row_3", new byte[] { 0x00 });
+
+			dataReader = new DbDataReaderMock (testData);
+
+			Assert.AreEqual (3, testData.Rows.Count);
+		}
+
+		[TearDown]
+		public void TearDown ()
+		{
+		}
+
+		#if NET_4_5
+		[Test]
+		public void GetFieldValueTest ()
+		{
+			//First row
+			dataReader.Read ();
+			Assert.AreEqual ("row_1", dataReader.GetFieldValue<string> (0), "#1");
+			byte[] expected_data = new byte[] { 0xde, 0xad, 0xbe, 0xef };
+			byte[] actual_data = dataReader.GetFieldValue<byte[]> (1);
+			Assert.AreEqual (expected_data.Length, actual_data.Length, "#2");
+			for (int i = 0; i < expected_data.Length; i++) {
+				Assert.AreEqual (expected_data [i], actual_data [i], "#3 at index " + i);
+			}
+
+			//Second row where data row column value is DBNull
+			dataReader.Read ();
+			Assert.AreEqual ("row_2", dataReader.GetFieldValue<string> (0), "#4");
+			try {
+				actual_data = dataReader.GetFieldValue<byte[]> (1);
+				Assert.Fail ("GetFieldValue method should throw InvalidCastException for DBNull values #5");
+			} catch (InvalidCastException) {
+				//This is expected
+			}
+
+			//Thord row
+			dataReader.Read ();
+			Assert.AreEqual ("row_3", dataReader.GetFieldValue<string> (0), "#6");
+			expected_data = new byte[] { 0x00 };
+			actual_data = dataReader.GetFieldValue<byte[]> (1);
+			Assert.AreEqual (expected_data.Length, actual_data.Length, "#7");
+			Assert.AreEqual (expected_data [0], actual_data [0], "#8");
+		}
+
+		[Test]
+		public void GetStreamTest ()
+		{
+			int testColOrdinal = 1;
+			byte[] buffer = new byte[1024];
+
+			dataReader.Read ();
+			Stream stream = dataReader.GetStream (testColOrdinal);
+			Assert.IsNotNull (stream, "Stream from datareader is null #1");
+
+			//Read stream content to byte buffer
+			int data_length = stream.Read (buffer, 0, buffer.Length);
+
+			//Verify that content is expected
+			byte[] expected = new byte[] { 0xde, 0xad, 0xbe, 0xef };
+			Assert.AreEqual (expected.Length, data_length, "#2");
+			for (int i = 0; i < expected.Length; i++) {
+				Assert.AreEqual (expected [i], buffer [i], "#3 at index " + i);
+			}
+
+			//Get DBNull value stream
+			Assert.IsTrue (dataReader.Read ());
+			stream = dataReader.GetStream (testColOrdinal);
+			Assert.AreEqual (0, stream.Length, "#4");
+
+			//Get single byte value stream
+			Assert.IsTrue (dataReader.Read ());
+			stream = dataReader.GetStream (testColOrdinal);
+			expected = new byte[] { 0x00 };
+			Assert.AreEqual (expected.Length, stream.Length, "#5");
+			Assert.AreEqual (expected [0], stream.ReadByte (), "#6");
+		}
+
+		[Test]
+		public void GetTextReader ()
+		{
+			int testColOrdinal = 0;
+
+			//Read first row
+			dataReader.Read ();
+			TextReader textReader = dataReader.GetTextReader (testColOrdinal);
+			Assert.IsNotNull (textReader, "return value from datareader GetTextReader method is null #1");
+
+			string txt = textReader.ReadToEnd ();
+			Assert.AreEqual ("row_1", txt, "#2");
+
+			//Move to second row
+			Assert.IsTrue (dataReader.Read ());
+			textReader = dataReader.GetTextReader (testColOrdinal);
+			txt = textReader.ReadToEnd ();
+			Assert.AreEqual ("row_2", txt, "#3");
+
+			//Move to third row
+			Assert.IsTrue (dataReader.Read ());
+			textReader = dataReader.GetTextReader (testColOrdinal);
+			txt = textReader.ReadToEnd ();
+			Assert.AreEqual ("row_3", txt, "#4");
+
+			Assert.IsFalse (dataReader.Read (), "#5");
+		}
+
+		#endif //NET_4_5
+	}
+}
+
+#endif // NET_2_0