Archive for January, 2008

SQL Server CE up and running with NHibernate & NAnt

I’ve been working to get SQL CE to work with our application lately. This is a great step towards a more painless desktop deployment model for us.

It turned out to be a multi step process, and first out was discovering how to make a SQL CE file.

Creating the SQL Server CE .sdf file

There are two alternatives as I see it:

  1. Create an empty database with ie SQL Enterprise Manager, and copy it for new deployment
  2. Create it programmatically at runtime.

We already have a solution folder and a setup for sql-script templates, so we went with #1.

Using NHibernate hbm2ddl NAnt task for the schema

NHibernate has built in support for SQL Server CE, and what you have to do is the following:

  1. Set the connection.connection_string property.
  2. Set the connection.driver_class property.
  3. Set the dialect property.

Our current NAnt build file has had support for SQL Express 2005 & SQL Developer Edition 2005, and our schema target have been doing a great job at creating the proper schema. The hbm2ddl task has been called with the following attributes:

<hbm2ddl
   connectionstring="${sql.nhibernate.connection}"
   droponly="false"
   exportonly="true">
   <assemblies>
      <include name="${directory.build}\ISY.Domain.dll"></include>
      <include name="${directory.build}\ISY.Infrastructure.dll"></include>
      <include name="${directory.build}\ISY.Repository.dll"></include>
   </assemblies>
</hbm2ddl>

So I go ahead and set the connectionstring attribute with the correct settings. And it fails miserably:

NHibernate.HibernateException: An error has occurred while establishing a connection to the server.  When connecting to SQL Server 2005, this failure may be caused by the fact that under the default settings SQL Server does not allow remote connections. (provider: SQL Network Interfaces, error: 26 – Error Locating Server/Instance Specified) —> System.Data.SqlClient.SqlException: An error has occurred while establishing a connection to the server.  When connecting to SQL Server 2005, this failure may be caused by the fact that under the default settings SQL Server does not allow remote connections. (provider: SQL Network Interfaces, error: 26 – Error Locating Server/Instance Specified)

 

Ok, that’s not good. It seems it cannot connect to the server. Checking the ins and outs of the my sql.nhibernate.connection property, I find that it should be pointing to the right file. After some investigation I find out that I miss #2 & #3; setting the correct dialect and driver_class. The hbm2ddl task had default values for dialect and driver_class which works great with both our previously two supported databases. So, I set them both like this:

<hbm2ddl
  connectionstring="${sql.nhibernate.connection}"
  dialect="${sql.dialect}"
  connectiondriverclass="${sql.driver}"
  droponly="false"
  exportonly="true">
  <assemblies>
    <include name="${directory.build}\ISY.Domain.dll"></include>
    <include name="${directory.build}\ISY.Infrastructure.dll"></include>
    <include name="${directory.build}\ISY.Repository.dll"></include>
  </assemblies>
</hbm2ddl>

Where:

<property name="sql.driver" value="NHibernate.Driver.SqlServerCeDriver" />
<property name="sql.dialect" value="NHibernate.Dialect.MsSqlCeDialect"/>

And we’re there with the hbm2ddl.

PS! Don’t forget to add the SQL CE dll into your folder with NAnt, or else it can’t find the right driver with the above settings (an easy to understand error message will tell you).

Populate the database with default data

After the schema is in place, we populate some tables with default system data from sql script files. For this we use the NAntContrib sql task like this:

<sql
  connstring="${sql.connectionstring}"
  delimiter="GO"
  delimstyle="Line"
  source="${target}"
  transaction="${sql.usetransactions}">
</sql>

First, the sql.connectionstring needs to reflect that I am talking to a SQL CE database, and ConnectionStrings.com comes to the rescue once more.

The first obstacle when running the first sql script file is this error:

Error while executing SQL statement.
    There was an error parsing the query. [Token line number,Token line offset,,Token in error,,]

Yes, very enlightening indeed! (Note to self: remember good error messages!). In my search for answers, this seems to be “the be all, know it all” error message.

