Thursday, May 17, 2007

Castle ActiveRecord class with stored procedures

Update 05/22/2007: No response from the community. I think Hammett is working on releasing a new version of Castle (It's much more than just ActiveRecord!), so I have not received any feedback on my patch.

I have just posted patch AR-156 to Castle's ActiveRecord project to add support for XML free mapping of insert, update and delete stored procedures to ActiveRecord classes. This requires a bit of work, since the stored procedures must match the field order generated by NHibernate, rather than being controlled by the application developer. This means that we have to create the class normally, run it through a test cycle with logging turned on, capture the prepared statement's field order, and then re-write the stored procedure to match what NHibernate wants. This is because behind the scenes the stored procedure replaces a prepared sql statement that NHibernate would otherwise be using. This will be a mess to maintain until or unless someone contributes a patch to NHibernate that allows us to map :name (or some other named parameter syntax) to the name property of the class. You should notice that NHibernate consistently places the primary key at the end of the parameter list. While it is not perfect, it allows me to meet my requirements to journal all database changes to certain tables.

The code that I submitted is quite simple since I avoided the loader and sql-query mapping elements that would supply Find(primary_key) support. It should theoretically allow stored procedures to be used with any driver and database, although my own testing was limited to SQL Server 2000. It also lacks a critical feature - a working test case. This is the only way that such a feature might reasonably enter the source repository.

The implementation is very easy, and you do not have to provide all of the stored procedures - if you only care about updates, just supply the update attribute ...

insertProc="exec pr_Order_Insert ?, ?, ?",
updateProc="exec pr_Order_Update ?, ?, ?",
deleteProc="exec pr_Order_Delete ?")]
public class Order : ActiveRecordBase

Remember, if you want this patch to be accepted, download it, apply it to your source version of ActiveRecord, build a test case, and vote for it.

Labels: , ,

Tuesday, May 15, 2007

Reflector, Doubler and Unit Testing

Update: the latest versions of Reflector and Doubler are working well together.

I just noticed that Jay Flowers has released a version of the Doubler Add-In that works with the current Reflector by Lutz Roeder. I tried installing Doubler in a sub-directory under Reflector, but it failed to load, so I had to move it into the Reflector directory. The current version of Doubler generates test stubs with a mis-spelled attribute (Memeber instead of Member), but it will generate test stubs, interfaces, recording wrappers, mock objects, etc. It seems like it will be quite handy, with support for NUnit, MBUnit, etc. although Doubler forgets all of your settings every time you move to a new class. That is almost a deal breaker there, but at least you can select an assembly and generate all tests at once. I have to change the output language to c#, change the output path (or just build where the tool wants to go, and copy it), change the default test framework, and set "WithTestAttibutes" aka "With Test AttRibutes". As a good citizen of the open source community, I intend to submit patches for the spelling errors (one is found in namespace Doubler.Templates.UnitTest, file TestTemplate.cs, method VisitTestGenerateMember). I will also look into the configuration issue when I get time, although I know that the path C:\Temp is hard-coded into ReflectorDoubler.

The only thing that bugs me about Reflector is that the code has a time bomb in it, and I am forced to upgrade Reflector every few months (or maybe lie to Windows about the current date). I am sure he does it to reduce bug reports from stale code, and maybe to force developers to try out his new code, but it means that I may have to upgrade any add-ins as well, and I may loose my tool set until critical add-ins are updated. I know, doubler is open source (Reflector is NOT!) and if I have enough time, I could maybe build it, but the doubler project has some HUGE dependencies, and has very elaborate and complicated directory structure. I tried building it from the Google Code repository, but Lutz had changed parts of his plug-in interface, and I did not have time to bother with it. I knew better than to fall into that time trap.

Speaking of time traps, I think that I am doing better at managing my time. I have learned to write clean and simple code where possible, and I am less obsessed with optimizing code that might run once a month. Code that is run rarely needs to be very readable, and easily maintained (aka fixed).


Friday, May 04, 2007

NHibernate 1.20 is released!

NHibernate was released May 3, 2007 and they have a migration guide for those of you who do not follow changes in the svn. This release supports stored procedures, and as you can see in the screen shot above, I am working on adding SQL stored procedure generation to my ActiveRecord Generator. I have templates for INSERT, UPDATE and DELETE now, and I will write a SELECT by primary key today. It's too bad I can't just write an attribute to append to the NHibernate mapping file that ActiveRecord creates. I don't know if I will have to write my own ActiveRecord attributes, but the Castle Project seems very friendly to patches. This is very important because I would not really want to release a program that requires a patched library.

I have found several bloggers who have created NHibernate + Stored Procedure samples, but none that have ActiveRecord samples (since we do not have the attributes yet). If you have been working on something, now is your chance to share. (grin) Just post a patch on the Active Record JIRA.

Speaking of the generator, I have converted it from a hand-coded series of write statements to a table object and a field list passed in to the NVelocity template library (available from the Castle Project in their subversion repository). I feel like I am re-inventing the wheel here ... how many NHibernate / ActiveRecord code generators are there anyway? I am still re-factoring it and building templates. As soon as I have broken the project into a code generating library, a windows UI and a command line UI, I will probably release the source as LGPL. The code generator was written for .Net 2.0, SQL Server 2000 or SQL Server 2005, with helpers for my own coding conventions. I will have to write some tests before I start accepting too many patches, but we can worry about that as I re-factor for testability.

On a personal note, I went to see "300" on iMax, thanks to Blingo and Fandango for the free tickets!

Labels: ,