Thursday, December 11, 2008

Tomboy for windows

When working in Windows I like to use as much Open Source software as possible to make my environment as familiar to my Linux desktop as I can. I have many of the popular applications installed such as Firefox, Thunderbird, Gimp, MySql, and XEmacs (who said XEmacs wasn't popular?!).

Recently a Tomboy preview for windows became available and a few nights ago I finally got round to installing on my laptop. Tomboy is a great application and works the way a note taking application should work.

The install is a little fiddly if you are running Vista due to a bug in the Gtk runtime installer, but it's not too challenging to get running.

If you've ever wanted an application to quickly jot notes into I throughly recommend you give Tomboy a try.

Labels: ,

Wednesday, November 26, 2008

Mono gets some first class love in Ubuntu!

I was pretty excited to see this article on mono in Jaunty Jackalope over at arstechnica today.

It looks like there is going to be a real effort to improve Mono support in Ubuntu and migrate all applications and the CLR to the 2.0 profile.

This is fantastic news - great work Ubuntu devs!

Labels: , , , ,

Wednesday, November 12, 2008

NHibernate onFlushDirty has null previousState

The problem


We use an Entity interceptor to create audit records when we update most tables. We also do a lot of our data access through .NET remoting. This means that we open a session to load the object, the object is detached, serialized, modified, then reattached to the session when we want to persist the changes.


We noticed that in the cases where we are updating detached objects, although the update was being applied correctly there were no audit records appearing in the database. On investigation we realised that the previousState parameter passed into the onFlushDirty method of our interceptor was null.

Why


In the Save method of our data access class we were using the SaveOrUpdate method of the NHibernate session to persist the changes. Section 10.7 of the documentation states:

saveOrUpdate() does the following:

  • if the object is already persistent in this session, do nothing
  • if another object associated with the session has the same identifier, throw
    an exception
  • if the object has no identifier property, save() it
  • if the object's identifier has the value assigned to a newly instantiated
    object, save() it
  • if the object is versioned (by a or ), and
    the version property value is the same value assigned to a newly instantiated
    object, save() it otherwise update() the object


and merge() is very different:

  • if there is a persistent instance with the same identifier currently
    associated with the session, copy the state of the given object onto the
    persistent instance
  • if there is no persistent instance currently associated with the session,
    try to load it from the database, or create a new persistent instance
  • the persistent instance is returned
  • the given instance does not become associated with the session, it remains
    detached

As our detached objects had an Id and version when we called SaveOrUpdate() they were being updated, and seeing as all update() does is reattach an object to the session, the session had no record of the changes that had been made to that object since it was loaded.



The solution


The solution was to use the merge() method (new in NHibernate 2.0). Merge() checks the first level cache to see if an object with the given identifier has previously been loaded. If so it loads that object out of the first level cache and updates it's properties using the detached object. This means that the session is now able to track the changes made to the object so that when the flush occurs the previousState is no longer null.

Labels: , ,

Thursday, November 06, 2008

NMock and out parameters

While trying to create a unit test the other day I came across the situation where my mock object needed to return a value via an Out parameter. A quick google turned up this post over at dev:ices.

I thought that had answered all my questions but when I tried it I kept getting a very unhelpful error:

------ Test started: Assembly: Tests.dll ------

TestCase 'Tests.BatchOrderMessageHandlerTests.TestNMock'
failed: NMock2.Internal.ExpectationException : unexpected invocation of foo.DoFoo(<1>, <1>, out)
Expected:
1 time: foo.DoFoo(equal to <1>, equal to <1>, equal to ), will set c=<2>, return <1> [called 0 times]
at NMock2.Mockery.FailUnexpectedInvocation(Invocation invocation)
at NMock2.Mockery.Dispatch(Invocation invocation)
at NMock2.Mockery.MockObject.Invoke(Invocation invocation)
at NMock2.Monitoring.Invoker.Invoke(Invocation invocation)
at NMock2.Monitoring.ProxiedObjectIdentity.Invoke(Invocation invocation)
at NMock2.Monitoring.ProxyInvokableAdapter.Invoke(IMessage msg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at Tests.BatchOrderMessageHandlerTests.IFoo.DoFoo(Int32 a, Int32 b, Int32& c)
C:\svn\GLGParnters.TradeIdeas\PositionManager\src\Tests\BatchOrderMessageHandlerTests.cs(136,0): at Tests.BatchOrderMessageHandlerTests.TestNMock()

0 passed, 1 failed, 0 skipped, took 0.77 seconds.



A bit confused I quickly whipped up a trivial test as my unit test was a bit complicated and returned an enum as the Out parameter. My hypothesis was that NMocks couldn't return an enum as an Out parameter.

public interface IFoo
{
int DoFoo(int a, int b, out int c);
}


[Test]
public void TestNMock()
{
IFoo foo = _mockery.NewMock();

Expect.Once.On(foo).Method("DoFoo")
.With(1, 1, Is.Out)
.Will(new SetNamedParameterAction("c", 2), Return.Value(1));

int result = 0;
int a = foo.DoFoo(1, 1, out result);

_mockery.VerifyAllExpectationsHaveBeenMet();
Assert.AreEqual(2, result);
}


This also failed so I checked what version of NMocks I was using. My NMock2.dll assembly had a revision number of 1.0.2313.18049. I downloaded the latest binaries from the NMock website. Checking the version number of the latest build shows it to be 2.0.0.44.

Rerunning the unit tests against this version of the NMock library everything now works!

So, if you're having trouble with out parameters in your NMock mocks, upgrade your build version.

Labels: , ,

Wednesday, November 05, 2008

NHibernate 2.0 and the join table syntax

I've noticed my post on Mapping a view with NHibernate is always quite popular. Resorting to mapping from a view has worked fine in the past as long as you only required read access, but if you wanted to build a complex object relational mapping that you could update you were in trouble...

Until Now

With NHibernate 2.0 recently being released we now have access to the join table syntax in our mapping documents. This means we can now build more sophisticated domain objects that map on to more than one table. NHibernate takes care of the multi-table inserts and updates behind the scenes making your life easier.

This has to be one of the most underrated features of NHibernate 2.0 as it finally allows you to break away from the one to one mapping between domain objects and your relational model which has ultimately caused compromises in the past.

I urge you to check out this and the other fantastic new features available in the latest NHibernate release.

Labels: , , ,

Thursday, July 24, 2008

Mono bugs fixed; Spring.Net support coming soon!

I've managed to get all my Mono patches committed in time for 2.0 which be released very soon. Bugs I've fixed are:

#325128 ConfigurationSection.GetRuntimeObject
#395209 Fix incompatibility in the HierarchicaDataBoundControl
#397612 Mutually exclusive behaviour between Mono and MS.NET for xs:import

As well as a couple of other fixes I didn't create bugzilla bugs for:
The TypeDescriptor bug which I blogged about a while ago, and another XmlSchema bug where Uri.OriginalString wasn't being returned in the correct case.

Hopefully with these Mono bugs fixed in the latest release the major barriers to getting Spring.Net support finished and committed in will be removed. I'm in the process of working through my patch with Mark Pollack, so all going well we may see some Mono support in the next Spring.Net release.

Labels: , , , ,

Friday, May 23, 2008

Patching Mono

I submitted a fix for bug #325128 last night which was the last of the four patches needed get Spring.Net working on the Mono runtime. So far I've submitted patches for:

  • TypeDescriptor

  • XmlSchema

  • HierarchicalDataBoundControl

  • ConigurationSection


So far only the TypeDescriptor patch has been accepted and committed to the repository, but hopefully the other three won't be far behind. It's quite important to us that these patches make it into the 2.0 release so we can just use the official builds rather than having to build from source ourselves.

Labels: , , , ,

Wednesday, May 21, 2008

Using MySQL in heterogeneous environments.

If like us you have a requirement to run MySQL in a mixed Windows and Linux environment and you want your database to be portable you will need to change the default case sensitive table name behaviour of MySQL on one of the operating systems. On Windows the default behaviour is case insensitive, on Linux the default behaviour is case sensitive.

I like my table names to stay in the same case I scripted them in so we chose to change Windows to be case sensitive. The fix is pretty simple - you just need to add the following line to your my.ini after [mysqld] and restart your mysql service.

lower_case_table_names = 0

Existing objects won't suddenly change case, but any new tables you add to your database will appear in the same case you scripted it in. See the mysql documentation for more details.

Labels: ,

Monday, April 28, 2008

Spring.NET on Mono

It's been a while since my last post because I've been extremely busy hacking away to get Spring.NET working on Mono. I've basically got a working solution now so we should hopefully get the changes committed back into the Spring.NET repositories in the next couple of weeks.

It's been a bit of an interesting road so far - transistioning our application onto Mono - and I am a bit surprised at how many framework bugs I've discovered. I've submitted one patch so far for a very minor bug in the TypeDescriptor class, however I still have three more patches to write and submit at this point. I wouldn't have thought that the parts of the framework we are using were especially esoteric but perhaps I'm wrong.

Now all I need is stepping debugger integration in MonoDevelop and I won't have to boot into Vista ever again!

Labels: , , ,

Sunday, April 06, 2008

Url Rewriting and the dreaded "Cannot use a leading .. to exit above the top directory"

I've just had a fun couple of hours trying to figure out why my site suddenly starting giving me this exception:

Exception type: HttpException
Exception message: Cannot use a leading .. to exit above the top directory.

It turns out that ASP.NET 2.0 doesn't like playing nicely with Url Rewriters. The problem occurs when the rewriting rebases the form action path. e.g instead of having your form tag look something like this:

<form id=form1 method="post" action="page.aspx?id=whatever" name="form1">

After rewriting it ends up looking like this:

<form id=form1 method="post" action="../page.aspx?id=whatever" name="form1">

This obviously is not a good thing. For a detailed breakdown of the problem I suggest you read sgerz's post Get GoogleBot to crash your .NET 2.0 site.

In my particular case I am using an open source url rewriter solution from http://urlrewriter.net. Of course the beauty of it being open source is that you can fix the problem! So a one line change on line 80 of HttpContextFacade.cs from:

HttpContext.Current.RewritePath(url, false);

to

HttpContext.Current.RewritePath(url, true);

solved the problem.

So why did this start happening all of a sudden? I can only surmise that it had something to do with the fact that I had just installed Vista SP1 and that caused cassini to start behaving as IIS 6.0 does.

I'll be emailing the maintainers of the project to see if they want to make the change to the main repository.

Labels: , ,

Wednesday, March 26, 2008

MonoDevelop 1.0 Released

I've been pretty slow in blogging about this but it's still worth pointing out that MonoDevelop 1.0 has officially been released. It's becoming a really feature rich and mature piece of software now and is definitely worth investigation if you do any development on a Linux platform.

Roll on 1.1 in six months time!

Labels: , ,

Saturday, June 23, 2007

Finally got my patch committed!

I'm stoked. With the release of MonoDevelop 0.14 my class and member selectors are finally in the core MonoDevelop. I know it's only a small contribution, but personally it's a feature I find very useful so I hope other people are deriving some benefit from that work too. I do notice that most of the screen shots of MD I see have them enabled so I guess it's not annoying people enough to turn it off!

Anyway, here is my little claim to fame:
http://www.monodevelop.com/Release_notes_for_MonoDevelop_0.14

Labels: ,

Tuesday, April 24, 2007

Ndbunit is great - once you get past the pain

Over the last few days I've been setting up my latest project to use Ndbunit to initialise the database to known state prior to running each of my unit tests. It has been a bit of painful process as the documentation is fairly minmal and non-existant for some features, but I think I've got there now.

A couple of things I wanted to put down here in case I ever forget them and start banging my head on the desk again!

Firstly if you want to use the InsertIdentity method you need to make sure your xsd sets the AutoIncrement attribute to true for your identity column. eg.

<xs:element autoincrement="true" type="xs:int" name="PERSON_ID">

Secondly if you want to insert more than one row into a table you need to make sure your xsd sets the IsDataSet attribute to true e.g

<xs:element name="PERSON" isdataset="true">

Labels: ,

Wednesday, March 21, 2007

subversion 1.4.3 on ubuntu Edgy amd64

Just went through a few dramas tonight to upgrade svn on my system from the old 1.3.2 version that is in the ubuntu repos to the latest 1.4.3.

I found this howto which gets you almost all the way there. Unfortunately amd64 uses will get a link error complaining that libneon.a needs to be compiled with the fPIC flag. This is easily fixed by changing the following line in neon/src/Makefile (line 28) after the configure step from this
CFLAGS = -g -O2
to
CFLAGS = -g -O2 -fPIC

then you make and install as per the howto.

HTH!

Labels:

Monday, February 26, 2007

Cool open source .NET charting component

I've been looking around for a decent free (as in beer) .NET charting component that I can use from ASP.NET for my current website project. At first I tried WebChart, but it didn't seem to want to work under mono. I could have probably figured out the problem with a little bit of effort, but I've got better things to spend my time on at the moment. So a little more digging and a search of the Mono mailing list uncovered zedgraph. This component is awesome. Take a look at some of the sample graphs - it produces really professional looking results.

Now I haven't delved into the guts of it yet, that's tonight's task, but I just wanted to let people know it's out there.

Labels:

Friday, February 16, 2007

nhibernate - a complex beast

I am beginning to discover that nHibernate is a far more complex beast than I realised. Over the last couple of days I've spent some more time reading the documentation (out of necessity rather than pure interest) and it is capable of some amazing things, however this flexiblity comes at the cost of complexity (as is often the case).

Here's an example of a trap for young players that caught me the other night. I have two entities A & B that map two two underlying tables tableA and tableB. The primary key of tableA is a foreign key in tableB. tableA contains a property Rating1Count which is the count of a column in tableB. I had code similar to the following:

ISession session = NHibernateHttpModule.CurrentSession;
ITransaction transaction = session.BeginTransaction();
try
{
    log.Debug("Saving new B");
    session.SaveOrUpdate(b);

    log.Debug("saved new B");
    ICriteria crit = session.CreateCriteria(typeof(A));
    crit.Add( Expression.Eq("AId", a.AId) );
    log.Debug("Executing query");
    IList As = crit.List();
    if (As.Count == 1)
    {
        a = As[0] as A;
        log.Debug(string.Format("Count of 1s in tableB {0}", a.Rating1Count));
    }
    transaction.Commit
}

After testing this I found that even though my changes were being persisted to tableB (verified by querying mysql directly) they weren't reflected in my tableA object.

Then it dawned on me, at what point does nhibernate write the changes to the database? I moved the transaction.Commit line up to be directly below the call to SaveOrUpdate and lowe and behold it works!

In hindsight it's obvious, but it had me scratching my head for a while (and it was late - at least that's my story and I'm sticking to it!).

Labels: ,

Friday, July 07, 2006

MonoDevelop hacking

Spent the last couple of evenings updating some work I did on MonoDevelop ages ago but never got round to submitting. The internals of MonoDevelop have really changed since I first wrote my code so I had to spend a couple of hours updating it to work with the new version of MonoDevelop from SVN.

I then realised that I hadn't quite got it right last time as the method combo would only show the methods the class had when the file was opened. i.e. if you added a new method it wouldn't show up in the combo until you closed and reopened the file. With some helpful pointers from Lluis on #monodevelop last night I think I have just about solved that problem by hooking into the IParseInformationChanged event. This event fires with every key stroke. With a bit of GLib.Timeout goodness to stop the combos being rebound every time the event fires we are almost there...

Labels: ,

Saturday, April 01, 2006

Gtk# woes

Well, I have spent a decent amount of time hacking on f-spot today and have achieved exactly nothing. I have two problems to fix before the first cut of the Compare view for f-spot will be ready for review. One is a nasty problem with scroll bars not rendering correctly. I have a feeling that this is to do with the underlying ImageView class and so not something I can fix without talking to Larry Ewing about it. The second problem is I can't seem to get any events firing of the those same scroll bars so I suppose it could be somewhat related. Hopefully I will be able to catch Larry on IRC next week and sort it out.

Labels:

Tuesday, March 28, 2006

f-spot compare view


f-spot compare view
Originally uploaded by roboguy.

A quick screenie of some early work on the compare view in f-spot.

Labels: