Thursday, April 17, 2014

Quick and Efficient Database Library

In recent projects the need to continually re-write database access routines came up over and over.  I got tired of redoing the same code and so I wrote these quick database functions and extensions.  They are fully unit-tested and I'll include those at the end.

I think they could be made slightly more efficient using lambda expressions to handle the try-catch block, but that is a future enhancement that I might make.

For now, here's the first function: ExecuteScalar.  The power of these functions is that they are not tied to a specific database type such as SqlServer.  The use the generic System.Data interfaces for all external objects and even when they throw an exception they throw the generic DbException (from which exceptions such as SqlException inherit).  This allows you to theoretically connect and execute commands on a wider range of relational database types (though I have not tested it against MySql, Oracle, etc).

The function parameters are quite simple and straight-forward.  Pass in a connection, the name of the stored procedure (or the inline sql if you wish).  Optional arguments include a parameter list, an error message to include if an exception is thrown, and if you wish to trap any exceptions you can.

Code Snippet
  1. public object ExecuteScalar(IDbConnection dbConnection, string storedProcedureName, IEnumerable<IDataParameter> parameters = null,
  2. string errorMessage = ""bool throwException = true)
  3. {
  4.   object result = null;
  5.   try
  6.   {
  7.     using (IDbCommand dbCommand = dbConnection.CreateCommand())
  8.     {
  9.       SetupDbCommand(dbConnection, dbCommand, storedProcedureName, parameters);
  10.       dbCommand.Connection.Open();
  11.       result = dbCommand.ExecuteScalar();
  12.       dbCommand.Connection.CleanupConnection();
  13.     }
  14.   }
  15.   catch (DbException ex)
  16.   {
  17.     dbConnection.CleanupConnection(); 
  18.     if (throwException)
  19.       throw;
  20.   }
  21.  
  22.   return result;
  23. }

This works great if all you are expected to be returned is a row count or a single value, but you need more if you expect an actual data-set. In that situation we have:

Code Snippet
  1. public T ExecuteQuery<T>(IDbConnection dbConnection, string storedProcedureName, Func<IDataReader, T> translateFunction, IEnumerable<IDataParameter> parameters = nullstring errorMessage = "", bool throwException = true) where T : class, new()
  2. {
  3.   if (translateFunction == null) throw new ArgumentNullException("translateFunction");
  4.  
  5.   try
  6.   {
  7.     using (IDbCommand dbCommand = dbConnection.CreateCommand())
  8.     {
  9.       SetupDbCommand(dbConnection, dbCommand, storedProcedureName, parameters);
  10.       dbConnection.Open();
  11.       using (IDataReader dbReader = dbCommand.ExecuteReader())
  12.       {
  13.         var result = new T();
  14.         if (dbReader != null)
  15.           result = translateFunction.Invoke(dbReader);
  16.  
  17.         dbCommand.Connection.CleanupConnection();
  18.  
  19.         return result;
  20.       }
  21.     }
  22.   }
  23.   catch (DbException ex)
  24.   {
  25.     dbConnection.CleanupConnection();
  26.  
  27.     if (throwException)
  28.       throw;
  29.   }
  30.  
  31.   return null;
  32. }

This function takes a data reader and passes it to a custom translation function you pass in.  The translation function is responsible for retrieving the data from the reader and creating the object or objects you wish to return.  In most cases I have used this by creating a static translate function on the class itself.  I have also created a variant of this function to handle returning an IEnumerable<> of the object type.

Finally, one key component these functions don't handle is transaction management.  For that, for a unit of work, you'd need to wrap the calls in your own transaction statements complete with commit and rollback handling.

Enjoy and as usual I welcome and encourage feedback!

Tuesday, March 18, 2014

Using Lamda's and Generics to encapsulate a Try-Catch-Finally block

I recently had a legacy (.NET 2.0) project that I was asked to bring up to date with .NET 4.5.  In the process I came across numerous functions that followed the same format wrapping their functionality in a try-catch-finally code block or some variant (try-catch or try-finally).

