Thursday, June 18, 2009

TechNet UK Virtual Conference 2009

Another virtual conference will be taking place tomorrow (Friday 19th June) which is the TechNet UK Virtual Conference.

Please find more information here: http://technet.microsoft.com/en-gb/dd819085.aspx

Sunday, June 14, 2009

DbDataReader.DoesColumnExist

Have you ever wanted to code something like the following:
var dbCommand = Database.DbProviderFactory.CreateCommand();
dbCommand.CommandText = "select * from MyTable";
var reader = Database.ExecuteReader(dbCommand, null);
if (reader.Read())
{
if (reader.DoesColumnExist("mycolumn")
{
//Then we know its safe to select the column.
}
}
You're probably thinking, why would I want to do that? well if you're building a generic data handler library and you don't know what columns have been selected but you know the columns that could be selected then it is very useful as using the indexer to return the data for the specified column will throw an exception if it doesn't exist.

I thought this extension method solves this problem and would be useful for others:
public static class DbDataReaderExtensions
{
public static bool DoesColumnExist(this IDataReader reader, string column)
{
if (reader.IsNull()) throw new ArgumentNullException("reader");
if (string.IsNullOrEmpty(column)) throw new ArgumentNullException("column");

for (var i = 0; i < reader.FieldCount; i++)
{
if (reader.GetName(i).Equals(column))
return true;
}
return false;
}
}
It's relatively straight forward but saves you from writing the same piece of code over and over again.

The unit test class for this is as follows:
[TestClass]
public class DataReaderExtensionsTests
{
[TestMethod]
public void ThrowsIfNullReaderIsPassed()
{
const MockDbDataReader reader = null;
AssertExt.Throws<ArgumentNullException>(() => reader.DoesColumnExist("foo"));
}

[TestMethod]
public void ThrowsIfNullColumnIsPassed()
{
var reader = new MockDbDataReader();
AssertExt.Throws<ArgumentNullException>(() => reader.DoesColumnExist(null));
AssertExt.Throws<ArgumentNullException>(() => reader.DoesColumnExist(string.Empty));
}

[TestMethod]
public void ValidExists()
{
var reader = new MockDbDataReader();
Assert.IsTrue(reader.DoesColumnExist("One"));
Assert.IsTrue(reader.DoesColumnExist("Two"));
Assert.IsTrue(reader.DoesColumnExist("Three"));
Assert.IsTrue(reader.DoesColumnExist("Four"));
Assert.IsTrue(reader.DoesColumnExist("Five"));
}

[TestMethod]
public void InvalidExists()
{
var reader = new MockDbDataReader();
Assert.IsFalse(reader.DoesColumnExist("foo"));
Assert.IsFalse(reader.DoesColumnExist("bar"));
}
}
You'll notice I have mocked the DbDataReader. Because there are mocking frameworks on the Compact Framework and probably will not be for some time (due to CF limitations) I have created a mocked class implementing the IDataReader interface. This mock class looks like the following:
public class MockDbDataReader : IDataReader
{
readonly Dictionary<int, string> getName = new Dictionary<int, string>();
public MockDbDataReader()
{
getName.Add(0, "One");
getName.Add(1, "Two");
getName.Add(2, "Three");
getName.Add(3, "Four");
getName.Add(4, "Five");
}

#region IDataReader Members

public void Close()
{
throw new NotImplementedException();
}

public int Depth
{
get { throw new NotImplementedException(); }
}

public DataTable GetSchemaTable()
{
throw new NotImplementedException();
}

public bool IsClosed
{
get { throw new NotImplementedException(); }
}

public bool NextResult()
{
throw new NotImplementedException();
}

public bool Read()
{
throw new NotImplementedException();
}

public int RecordsAffected
{
get { throw new NotImplementedException(); }
}

#endregion

#region IDisposable Members

public void Dispose()
{
throw new NotImplementedException();
}

#endregion

#region IDataRecord Members

public int FieldCount
{
get { return 5; }
}

public bool GetBoolean(int i)
{
throw new NotImplementedException();
}

public byte GetByte(int i)
{
throw new NotImplementedException();
}

public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length)
{
throw new NotImplementedException();
}

public char GetChar(int i)
{
throw new NotImplementedException();
}

public long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length)
{
throw new NotImplementedException();
}

public IDataReader GetData(int i)
{
throw new NotImplementedException();
}

public string GetDataTypeName(int i)
{
throw new NotImplementedException();
}

public DateTime GetDateTime(int i)
{
throw new NotImplementedException();
}

public decimal GetDecimal(int i)
{
throw new NotImplementedException();
}

public double GetDouble(int i)
{
throw new NotImplementedException();
}

public Type GetFieldType(int i)
{
throw new NotImplementedException();
}

public float GetFloat(int i)
{
throw new NotImplementedException();
}

public Guid GetGuid(int i)
{
throw new NotImplementedException();
}

public short GetInt16(int i)
{
throw new NotImplementedException();
}

public int GetInt32(int i)
{
throw new NotImplementedException();
}

public long GetInt64(int i)
{
throw new NotImplementedException();
}

public string GetName(int i)
{
return getName.ContainsKey(i) ? getName[i] : string.Empty;
}

public int GetOrdinal(string name)
{
throw new NotImplementedException();
}

public string GetString(int i)
{
throw new NotImplementedException();
}

public object GetValue(int i)
{
throw new NotImplementedException();
}

public int GetValues(object[] values)
{
throw new NotImplementedException();
}

public bool IsDBNull(int i)
{
throw new NotImplementedException();
}

public object this[string name]
{
get { throw new NotImplementedException(); }
}

public object this[int i]
{
get { throw new NotImplementedException(); }
}

#endregion
}
All we have done is returned 5 for the FieldCount, then provided some data so when GetName() is called we return the relevant item in the dictionary to resemble a real data reader object.

We could have written an integration test but this is pointless as we know the DataReader class has been tested and works.

The unit test class above gives 100% code coverage.

Thursday, June 04, 2009

JP Morgan Chase & Co. Corporate Challenge



Hitachi Consulting (including me) is participating in the JP Morgan Chase & Co. Corporate Challenge which is a world wide fundraising event in most major cities throughout the world.

Hitachi Consulting's goal is to raise £1000 for the Down's Syndrome Association and the challenge is a 6.5km run around Battersea park in London on the 9th July 2009.

If you were feeling generious :) you can sponsor the us over at:

http://www.justgiving.com/hcukjpmorganchallenge2009