Finally, it dawned upon me; SQL CE doesn’t support stored procs. And for that reason, why would it understand a script which practically could be a stored proc? Luckily, all our default data is inserted with “ordinary” statements, and the sql task does have an attribute called batch which defaults to true. With SQL CE you need to set it to false and you’re good to go with this setup (where the sql.batch property depends on which database is being used):

<sql
  connstring="${sql.connectionstring}"
  delimiter="GO"
  delimstyle="Line"
  source="${target}"
  batch="${sql.batch}"
  transaction="${sql.usetransactions}">
</sql>

 

Conclusion and further work

All in all, the effort to investigate and include the SQL CE to our array of supported databases is well worth. It will make a one off deployment issues a lot easier with no extra installation, and it is a champ when it comes to our database unit testing and integration testing.

What’s still missing is a script which populates our database with test data. The existing script is not easily split into single statements. We’ll dig into it and I’ll explain it all in a later post!

2 Comments

Automatic versioning with CruiseControl.Net and NAnt

I’ve created a similar setup as David Donald Belcham (a.k.a. igloocoder) mentions in this post for our current project at NOIS.

When I mean similar, we’re using the exact same tools for the job, with NAnt (asminfo task) & CC.NET. But there’s a couple of differences.

New labeller for CC.NET

The first, and minor difference is the labeller. I wanted the versions to work almost as the NAntContrib version task with the automatic build & revision based on day of year and time of day respectively. As most people were running the traditional ymmdd-format for the build, this effectively had to stop at the beginning of 07; 16 bit for the build number breaks that setup. So I settled for an algorithm which won’t break until the year 2066. The major & minor numbers is set manually.

I couldn’t seem to find such a labeller out there, and as I wanted the same number in the CC.NET build-number, and in the assemblies (and in the source control system as well, I’ll get back to that), CC.NET needed to be master. Not finding what I wanted, I created my own labeller for CC.NET, which gives me the build-numbering scheme I wanted.

With the extensibility-points in CC.NET it was great fun, and real easy to deploy my own. Here’s the whole thing:

using System;

using Exortech.NetReflector;

using ThoughtWorks.CruiseControl.Core;

 

namespace Haugern.Util.CCNet

{

    [ReflectorType("versionLabeller")]

    public class VersionLabeller : ILabeller

    {

        [ReflectorProperty("major", Required = true)]

        public int Major;

        [ReflectorProperty("minor", Required = true)]

        public int Minor;

 

        public string Generate(IIntegrationResult integrationResult)

        {

            if(integrationResult == null)

                throw new ArgumentNullException(“integrationResult”);

 

            DateTime now = DateTime.Now;

            return Major + “.” + Minor + “.” + ComputeBuild(now) + “.” + ComputeRelease(now);

        }

 

        private static string ComputeRelease(DateTime now)

        {

            return Math.Round((now.TimeOfDay.TotalSeconds/10)).ToString();

        }

 

        private static string ComputeBuild(DateTime now)

        {

            return now.ToString(“yy”) + now.DayOfYear.ToString(“000″);

        }

 

        public void Run(IIntegrationResult result)

        {

            result.Label = Generate(result);

        }

    }

}

Consistent Build Number

The second difference (well, in his defence, it’s not even mentioned), is that the exact same label should be set back into the source control system. In our case, we’re using TFS Source Control, and with the standard plugin it was easy to apply it there as well.

Now we got this great setup where we can track everything that happens back to the build-number as it is the same across the whole environment:

Application <-> Build server <-> Source Control

Consistent build number across the production line also means every build is a candidate for release.

Should some bug find it way through our thorough unit-testing & qa-scheme into the hands of our customers, finding the right version to search for it will not be a problem!

4 Comments

What happened in 2007

Here the main things that happened in 2007 grouped by month.

January

It’s my last month at my former employee Adrega AS. We’re working hard to get as much as possible done on a new module for our product before I leave. I’m sad to leave, but I think I’ve accomplished a lot as developer and development manager the past 3 years there.

