A while ago a wrote about a mono app I was busy developing. Well this weekend the event took place where my app was used. And expect one little bug in the app (my fault) it worked very very good! Everyone was pleased with the result.Let me explain a bit about the event. It’s called 6 uren loop van zolder (dutch) in english this would translate to something like 6 hour run of zolder , as you prolly guessed its about a group of people running 6 hours 🙂
So these people run laps around the race track of zolder. One round was 3930 meters, I had designed an application that would let them insert new runners but more importantly it was made to keep track of how many laps a runner did. So we set us up in a little box at the start/finish line. Everytime someone came along they yelled the number of the runner and we had to insert it. Not so difficult you would image, right. Okay but imagin this, those runners sometimes stay in groups of 20 people. And all those 20 people come by you have to insert them, believe me the first couple of rounds it was really speed typing and mistakes were not so easy to fix then because the lack of time. At the end reports had to be generated for every category with the best results frist, bad results last. (if you can say that 50 km is bad 🙂 )
How did I do this, well first off this application had to run for 6 hours and had to be pretty stable so linux was off course my prefered choice of OS 🙂
Now I had to choose what language to do it in. Okay for work I do java, but I like to use other languages as well. I have done some project in dotnet in the past, but not yet on linux using mono. This was the best use case I could imagine. I had already played around with monodevelop in the past, so my choice for IDE was easy too. (I also wanted to try out the new version with the plugin system).
Because I really hate writting DAO layers with their CRUD statements.
(CreateReadUpdateDelete)
I used Nhibernate for doing all the Data Access. I’ve used Hibernate frequently in my java projects and wanted to know how far the dotnet/mono version got. I must say they did a pretty good job, only thin that didn’t work for me was the mapping in custom sql statements. ie. You have an object Runner with a property StartNumber that maps to a column Runner_Id, if you want to use it in a custom sql query, you would have to do something like “from Runner order by Runner_id” and not “from Runner order by StartNumber” as is in the java version and what you expect it to be. But hey maybe I didn’t check it good enough, and I didn’t get the CVS version.
Okay a Little example of a hibernate setup:
the mapping file
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0" assembly="6urenloop">
<class name="Categorie" table="categorie">
<id name="CategorieId" column="categorie_id" type="int">
<generator class="assigned"/>
</id>
<property name="CategorieName" column="categorie_name" type="String"/>
</class>
</hibernate-mapping>
The Mapped object
// created on 1/25/2006 at 11:53 PM
using System;
public class Categorie
{
private int _categorieId;
private String _categorieName;
public int CategorieId
{
get{return this._categorieId;}
set{this._categorieId=value;}
}
public String CategorieName
{
get{return this._categorieName;}
set{this._categorieName=value;}
}
}
The Dao
using NHibernate;
using NHibernate.Cfg;
using System;
using System.Collections;
using System.Reflection;
public class CategorieDao{
private ISessionFactory factory;
private static CategorieDao _instance;
private CategorieDao(){
this._Init();
}
public static CategorieDao Instance{
get
{
if(_instance==null)
{
_instance = new CategorieDao();
}
return _instance;
}
}
private void _Init() {
factory = HibernateUtil.Instance.Factory;
}
public Categorie FindById(int id)
{
ISession session = factory.OpenSession();
ITransaction transaction = session.BeginTransaction();
IQuery query = session.CreateQuery("from Categorie where Categorie_Id = :id");
query.SetParameter("id",id);
IList list = query.List();
Categorie cat = (Categorie)list[0];
transaction.Commit();
session.Close();
return cat;
}
public IList LoadAll()
{
ISession session = factory.OpenSession();
ITransaction transaction = session.BeginTransaction();
IQuery query = session.CreateQuery("from Categorie order by categorie_name");
IList list = query.List();
Console.WriteLine("list size : "+list.Count);
transaction.Commit();
session.Close();
return list;
}
}
Pretty straight forward right? As backend database I used mysql. I know there are other people running windows who want the results, this way if they setup a mysql on their windows they can import my tables.
I used 4 tables:
- Runners
- Categories
- Laps
- Results
The first 2 are obvious, but the laps table is a table with 3 columns
- runner_id
- max_lap
- timestamp
Every time a runner passes our box we would insert his startnumber, in the end we can track every runner his laps. This way if there are any wrong entries you can quickly fix them withou
Another thing that was pretty strange in my eyes was getting the selected value from a TreeView the code goes like this:
TreeModel model;
TreeIter iter;
if(this.CategorieLst.Selection.GetSelected(out model,out iter))
{
newLoper.Categorie = (int)model.GetValue(iter,0);
}
With my java background it’s not that obvious, even in my dotnet projects I haven’t seen a construct like this. However in the C language it looks normal 🙂 Guess this is result from binding a C object to C# object. But it works, that’s what matters!
I used glade-2 to create the GUI (as is the standard for creating Gtk applications). I used the glade bindings to connect my gui to my code with the simple lines of code:
Glade.XML gxml = new Glade.XML (null, "6urenloop.glade", "window1", null);
gxml.Autoconnect (this);
And giving my widgets the same name as in the glade file,adding the xml attribute [Glade.WidgetAttribute] is all that is needed. Easy isn’t it?
Here you can find some screenhosts
The screen for inserting new runners:
The screen for inserting laps and creating,exporting the results:
I’m going to make some small adjustments, refactor to use english variables and not dutch variables. Have a GUID for every lap to make updating the laps easier. Once that is done I’ll post it on sourceforge and everybody who does something like this can reuse the code base maybe even update it. You can even check it out for Nhibernate, the documentation of NHibernate isn’t quite as good as the java version.
Ps yes I know, the interface is very ugly and not following the Gnome Guidelines, but it works like a sharm.
Like this:
Like Loading...