Thursday, June 21, 2012

Better MVC Enum Dropdown List Implementation

Created a new ASP.NET MVC extension method for creating a “DropDownListFor” an Enum or nullable enum.

Features:

  • Automatic support for nullable Enum property types.
  • Automatic conversion of camel cased enumeration name to human readable name.
  • Supports custom name generation for enumeration values.
  • Auto-orders options by name.

If you want to add a feature that’s not there, feel free to fork the gist below and go crazy! (let me know and I’ll update it here too!)

Thursday, February 9, 2012

Introducing FluentMySQL

Just a quick post having pushed a new project up to GitHub called FluentMySQL, here’s a quick intro:

Overview

This is framework, hoping to solve a very specific problem: building SQL statements which are easy to validate, refactor and help maximise re-use.

Before coming to write this framework, my experience has been with working with in-house database (leaky) abstraction layers, hand-writing SQL builders within frameworks and also the mybatis (previously Apache iBatis). This project has therefore come out of wanting to have the control of writing pure SQL but with the separation and modularity of writing SQL in a framework such as iBatis.

I can foresee that this project could be useful both as a standalone framework to generate SQL to run manually, but also as a feeder into a project to wrap up the execution and mapping of result sets to objects.

Design Principals

Consistency: The feature-set and design should aim to be one-to-one with the MySQL grammar.

Specific: Want to solve a fairly narrow problem, but solve it well. If this works well, then hopefully the same principals could be applied for other such grammars or frameworks.

Immutability: A single query object should not be able to be modified; rather, new copies should be produced on each modification. This makes the approach more akin to that of functional programming (and F# was also a serious consideration for this project).

Tuesday, January 17, 2012

Code generation workflow brainstorming

Since starting work at Pebble {code} one of the exciting new areas that I’ve been looking into is code generation (or automatic programming). The use case is simply auto-generating the bulk of database access code directly from the database model its self allowing quicker changes to the core model as you’re not having to re-write database access code along with every model change. This also allows for a higher level of abstraction, therefore allowing higher productivity with less code to directly maintain.
The current code generation approach we’re using is based around the open source MyGeneration tool. For the design of the model we’re using MySQL workbench for modelling the database. For the database interaction we’re using the Apache iBatis project for database mapping.
The current workflow for making a change to the model goes something like this:
  1. Create table(s) in the MySql workbench model
  2. Export updated create script
    1. Also create any migration scripts required to update the existing database with your changes
  3. Re-create your local development database with the changes
  4. Open MyGeneration and add any required metadata
  5. Select the tables and objects you want to re-generate
  6. Execute code generation
  7. Perform required manual integration of the generated code
  8. Add any additional handmade code to compliment the generated code
This current workflow can introduce friction to integration in two main areas:
  1. Generating code off the local database does not ensure that the database has the latest set of changes, or is even generated from the current branch of development. Re-deployment of the database can also be a time-consuming process if it’s having to be run multiple times.
  2. The MyGeneration tool has a single install path and is therefore a shared component, not specific to the current branch of development or included alongside the source control.
Therefore, my current ideas around this area are to research the feasibility of two main changes.

Remove deployment to an actual database before generating code

The ideal solution here would be to have a method of extracting the database metadata from as close to the original model as possible. A good point of interception could be the SQL database create script. Theoretically it could be possible to work directly with the workbench files, however these are far less stable in standardisation than SQL and would be more likely to change and require more on-going work, whereas the SQL syntax is very strictly defined.
My current research in this area is to use ANTLR to parse the MySQL grammar (zip file), and create an object model to represent the created database. Initially this would just be supporting table creation statements, but could theoretically also extend to views and stored procedures. A good example of the object model is the interfaces used in the MyMeta project of MyGeneration.

Integrate code generation into the IDE

I’m looking specifically at the T4 Text Templates. This tool is specifically quite useful as it has tight integration with Visual Studio (and other .Net IDEs) as well as being able to be run on the command line directly.
The T4 engine is designed specifically to create a single output file off of a single template but can also be adapted to generate multiples files. Using the MyGeneration tool to generate multiple files also uses a similar technique. This would therefore mean that there is a single control template which gets the input model using the previous technique, then runs all the sub-templates to create the files in the correct locations.

Tuesday, December 20, 2011

Creating possible combinations from a list of lists in F#

Just a short post after I came across an interesting problem while learning F# and couldn’t find any great resources to solve what seems to be quite a generic problem.
The scenario is:
  1. You have a list of lists where each of the inner lists contains 1 or more element.
  2. You want to find all possible combinations where you take precisely one element from each inner list.
The example of where I found this problem is calculating the possible value of a hand in blackjack:
  • You have a set of cards
  • Each card has a value
  • Ace has both the value 1 and 11 at the same time
  • You might be holding more than 1 ace
Therefore we want to be able to calculate the possible values the card could be determined to have.
We represent the value of each card as a list. The five of hearts is [5], the jack of clubs is [10], and the ace of spades is [1;11]. If you hold all three of these cards in your hand you can either make 16 or 26.
We would represent this hand as [[5];[10];[1;11]] and would ultimately aim to get our results in the form [16;26]. However as an intermediate step we want to transform our hand into a list of possible card values such as [[5;10;1];[5;10;11]] which we can then simply sum to get our result.
Here’s the function that recursively expands all combinations, returning a list of each combination of items.
let rec combinations (l) =
    match l with
    | [] -> []
    | h::[] -> h |> List.map (fun opt -> [opt])
    | h::t ->
        combinations t
        |> List.map (fun tOpts ->
            h |> List.map (fun hOpt -> hOpt ::tOpts)) 
        |> List.concat

Essentially, a quick line by line run through is:


  1. To cover all cases, if this is called with an empty list, just return an empty list. This is not used in the recursion.
  2. If we are looking at the last list of options then return each option as a new list containing only itself.
  3. If we are in the middle of the list (or equally the start) then get the combinations of the tail option lists giving us a list of combinations.
  4. For each combination,:

    1. For each option in the current set of options

      1. Add the option to the beginning of each of the tail combinations
  5. Flatten the list of tail combinations of head options to outcome list to a list of outcome lists.

Friday, December 2, 2011

A New Home

So, just a quick blog post as I've just opened my new danielbradley.net blog as a place to write up some of the things I'm doing. This is taking the place of my old GeeksWithBlogs account as it'll hopefully be a little easier to keep up to date and just write quick posts here.

About the name "The Argumentative Exception": this is just a little play on words about the fact that I'm not really a confrontational person, apart from when talking about software development (or so I'm told)!