{"id":19,"date":"2006-02-21T16:00:24","date_gmt":"2006-02-21T15:00:24","guid":{"rendered":"http:\/\/blog.pczone.be\/?p=19"},"modified":"2006-02-21T16:19:00","modified_gmt":"2006-02-21T15:19:00","slug":"monoglade-app-did-the-job","status":"publish","type":"post","link":"http:\/\/blog.pczone.be\/?p=19","title":{"rendered":"Mono\/glade app did the job"},"content":{"rendered":"<p>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&#8217;s called <strong><em>6 uren loop van zolder<\/em><\/strong> (dutch) in english this would translate to something like <em><strong>6 hour run of zolder <\/strong><\/em>, as you prolly guessed its about a group of people running 6 hours \ud83d\ude42<\/p>\n<p>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, <em>bad <\/em>results last. (if you can say that 50 km is bad \ud83d\ude42 )<\/p>\n<p>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 \ud83d\ude42<\/p>\n<p>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 <a href=\"http:\/\/www.monodevelop.com\/Main_Page\"><strong>monodevelop<\/strong><\/a> in the past, so my choice for IDE was easy too. (I also wanted to try out the new version with the plugin system).<\/p>\n<p>Because I really hate writting DAO layers with their CRUD statements.<br \/>\n(<strong>C<\/strong>reate<strong>R<\/strong>ead<strong>U<\/strong>pdate<strong>D<\/strong>elete)<br \/>\nI used Nhibernate for doing all the Data Access. I&#8217;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&#8217;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 <strong>&#8220;from Runner order by Runner_id&#8221;<\/strong> and not <strong>&#8220;from Runner order by StartNumber&#8221;<\/strong> as is in the java version and what you expect it to be. But hey maybe I didn&#8217;t check it good enough, and I didn&#8217;t get the CVS version.<\/p>\n<p>Okay a Little example of a hibernate setup:<br \/>\n<strong>the mapping file<\/strong><\/p>\n<pre>\r\n&lt;hibernate-mapping xmlns=\"urn:nhibernate-mapping-2.0\" assembly=\"6urenloop\">\r\n\t&lt;class name=\"Categorie\" table=\"categorie\">\r\n\t\t&lt;id name=\"CategorieId\" column=\"categorie_id\" type=\"int\">\r\n\t\t\t&lt;generator class=\"assigned\"\/>\r\n\t\t&lt;\/id>\r\n\t\t&lt;property name=\"CategorieName\" column=\"categorie_name\" type=\"String\"\/>\r\n\t&lt;\/class>\r\n&lt;\/hibernate-mapping>\r\n<\/pre>\n<p><strong>The Mapped object<\/strong><\/p>\n<pre>\r\n\/\/ created on 1\/25\/2006 at 11:53 PM\r\nusing System;\r\n\r\npublic class Categorie\r\n{\r\n\tprivate int _categorieId;\r\n\tprivate String _categorieName;\r\n\t\r\n\tpublic int CategorieId\r\n\t{\r\n\t\tget{return this._categorieId;}\r\n\t\tset{this._categorieId=value;}\r\n\t}\r\n\t\r\n\tpublic String CategorieName\r\n\t{\r\n\t\tget{return this._categorieName;}\r\n\t\tset{this._categorieName=value;}\r\n\t}\r\n}\r\n<\/pre>\n<p><strong>The Dao<\/strong><\/p>\n<pre>\r\nusing NHibernate;\r\nusing NHibernate.Cfg;\r\nusing System;\r\nusing System.Collections;\r\nusing System.Reflection;\r\n\r\npublic class CategorieDao{\r\n\tprivate ISessionFactory factory;\r\n\tprivate static CategorieDao _instance;\r\n\r\n\tprivate CategorieDao(){\r\n\t\tthis._Init();\r\n\t}\r\n\t\r\n\tpublic static CategorieDao Instance{\r\n\t\tget\r\n\t\t{\r\n\t\t\tif(_instance==null)\r\n\t\t\t{\r\n\t\t\t\t_instance = new CategorieDao();\r\n\t\t\t}\r\n\t\t\treturn _instance;\r\n\t\t}\r\n\t}\r\n\t\r\n\t\r\n\tprivate void _Init() {\r\n\t\tfactory = HibernateUtil.Instance.Factory;\r\n\t}\r\n\t\r\n\tpublic Categorie FindById(int id)\r\n\t{\r\n\t\tISession session = factory.OpenSession();\r\n\t\tITransaction transaction = session.BeginTransaction();\r\n\t\tIQuery query = session.CreateQuery(\"from Categorie where Categorie_Id = :id\");\r\n\t\tquery.SetParameter(\"id\",id);\r\n\t\tIList list = query.List();\r\n\t\tCategorie cat = (Categorie)list[0];\r\n\t\ttransaction.Commit();\r\n\t\tsession.Close();\r\n\t\treturn cat;\r\n\t}\r\n\t\r\n\t\r\n\tpublic IList LoadAll()\r\n\t{\r\n\t\tISession session = factory.OpenSession();\r\n\t\tITransaction transaction = session.BeginTransaction();\r\n\t\tIQuery query = session.CreateQuery(\"from Categorie order by categorie_name\");\r\n\t\tIList list = query.List();\r\n\t\tConsole.WriteLine(\"list size : \"+list.Count);\r\n\t\ttransaction.Commit();\r\n\t\tsession.Close();\r\n\t\treturn list;\r\n\t}\r\n}\r\n<\/pre>\n<p>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.<\/p>\n<p>I used 4 tables:<\/p>\n<ol>\n<li>Runners<\/li>\n<li>Categories<\/li>\n<li>Laps<\/li>\n<li>Results<\/li>\n<\/ol>\n<p>The first 2 are obvious, but the laps table is a table with 3 columns<\/p>\n<ol>\n<li>runner_id<\/li>\n<li>max_lap<\/li>\n<li>timestamp<\/li>\n<\/ol>\n<p>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<\/p>\n<p>Another thing that was pretty strange in my eyes was getting the selected value from a TreeView the code goes like this:<\/p>\n<pre>\r\nTreeModel model;\r\nTreeIter iter;\r\nif(this.CategorieLst.Selection.GetSelected(out model,out iter))\r\n{\r\n\tnewLoper.Categorie = (int)model.GetValue(iter,0);\r\n}\r\n<\/pre>\n<p>With my java background it&#8217;s not that obvious, even in my dotnet projects I haven&#8217;t seen a construct like this. However in the C language it looks normal \ud83d\ude42 Guess this is result from binding a C object to C# object. But it works, that&#8217;s what matters!<\/p>\n<p>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:<\/p>\n<pre>\r\nGlade.XML gxml = new Glade.XML (null, \"6urenloop.glade\", \"window1\", null);\r\ngxml.Autoconnect (this);\r\n<\/pre>\n<p>And giving my widgets the same name as in the glade file,adding the xml attribute <strong>[Glade.WidgetAttribute]<\/strong> is all that is needed. Easy isn&#8217;t it?<\/p>\n<p>Here you can find some screenhosts<br \/>\nThe screen for inserting new runners:<br \/>\n<a href=\"http:\/\/blog.pczone.be\/wp-content\/uploads\/2006\/02\/lopers_cut.png\"><img decoding=\"async\" src=\"http:\/\/blog.pczone.be\/wp-content\/uploads\/2006\/02\/lopers_cut_thmb.png\" border=\"0\"\/><\/a><\/p>\n<p>The screen for inserting laps and creating,exporting the results:<br \/>\n<a href=\"http:\/\/blog.pczone.be\/wp-content\/uploads\/2006\/02\/ronde_cut.png\"><img decoding=\"async\" src=\"http:\/\/blog.pczone.be\/wp-content\/uploads\/2006\/02\/ronde_cut_thmb.png\" border=\"0\"\/><\/a><\/p>\n<p>I&#8217;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&#8217;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&#8217;t quite as good as the java version.<\/p>\n<p>Ps yes I know, the interface is very ugly and not following the Gnome Guidelines, but it works like a sharm.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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&#8217;s called &hellip; <\/p>\n<p class=\"link-more\"><a href=\"http:\/\/blog.pczone.be\/?p=19\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Mono\/glade app did the job&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"enabled":false},"version":2}},"categories":[6,4,7],"tags":[],"class_list":["post-19","post","type-post","status-publish","format-standard","hentry","category-c","category-informatics","category-linux"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p3U9nk-j","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack-related-posts":[],"_links":{"self":[{"href":"http:\/\/blog.pczone.be\/index.php?rest_route=\/wp\/v2\/posts\/19","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/blog.pczone.be\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.pczone.be\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.pczone.be\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.pczone.be\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=19"}],"version-history":[{"count":0,"href":"http:\/\/blog.pczone.be\/index.php?rest_route=\/wp\/v2\/posts\/19\/revisions"}],"wp:attachment":[{"href":"http:\/\/blog.pczone.be\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=19"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.pczone.be\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=19"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.pczone.be\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=19"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}