This is a normal process in many apps, of course, but in many of these cases the catch and finally logic were duplicated.  The more I worked with it, the more I felt like there had to be a way to create a re-usable function to handle it for me.  What I came up with works pretty darn well, though it does make the code a little more complicated.

Code Snippet
  1. public static TResult TryCatch<TParam1, TResult, TException>(this Func<TParam1[], TResult> executeFunc, Func<TException, TResult> errorAction = null, Action<TParam1[]> finalAction = null, params TParam1[] args) where TException : Exception
  2. {
  3.     if (executeFunc == null)
  4.         throw new ArgumentNullException("executeFunc");
  5.  
  6.     try
  7.     {
  8.         return executeFunc.Invoke(args);
  9.     }
  10.     catch (TException ex)
  11.     {
  12.         if (errorAction != null)
  13.             return errorAction.Invoke(ex);
  14.     }
  15.     finally
  16.     {
  17.         if (finalAction != null)
  18.             finalAction.Invoke(args);
  19.     }
  20.     throw new ArgumentException("No return value specified");
  21. }

As you can see the function takes a variety of inputs to handle the guts of the code itself as well as the catch and finally blocks. The key parts of this function are:

  1. TParam1 - The type of parameter object
  2. TResult - The type of the return object
  3. TException - The type of exception expected to be caught
  4. executeFunc - The function to execute in the try block
  5. errorAction - An action to perform if an exception of the given type is caught
  6. finalAction - An action to perform on Finally
  7. args - An array of arguments passed to the executeFunc (if any)

Code Snippet
  1. [Test]
  2. public void TryCatch_Test()
  3. {
  4.     var callback = false;
  5.  
  6.     Func<object[], bool> func = x =>
  7.         {
  8.             callback = true;
  9.             return true;
  10.         };
  11.     Func<Exception, bool> showError = exception => false;
  12.  
  13.     var result = func.TryCatch(showError);
  14.  
  15.     Assert.That(result, Is.True);
  16.     Assert.That(callback, Is.True);
  17. }
  18.  
  19. [Test]
  20. public void TryCatch_Exception_Test()
  21. {
  22.     var callback = false;
  23.  
  24.     Func<object[], bool> func = x => { throw new Exception("Test Exception"); };
  25.  
  26.     Func<Exception, bool> showError = exception =>
  27.         {
  28.             callback = true;
  29.             return false;
  30.         };
  31.  
  32.     var result = func.TryCatch(showError);
  33.  
  34.     Assert.That(result, Is.False);
  35.     Assert.That(callback, Is.True);
  36. }
  37.  
  38. [Test]
  39. public void TryCatch_DifferentType_Test()
  40. {
  41.     var callback = false;
  42.     var finalCallback = false;
  43.  
  44.     Func<int[], int> func = ints =>
  45.         {
  46.             callback = true;
  47.             return ints.Sum();
  48.         };
  49.     Func<Exception, int> showError = exception => 0;
  50.     Action<int[]> final = ints => { finalCallback = true; };
  51.  
  52.     var result = func.TryCatch(showError, final, 2, 5, 8);
  53.  
  54.     Assert.That(result, Is.EqualTo(15));
  55.     Assert.That(callback, Is.True);
  56.     Assert.That(finalCallback, Is.True);
  57. }

I included these three unit tests as I felt like they displayed the uses of this function quite nicely.

This code creates a nice re-usable function that gives us some real power and flexibility. No need to wrap your functions into a try-catch block. And since its an extension method you can write your Func and then tack the .TryCatch() call to the end.

Tuesday, March 4, 2014

NCalc and Custom Expressions

I've been a fan of MUDs (multi-user dungeons) since I was introduced to the internet back in 1993.  Back then I just played them, but after a while I started programming on them.  Since 2000 I've tinkered with various forms of them on my own, often using them as a platform for learning or for practicing coding techniques.

Recently I decided to take an existing code-base that was written in ANSI C and port the entire project to C# (for those who might be interested, the project is called SmaugCS).  Yes, that is pretty crazy I know, but its been a very fun challenge.  Even more of a challenge I think than creating a MUD from the ground up.