I have my birthday the 8th and I’m just a year from my thirtieth.

February

I start up my career at my current employer Norconsult Informasjonssystemer AS. It’s a soft start, but I eventually get everything up and running and start to get productive on an internal project merging two older applications; Visual Project & GProg ProsjektØkonomi -> ISY Prosjekt Økonomi (project economy). I’ve long neglected a lot of hard core technical topics, but now I’m back in and I start reading technical blogs. I find that they’re a great source for what’s hot. Take a look at my blogroll.

March

Still doing work on ISY Prosjekt Økonomi, I’m mostly doing the administration part. I’m finding it somewhat hard to adjust to my new position, being a peripheral employee in contrast to what I was at my previous job.

April

I’m supposed to get technical responsibility for a new application currently developed by a sub-contractor, but it is in no way finished. So I’m still doing work on the ISY PØ application. I’m getting more involved every day, and I’m doing some interesting work in the core of the application. I’ve stated my interest in development methodologies at work and I’m getting involved with an ongoing quality project. I’m also starting a job making an aggregate installation for the Visual Project product line.

My oldest son turns 3 the 10th, and is definitively growing his own mind by the minute :-) .

May

Working with ISY PØ most of the time. I’m also involved with another section at work regarding  a planning module with a third party tool from Ilog called Gantt for .NET. If I tell it to dance, so it does.

I’m buying a few books from Amazon on development; WCF, WPF, Software factories and some more.

Most of May and June I’m home with my youngest son which is about 9 months old, giving our father-son relationship a real boost.

June

I find myself intrigued by the blogosphere, and I order a web hotel to host a blog.

I’m still mostly changing diapers at home though.

July

It’s a month mostly filled with summer vacation at work.

After a lot of waiting (felt like ages!) my web hotel is around and I start blogging. It’s going slow, but at least I got it out there.

I download my first podcast from .NET Rocks, but don’t listen to it right away.

My wife and I celebrate our 5th wedding anniversary.

August

Things are now rolling at work as I embark on a new development project with some initial analysis and estimation. It was the only thing missing, so I am very pleased with situation at the moment. I’m also guide for two new employees at our section, showing them the out and ins of NOIS and the projects they will start on. They are fresh out of school as MScs.

My youngest son is 1 year old on the 27th.

September

We’re awarded the project we just estimated, and starts up the initial exploratory phase. Deliverables from this phase will be a specification document and a working prototype showing a vertical slice of the architecture and testing its feasibility. I’m also pretty involved with our company’s effort to evolve our development methodologies. My first submission is a guide to source control going a bit further than just check-outs and check-ins; going into labels, branching, merging and general best practices.

I get hooked on podcasts, and I download episodes from .NET Rocks and Hanselminutes continually. My commute is 45 minutes twice a day so I got plenty of time to listen to it. Good thing I have a lot of catching up to do.

October

Now working full time on the prototype, trying some technologies and how they can fit into the big picture. We’re steadily heading towards a smart client solution as a rich and responsive user interface will be crucial. We don’t want any stone unturned, so we’re trying AJAX-solutions and different vendors before we’re going down the Windows Forms-road.

November

We’re settling for the smart client solution, and we’re ramping up the environment (continuous integration ++). We also have our first sprint planning sessions, and project kick-off with all participants.

The wife is 30 years old on the 16th, oh my, she’s old :-)

December

Our first sprint started and we’re developing at full throttle now. We’re going TDD and I find it a very good methodology.

I’ve listened to 114 hours, 20 minutes and 52 seconds of quality podcasts from .NET Rocks and Hanselminutes since September.

We’re celebrating Christmas with my mother and I’m amazed at the all the presents for my sons.

1 Comment

Happy new year!

And good luck with that. 2007 was a great year overall, and I’m hoping 2008 will be just as great.

I’m starting the year adding my blog to the Technorati community. Do place my site in your favourites if you like what you read.

I also have a new year resolution regarding this blog; there will be a post at least once a week.

Phuh… then I’m saved the first week ;-)

No Comments