Great Query DSL

Update: Ayenda replied with the following

This is Rhino Commons repository + NHibernate Query Generator code.

Ayende posted an example of a great query DSL. Is this real? If so, where can I download this framework?

ICollection<Event> eventsInTwoDays = Repository<Event>.FindAll(        Where.Event.ScheduledDate == DateTime.Today.AddDays(2) &&        Where.Event.Participants.With(FetchMode.Join)    );

Flattering

I want to thank the person that added my blog as a reference for MonoRail on Wikipedia. I am flattered.Thanks.

C# Puzzlers: Elvis Lives

I was a Java instructor earlier in my career. The best thing about being a Java instructor is you really learn Java. I knew Java as well or better than anybody while I was teaching. I quickly learned that students ask the best questions and they forced me to truly understand Java.A group of developers, at work, started exploring Java Puzzlers. Java Puzzlers reminded me about how well I knew Java and how I don’t have the same depth of knowledge in C#. I want/need the same depth of knowledge in C# as I do in Java.I am currently working my way through the Java puzzlers in C#. This post is the result of the first puzzler. This puzzler was written by Jeff Grigg.Given the following: What will be printed to the console?

public class Elvis : King{    public bool IsAlive = true;    protected override void Kill()    {        IsAlive = false;        Console.WriteLine("The king is dead.");    }    public static void Main(String[] args)    {        Elvis elvis = new Elvis();        if (elvis.IsAlive)            Console.WriteLine("Long live the king!");        Console.WriteLine("Hit enter to continue....");        Console.ReadLine();    }}public abstract class King{    public King()    {        Kill();    }    protected abstract void Kill();}

It turns out it only prints

The king is dead.

This went against my instinct. Why? The same puzzler prints

The king is dead.Long live the king!

in Java. Java does not execute public bool IsAlive = true; until after the super constructor executes.This obviously does not happen in C#. C# must initialize all member variables before executing the constructor. This behavior seems to be more obvious than the Java behavior. I guess I should try not to think so hard when I am working through these puzzles ;)The code for the puzzlers can be found in my svn repository.https://esterline.devguard.com/svn/code/csharp_puzzlers

No Dots

On my last project, James and I started the slogan “No Dots”. “No Dots” reminds us that templates/views are “documents with holes” and should contain a very minimum amount of logic.

I amended the slogan to be: “Zero or One Dot”. You will see why shortly. The amended version was an artifact of using NVelocity. 

The example below is the reason behind the slogan.

Note: This example is in NVelocity, but it really applies to any template engine. 

#if(person.Age > 10)<div class="discount">Team</div>#end#if(person.Age > 20)<div class="discount">Network</div>#end#if(person.Age > 30)<div class="discount">World</div>#end

Is this code bad? Not really. The logic in the view is minimal.I say this view might be acceptable in a small project. The problem occurs when a project gets large. Why? Testing any logic in the view is hard and therefore does not get tested throughly. This under-tested logic is a breading ground for new bugs.James and I created a solution to this problem that James coined as the Advocate pattern.

Does this “pattern” have another name? 

What is an Advocate?The advocate is a “plain old object”, living outside the view, that answers questions about a model or models for a specific view.Enough with the definition, we want to see the code.PersonAdvocate