This past fall I found the need to evaluate expressions that are commonly used in games such as D&D.  These are often represented in short-hand form and appear as "2d4+2" or "12d10-6" where the "d" is short-hand for "die".  So 2d4 would tell the system to roll two 4-sided dice twice and add the results together.  In the Smaug MUD code this formula often incorporates statistics or values from within the game and appear as "2d4+L+4" where the L represents the level of a character or monster.  Parsing expressions can be challenging, but the addition of a variety of values made it even more so.

While working on a solution I came across a third-party library called NCalc - Mathematical Expressions Evaluator for .NET.  This appeared to have what I needed so I began working on integrating it, but I ran into a problem with the "L".  How to turn that into a custom function that NCalc could understand?

The solution it turns out was a mixture of regular expressions and the almight Func<>.  To begin with I download the NCalc package using Nuget.  This was the easiest way and ensures you have the latest version.  Then I created an ExpressionParser class with an Execute function that took the expression I want to parse as a string parameter.

Code Snippet
  1. public int Execute(string expr)
  2. {
  3.     Validation.IsNotNullOrEmpty(expr, "expr");
  4.  
  5.     string newExpr = ReplaceExpressionMatches(expr);
  6.  
  7.     Expression exp = new Expression(newExpr);
  8.     exp.EvaluateFunction += delegate(string name, FunctionArgs args)
  9.       {
  10.         if (_expressionTable == null)
  11.           return;
  12.  
  13.         CustomExpression customExpr = _expressionTable.Get(name);
  14.         if (customExpr != null && customExpr.ExpressionFunction != null)
  15.           args.Result = customExpr.ExpressionFunction.Invoke(args);
  16.       };
  17.  
  18.     object result = exp.Evaluate();
  19.  
  20.     Int32 outResult;
  21.     Int32.TryParse(result.ToString(), out outResult);
  22.     return outResult;
  23. }

This may look a bit odd, but follow my logic here.  The important part is that the function must convert my syntax (in this case the "L" in the expression) to a function that the NCalc library can parse and that function must have logic associated with it.  So, in the case of the "L" we first want to transform it into something such as "Level()".  The expression started as "2d4+L+4" and becomes "2d4+Level()+4".  This is done using a custom ExpressionTable that we pass into the ExpressionParser during construction.  I'll get to the table and to the ReplaceExpressionMatches() function in a moment.

To continue with the logic of the Execute function, after we replace "L" with "Level()" we create a NCalc Expression object and then a delegate that will be called when that expression is evaluated.  This delegate will invoke each custom function defined within the expression tree and replace it with the result.  So, if the character's level statistic was 16 at the time the expression was evaluated then the debugged expression might look like "2d4+16+4".

Finally, we tell the expression to evaluate itself and then try to parse the result.  That's it!  Pretty clean and straight-forward.  What about the regular expressions and your custom functions you ask?  Well, let's go back to that.

Within the Execute() function we made a call to another function in the class called ReplaceExpressionMatches() that looks like this:

Code Snippet
  1. private string ReplaceExpressionMatches(string expr)
  2. {
  3.     if (_expressionTable == null || _expressionTable.Keys.IsEmpty())
  4.         return expr;
  5.  
  6.     string newStr = expr;
  7.     foreach (CustomExpression customExpr in _expressionTable.Values)
  8.     {
  9.       Regex regex = customExpr.Regex;
  10.       int originalLength = newStr.Length;
  11.       int lengthOffset = 0;
  12.  
  13.       foreach (Match match in regex.Matches(newStr))
  14.       {
  15.         string firstPart = newStr.Substring(0, match.Index 
  16.           + lengthOffset);
  17.         string secondPart = newStr.Substring(match.Index 
  18.           + lengthOffset + match.Length,
  19.         newStr.Length - (match.Index + lengthOffset + match.Length));
  20.         newStr = firstPart + customExpr.ReplacementFunction.Invoke(match) 
  21.           + secondPart;
  22.         lengthOffset = newStr.Length - originalLength;
  23.       }
  24.     }
  25.  
  26.     return newStr;
  27. }

What does this do?  Well, we loop through the CustomExpression objects within the ExpressionTable and do a regex match and replace on every match found (since there could potentially be more than one "L" in our expression).  And then we return the newly updated expression which turned "2d4+L+4" into "2d4+Level()+4".

The last piece is our expression table itself.  Here's what an entry looks like.  The ExpressionFunction is what is called when NCalc does the actual evaluation of the expression (e.g. getting the value of Level()) while the ReplacementFunction tells the ExpressionParser what to replace the regex match with.

Code Snippet
  1. ExpressionTable table = new ExpressionTable();
  2. table.Add(new CustomExpression
  3. {
  4.     Name = "Level",
  5.     RegexPattern = @"^?\b\w*[l|L]\w*\b$?",
  6.     ExpressionFunction = LevelFunction,
  7.     ReplacementFunction = ReplaceLevelCall
  8. });

The final two pieces, the contents of the ExpressionFunction and the ReplacementFunctions.

Code Snippet
  1. private static int LevelFunction(FunctionArgs args)
  2. {
  3.     return GameManager.CurrentCharacter.Level;
  4. }
  5. private static string ReplaceLevelCall(Match regexMatch)
  6. {
  7.     return "Level()";
  8. }

Both functions could probably be handled more elegant, perhaps in a static dictionary, but my primary goal was to make the system flexible.  So the CustomExpression object maintains a reference to each of these functions, one which tells the Replace method what to replace the match with (the word "Level()" in this case) and another which tells NCalc what to do when it encounters the Level() function in an expression (in this case, call the GameManager and get the CurrentCharacter's level).

That about covers it.  There are also unit tests covering the ExpressionTable and the ExpressionParser (giving it 96% coverage in fact).  All of this was packaged into two self-contained libraries for each portability and reference.

I welcome any feedback, suggestions, comments on the code and if you want to see more (including the unit tests) please let me know.

Tuesday, February 25, 2014

BiDirectional Dictionary

I had the need for a dictionary in a personal project recently, but I ran into a bit of a snag.  I needed to be able to look up values from either direction.  That is, both forward (Key to Value) and backward (Value to Key).  Your standard C# Dictionary out of the box doesn't support this behavior.

Fortunately I happened across a good solution from another blogger, Tim Barrass (Bidirectional Lookup).  So, I began implementing it and then writing unit tests to cover it.  In the process I uncovered a couple issues with adding new items and removing them that I corrected.  So, here's the updated dictionary:

The changes are pretty straight-forward:

  1. Changed the secondList.ToList().Add(second); and firstList.ToList().Add(first); calls on lines 49 and 50 to Append to the IEnumerable<> and also to re-assign to the internal dictionaries.
  2. Rewrote the entire Remove() function to remove from the internal lists and if its the last entry remove the keys as well.

Code Snippet
  1. public class BidirectionalDictionary<TFirst, TSecond>
  2. {
  3.     private IDictionary<TFirst, IEnumerable<TSecond>> Forward { get; set; }
  4.     private IDictionary<TSecond, IEnumerable<TFirst>> Backward { get; set; }
  5.  
  6.     private static readonly IEnumerable<TFirst> EmptyFirstList = new List<TFirst>();
  7.     private static readonly IEnumerable<TSecond> EmptySecondList = new List<TSecond>();
  8.  
  9.     public BidirectionalDictionary(IDictionary<TFirst, IEnumerable<TSecond>> forward, IDictionary<TSecond, IEnumerable<TFirst>> backward)
  10.     {
  11.         Forward = forward;
  12.         Backward = backward;
  13.     }
  14.  
  15.     public BidirectionalDictionary()
  16.     {
  17.         Forward = new Dictionary<TFirst, IEnumerable<TSecond>>();
  18.         Backward = new Dictionary<TSecond, IEnumerable<TFirst>>();
  19.     }
  20.  
  21.     public void Add(TFirst first, TSecond second)
  22.     {
  23.         IEnumerable<TSecond> secondList;
  24.         if (!Forward.TryGetValue(first, out secondList))
  25.         {
  26.             secondList = new List<TSecond>();
  27.             Forward[first] = secondList;
  28.         }
  29.  
  30.         IEnumerable<TFirst> firstList;
  31.         if (!Backward.TryGetValue(second, out firstList))
  32.         {
  33.             firstList = new List<TFirst>();
  34.             Backward[second] = firstList;
  35.         }
  36.  
  37.         Forward[first] = secondList.Append(second);
  38.         Backward[second] = firstList.Append(first);
  39.     }
  40.  
  41.     public IEnumerable<TSecond> GetByFirst(TFirst first)
  42.     {
  43.         return Forward.ContainsKey(first) ? Forward[first] : EmptySecondList;
  44.     }
  45.  
  46.     public IEnumerable<TFirst> GetBySecond(TSecond second)
  47.     {
  48.         return Backward.ContainsKey(second) ? Backward[second] : EmptyFirstList;
  49.     }
  50.  
  51.     public void Remove(TFirst first, TSecond second)
  52.     {
  53.         IEnumerable<TSecond> secondList;
  54.         if (Forward.TryGetValue(first, out secondList))
  55.         {
  56.             if (secondList.Contains(second))
  57.             {
  58.                 secondList.ToList().Remove(second);
  59.                 if (secondList.Any())
  60.                     Forward[first] = secondList;
  61.                 else
  62.                     Forward.Remove(first);
  63.             }
  64.             else
  65.                 Forward.Remove(first);
  66.         }
  67.  
  68.         IEnumerable<TFirst> firstList;
  69.         if (Backward.TryGetValue(second, out firstList))
  70.         {
  71.             if (firstList.Contains(first))
  72.             {
  73.                 firstList.ToList().Remove(first);
  74.                 if (firstList.Any())
  75.                     Backward[second] = firstList;
  76.                 else
  77.                     Backward.Remove(second);
  78.             }
  79.             else
  80.                 Backward.Remove(second);
  81.         }
  82.     }
  83. }

And now the unit tests surrounding this code. I used NUnit for this project and as you can see covered nearly all of the behavior within the new class.

Code Snippet
  1. [TestFixture]
  2. public class BidirectionalDictionaryTests
  3. {
  4.     private static BidirectionalDictionary<string, string> _dictionary;
  5.         
  6.     [SetUp]
  7.     private void OnSetup()
  8.     {
  9.         _dictionary = new BidirectionalDictionary<string, string>();
  10.         _dictionary.Add("FirstValue", "FirstLookupValue");
  11.     }
  12.  
  13.     [TestCase("FirstValue", "FirstLookupValue", true)]
  14.     [TestCase("SecondValue", "FirstLookupValue", false)]
  15.     public void GetByFirstTest(string firstValue, string secondValue, bool expectedResult)
  16.     {
  17.         var results = _dictionary.GetByFirst(firstValue);
  18.  
  19.         Assert.That(results.ToList().Contains(secondValue), Is.EqualTo(expectedResult));
  20.     }
  21.  
  22.     [TestCase("SecondValue", "FirstLookupValue", true)]
  23.     [TestCase("SecondLookupValue", "FirstLookupValue", false)]
  24.     public void GetBySecondTest(string secondValue, string firstValue, bool expectedResult)
  25.     {
  26.         var results = _dictionary.GetBySecond(secondValue);
  27.  
  28.         Assert.That(results.ToList().Contains(firstValue), Is.EqualTo(expectedResult));
  29.     }
  30.  
  31.     [Test]
  32.     public void Remove_Test()
  33.     {
  34.         _dictionary.Remove("FirstValue", "FirstLookupValue");
  35.  
  36.         var results = _dictionary.GetByFirst("FirstValue");
  37.  
  38.         Assert.That(results.ToList().Contains("FirstValue"), Is.False);
  39.  
  40.         results = _dictionary.GetBySecond("FirstLookupValue");
  41.  
  42.         Assert.That(results.ToList().Contains("FirstLookupValue"), Is.False);
  43.     }
  44. }

Again, I want to thank Tim Barrass for the initial work on this dictionary. I hope this is helpful to anyone else as its worked great for me.

First Post - Introduction

This is my very first blog post, so here goes.  I'm not entirely sure what I'll be doing with this blog yet, but I suspect it may become a mixture of code, game design, writing, and perhaps even ramblings.  Maybe in the future it will gain more focus.  However, for now here it is.