public class PersonAdvocate{    private Person person;    public PersonAdvocate(Person person)    {        this.person = person;    }    public void IList<Discount> Discounts    {        get        {            IList<Discount> discounts = new List<Discount>();            if(person.Age > 10) discounts.Add(new Discount("Team"));            if(person.Age > 20) discounts.Add(new Discount("Network));            if(person.Age > 30) discounts.Add(new Discount("World"));        }    }}

NVelocity Template

#foreach($Discount in $PersonAdvocate.Discounts)<div class="discount">$Discount.Name</div>#end

The above template code is an example of “One Dot”. Allowing “One Dot” means that only one object needs to be put into the template’s context. Sticking to “No Dots’ would force one object in the context per hole in the template. I am willing to allow “One Dot”, but no more.

The new version of the template is less complicated and more resistant to change. The decisions about what discounts to display are encapsulated in PersonAdvocate. Moving the logic from the template to the advocate made it easier to test and refactor. Advocates allowed us to fix buggy view logic that finally stayed fixed.

ActiveScaffold – Improved Search

As I noted in my last post, I have changed projects. In my current project, we are using a combination of Ruby and Java. A small group of developers (including me) on the project were tasked with creating a set of automation tools. One of the tools we needed was a small data gathering and reporting application to help our project managers keep track of our progress. The logical choice, for us, was to implement our reporting tool in Ruby on Rails (ROR).Why ROR? One word, “Scaffolding”. If you are not a Ruby or ROR fan, you may not be familiar with Scaffolding (screencast). Scaffolding gives a developer “declarative” control over the user interface.The original scaffolding is really not meant to be a full fledge declarative user interface. It was really intended to be a starting point. The original scaffolding does not support relationships very well (as in not at all). Given this information we knew that we needed to find a rails plugin that could do more than the original. We had two choices.

  1. Streamlined – This was the first plugin that we evaluated. We really liked the interface that it generated and its configuration syntax, but we were not happy with how it allowed users to create related objects. Creating a new relationship in Streamlined is a heavy three step process.
    1. Goto related object’s page and create the new related object.
    2. Return to the parent page.
    3. Apply the relationship to the desired parent.
  2. ActiveScaffold – This was the second plugin that we evaluated. ActiveScaffold allows users to create anything and everything about a record from a single page. This was really attractive to us. ActiveScaffold allowed us to quickly add relationships without have to move to multiple parts of the application.

ActiveScaffold won the race in the end. Armed with ActiveScaffold, we were able to quickly to implement our reporting application. One criticism from our users was the somewhat weak search that ActiveScaffold exposes.The default search is a simple ‘%like%’ search on all columns in a given record. Our users wanted to be able to negate a search. Give me all records except those that contain X. What can we do? ActiveScaffold does not support this functionality. We can go hacking 😉 The module in ActiveScaffold that implements this functionality is ActiveScaffold::Finder; specifically the create_conditions_for_columns method.This is my hacked up version of create_conditions_for_columns. Negation is triggered by placing a ~ in front of a term. Example: ~adam. Fill free to take this code and do with it as you wish. Hopefully someone else can make use of it. As always, questions and comments are welcome.

def self.create_conditions_for_columns(tokens, columns,    like_pattern = '%?%')  # if there aren't any columns, then just return a nil condition  return unless columns.length > 0  tokens = [tokens] if tokens.is_a? String  phrases = []  tokens.each do |token|    where_clauses = []    not_token = /^~/.match(token)    not_clause = not_token ? 'NOT' : ''    columns.each do |column|      where_clauses <<        "LOWER(COALESCE(#{column.search_sql}, '')) REGEXP ?"    end    phrases << "(#{not_clause} (#{where_clauses.join(' OR ')}))"  end  sql = phrases.join(' AND ')  tokens = tokens.collect do |value|    value = /^~/.match(value) ? value[1..-1] : value    value = '.' if value.empty?    [value.downcase] * columns.length  end.flatten  [sql, *tokens]end

Attribute Fun with Ruby

I have been working with Ruby a lot lately. I came across something interesting today, so I thought that I would share it.Given the following code, what do you think will be printed to the screen?

class Person  attr_accessor :last_modified  def update_last_modified    last_modified = Date.today.to_s  endendperson = Person.newperson.update_last_modifiedp person.last_modified

Coming from C#, I thought that it would print today’s date. Once again, I was wrong. It prints nil. Why would it print nil?I assume Ruby thinks last_modified is a local variable and not an attr_accessor in the method update_last_modified. I guess this makes sense. How would Ruby know it was an accessor and not a variable?To get the results that I wanted the update_last_modified would have to change to the following.

def update_last_modified  self.last_modified = Date.today.to_send

It seems a little strange to see the self coming from C#. I would never put a this in front of a property setter.If you would like to see the full code snippet, you can check it out of subversion.https://esterline.devguard.com/svn/code/ruby_snippets

NHibernate/ActiveRecord Bug?

We receive the following exception when our system is under high load. Has anyone else seen this problem? Any ideas?

Exception type: ADOExceptionException message: could not initialize a collection:at NHibernate.Loader.Loader.LoadCollection(ISessionImplementor session, Object id, IType type)   at NHibernate.Loader.Collection.CollectionLoader.Initialize(Object id, ISessionImplementor session)   at NHibernate.Persister.Collection.AbstractCollectionPersister.Initialize(Object key, ISessionImplementor session)   at NHibernate.Impl.SessionImpl.InitializeCollection(IPersistentCollection collection, Boolean writing)   at NHibernate.Collection.AbstractPersistentCollection.ForceInitialization()   at NHibernate.Impl.SessionImpl.InitializeNonLazyCollections()   at NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies)   at NHibernate.Loader.Loader.LoadEntity(ISessionImplementor session, Object id, IType identifierType, Object optionalObject, Type optionalEntityName, Object optionalIdentifier, IEntityPersister persister)   at NHibernate.Loader.Entity.AbstractEntityLoader.Load(ISessionImplementor session, Object id, Object optionalObject, Object optionalId)   at NHibernate.Loader.Entity.AbstractEntityLoader.Load(Object id, Object optionalObject, ISessionImplementor session)   at NHibernate.Persister.Entity.AbstractEntityPersister.Load(Object id, Object optionalObject, LockMode lockMode, ISessionImplementor session)   at NHibernate.Impl.SessionImpl.DoLoad(Type theClass, Object id, Object optionalObject, LockMode lockMode, Boolean checkDeleted)   at NHibernate.Impl.SessionImpl.ImmediateLoad(Type clazz, Object id)   at NHibernate.Proxy.LazyInitializer.Initialize()   at NHibernate.Proxy.CastleLazyInitializer.Intercept(IInvocation invocation, Object[] args)   at CProxyTypeSIROffices_ModelLocationModel_NHibernate_ProxyINHibernateProxy_System_Runtime_SerializationISerializable2.get_Name()   at SIROffices.Model.Listing.FindLocationNodesByPropertyID(Int32 propertyId)   at SIROffices.Model.Listing.FindSalesNeighborhoodByLocationTree()   at SIROffices.Model.Listing.GetSalesNeighborhood()   at SIROffices.Model.Listing.get_SalesNeighborhood()Could not perform ExecuteQuery for SaleListingCastle.ActiveRecord.ActiveRecordBase.ExecuteQuery(IActiveRecordQuery query)   at Castle.ActiveRecord.ActiveRecordBase`1.ExecuteQuery2[R](IActiveRecordQuery`1 query)   at Castle.ActiveRecord.Queries.SimpleQuery`1.Execute()