• Embedded Databases

    I needed an embeddable database to handle some processing before

    inserting the data into the final database. I worked with three

    different embeddable databases, each had some pros and cons.

    SQL Server Everywhere/Mobile edition

    SQL Server Everywhere

    is a free embeddable database from Microsoft, formally SQL CE. It’s

    small, fast and offers almost full support for T-SQL. One thing that it

    doesn’t support is square brackets for escaping names. Also, no support

    for stored procedures, which wasn’t a concern for this project. The

    main problem was that it will throw an exception if it’s running under

    IIS. It’s obvious from the documentation that running under IIS is not a supported

    environment, but there are some cases where it could provide a good

    solution. I worked around this using app domains, which I’ll post about

    later. It can be used with SQL Server replication which could be a hugely useful feature.

    Being a MS product it has a fully supported .net provider and is supported on Mobile devices.

    Embeddable Firebird

    Firebird was

    easy to setup and get going, but it does have one very annoying quirk.

    It uppercases names by default and it doesn’t accept square brackets

    for escaping names, but does accept single quotes. Also, it is case

    sensitive so if you use them then you always have to use them unless

    your names are uppercase. For example select * from ‘mytable’ is not the

    same as select * from ‘MyTable’. And if you create a table with create

    table mytable it will create a table named MYTABLE and selects will

    need to select from MYTABLE not mytable. I don’t know if I explained

    this clearly, but it is a weird quirk. This may be changed in version 2

    which I don’t think has an embedded version yet, but could be a very good DB if this quirk was addressed.

    The download section has the embeddable version and a .net provider.


    Sqlite was also

    very easy to get working and worked well for smaller data sets. Using

    an index column or having a lot of data rows (10,000+) and things started

    to really slow down. It could have been that I didn’t have something

    setup correctly, but regardless it was performing really slowly. Setting up a auto

    incrementing primary key was a bit tricky, the syntax is below. I don’t

    see any advantage to this over SQL Server Everywhere, except that it’s

    open source, it may also support stored procedures, but I’m not sure.

    create table mytable (id integer primary key)…

    The System.Data.Sqlite

    project offers the Sqlite DB and a .net provider in one merged managed DLL, which makes

    for a very clean distribution. Also, provides Mobile development


    All in all, I liked SQL Server Everywhere the best, it has really good

    performance a small footprint and a familiar syntax if you’re used to

    SQL Server.</p>

  • Castle monorail logging with windsor

    Using Castle monorail with windsor, I setup the logging facility and followed the IoC of concept parameters for optional components. I noticed the base Controller had Logger property and assumed that windsor would handle it from there. However, my controller always had the NullLogger as the ILogger property. The base Controller class doesn’t have a setter for the Logger property. Still not sure why that is, also the property is not virtual. I should submit a patch for this. Anyway, one solution is to create a new property Logger in your own Controller with a getter and setter thus allowing windsor to set the Logger when the Controller is created.

    public abstract class BaseSiteController : ARSmartDispatcherController
    private ILogger _logger = new NullLogger();

    public new virtual ILogger Logger {
    get { return _logger; }
    set { _logger = value; }
  • SharpDevelop project templates

    I wanted to create castle project template for SharpDevelop, I ran into a few issues, some I found a way to fix, some I didn’t.

    One thing that I needed to do was add a project reference to a dll that was not in the GAC, to do this the HintPath attribute can be used on the Reference element.

        <Reference Include=“Castle.Core” HintPath=“c:\castlebin\Castle.Core.dll”/>

    Secondly, I wanted to set the debug options to allow cassini debugging. I found a way to set these options but I didn’t find a way to dynamically insert the project name/dll into the command line options. In the PropertyGroup element you can add the following to set these options. Note the ${ProjectName} string is not replaced with the project name.

            <StartProgram>c:\program files\cassini\CassiniWebServer2.exe</StartProgram>
            <StartArguments>C:\Documents and Settings\Dusty\My Documents\SharpDevelop Projects\${ProjectName} 8080 “/${ProjectName}”</StartArguments>

    So I guess there are still two main problems with this setup. First you have to know the path of any dll’s that are not installed in the GAC. And if you want to reference the project name in the debug options, it doesn’t look like there is a way to do that. But for setting up personal project templates these things may be useful.

  • Setting build numbers with Nant

        <h3> Setting build numbers with Nant </h3> I wanted something that would update the version number of my builds from within Nant. I found that using some of the built in functions of Nant I could get what I wanted without too much work. Nothing really exciting here, but a couple of notes. First the version numbers stored in the meta data limit the size to uint16.maxvalue - 1 so the value must be less then 65534. As such I could not use the format yyyyMMdd as I wanted to, so I ended up using days since 1/1/2000. Secondly, when loading the file with loadfile I needed to mark the encoding as UTF-8 so that the file would be writen back out in a usable form. Anyway, here's the nant code I ended up using.<br /><pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">property</span><span class="attr"> name</span><span class="kwrd">="build.major"</span><span class="attr"> value</span><span class="kwrd">="0"</span><span class="kwrd">/&gt;</span><span class="kwrd"><br />&lt;</span><span class="html">property</span><span class="attr"> name</span><span class="kwrd">="build.minor"</span><span class="attr"> value</span><span class="kwrd">="9"</span><span class="kwrd">/&gt;</span><span class="kwrd"><br />&lt;</span><span class="html">property</span><span class="attr"> name</span><span class="kwrd">="build.build"</span><span class="attr"> value</span><span class="kwrd">="${timespan::get-days(datetime::now() - datetime::parse('01/01/2000'))}"</span><span class="kwrd">/&gt;</span><br /><span class="kwrd">&lt;</span><span class="html">property</span><span class="attr"> name</span><span class="kwrd">="build.revision"</span><span class="attr"> value</span><span class="kwrd">="0"</span><span class="kwrd">/&gt;</span><br /><span class="kwrd">&lt;</span><span class="html">property</span><span class="attr"> name</span><span class="kwrd">="build.version"</span><span class="attr"> value</span><span class="kwrd">="${build.major}.${build.minor}.${build.build}.${build.revision}"</span><span class="kwrd">/&gt;</span><br /><span class="kwrd">&lt;</span><span class="html">foreach</span><span class="attr"> item</span><span class="kwrd">="File"</span><span class="attr"> property</span><span class="kwrd">="assemblyinfofile"</span><span class="kwrd">&gt;</span><br />  <span class="kwrd">&lt;</span><span class="html">in</span><span class="kwrd">&gt;<br /></span>    <span class="kwrd">&lt;</span><span class="html">items</span><span class="attr"> basedir</span><span class="kwrd">="${project.root}"</span><span class="kwrd">&gt;<br /></span>      <span class="kwrd">&lt;</span><span class="html">include</span><span class="attr"> name</span><span class="kwrd">="**\AssemblyInfo.cs"</span><span class="kwrd">/&gt;<br /></span>    <span class="kwrd">&lt;/</span><span class="html">items</span><span class="kwrd">&gt;</span><br />  <span class="kwrd">&lt;/</span><span class="html">in</span><span class="kwrd">&gt;</span><br />  <span class="kwrd">&lt;</span><span class="html">do</span><span class="kwrd">&gt;<br /></span>    <span class="kwrd">&lt;</span><span class="html">echo</span><span class="attr"> message</span><span class="kwrd">="${path::get-file-name(assemblyinfofile)}"</span><span class="kwrd">/&gt;<br /></span>    <span class="kwrd">&lt;</span><span class="html">loadfile </span><span class="attr">file</span><span class="kwrd">="${assemblyinfofile}"</span><span class="attr">property</span><span class="kwrd">="assemblyinfofile.content"</span><span class="attr">encoding</span><span class="kwrd">="utf-8"</span><span class="kwrd">/&gt;</span><br />    <span class="kwrd">&lt;</span><span class="html">regex</span><span class="attr"> pattern</span><span class="kwrd">="&amp;quot;(?'version'\d+\.\d+\.\d+\.\d+|\d+\.\d+\.\*)&amp;quot;" </span><span class="attr">input</span><span class="kwrd">="${assemblyinfofile.content}"</span><span class="kwrd">/&gt;</span><br />    <span class="kwrd">&lt;</span><span class="html">echo</span><span class="attr"> file</span><span class="kwrd">="${assemblyinfofile}"</span><span class="kwrd">&gt;</span>${string::replace(assemblyinfofile.content, version, build.version)}<span class="kwrd">&lt;/</span><span class="html">echo</span><span class="kwrd">&gt;</span><br />    <span class="kwrd">&lt;</span><span class="html">echo</span><span class="attr"> message</span>="<span class="attr">-</span><span class="kwrd">&gt;</span> Updated version from ${version} to ${build.version}"<span class="kwrd">/&gt;<br /></span>  <span class="kwrd">&lt;/</span><span class="html">do</span><span class="kwrd">&gt;</span><br /><span class="kwrd">&lt;/</span><span class="html">foreach</span><span class="kwrd">&gt;</span></pre><div style="clear: both; padding-bottom: 0.25em;"></div>
  • Monorail: Exception Handlers: Flash and Redirect

    e setting up exception chaining on monorail, I wanted to use the Flash properties to store the LastException for next request, an error page. This by default doesn't work if the exception happens outside of the Castle.MonoRail.Framework.MonoRailHttpHandler.Process method. This is because the Flash variables don't get saved until after this method. One note here, the Process method is wrapped in a try, finally block and the Flash properties will be saved in the case of an exception on the Process method, some additional checking in the exception handler may be needed to catch this. Anyway, I added the following line to my last handler and the Flash properties are working great.<br /><br /><span style="font-family: Courier New;">context.Session[Flash.FlashKey] = context.Flash;</span><br /><br /> Secondly, I wanted to redirect to different views based on the exception, which I wasn't able to do. The reason was that the asp.net framework noticed the exception an handled according, not what I wanted. The way around this is to clear the error using the Server.ClearError() method before redirecting.<br /><br /><span style="font-family: Courier New;">context.UnderlyingContext.Server.ClearError();</span><br /><div style="clear: both; padding-bottom: 0.25em;"></div>
  • Using nant and tallow to create usable WIX component.

        <p>Creating installer for web application can be a pain, but using tallow and an nant script element can make things a lot easier.</p>
        <p>Once my nant script was building my solution and web project with all the needed output files I begin to setup automating the build of the WIX component for the web application.</p>
        <p>As you know tallow output is not usable as is, some custom handling needs to be done. I've found the script element of nant to work well for this. I've also created a new class library project to keep the script block small, and keep the source in a project. I've included the class library in the solution build. </p>
        <p>Nant target:</p>
        <!-- code formatted by http://manoli.net/csharpformat/ -->
        <pre class="csharpcode">&lt;property name="wix.websitefragment.file" value="${build.output.temp}\website-fragment.wsx"/&gt;<br />&lt;target name="buildwebsitewsx" depends="solution"&gt;<br />    &lt;mkdir dir="${build.output.temp}"/&gt;<br />    &lt;exec program="${wix.bin}\tallow.exe" workingdir="${build.output.temp}" output="${wix.websitefragment.file}"&gt;<br />        &lt;arg value="-d &amp;quot;${compile.output.webapplication}&amp;quot;"/&gt;<br />        &lt;arg value="-nologo"/&gt;<br />    &lt;/exec&gt;<br />    &lt;script language="C#" verbose="true"&gt;<br />        &lt;references&gt;<br />            &lt;include name="${compile.output}\InstallHelper.dll"/&gt;<br />        &lt;/references&gt;<br />        &lt;imports&gt;<br />            &lt;import namespace="InstallHelper"/&gt;<br />        &lt;/imports&gt;<br />        &lt;code&gt;<br />        &lt;![CDATA[<br />        public static void ScriptMain(Project project) {<br />            string file = project.Properties["wix.websitefragment.file"];<br />            new FixTallow(file, "My.ComponentGroup.Name").UpdateFile();<br />        }<br />        ]]&gt;<br />        &lt;/code&gt;<br />    &lt;/script&gt;<br />&lt;/target&gt;<span class="kwrd"></span></pre>
        This calls the tallow application on the directory where the web application is built. Then loads and calls the InstallHelper.dll to modify the tallow output into something more usable. <br /><p>The FixTallow class loads the tallow output into an XML document and takes the following actions; adds a component group, creates guids for the components, renames the directory id's and changes the directoryRef element to point to the INSTALLDIR.</p><p>The component group needs to be created so a reference can be added to the main WIX file. This is because tallow creates a component for each directory (or each file) and because I don't want to update the main WIX file every time there is a directory added or removed from the web application. The group name is passed the the constructor of the FixTallow class. </p><p>FixTallow also renames the directory id's so that I can reference them if needed from the main WIX file, however if the directory is removed or renamed, the main WIX file will need to be updated. Also, the root DirectoryRef element is changed to reference INSTALLDIR which needs to be set in the main WIX file. This is a good idea as it allows the installation directory to be changed when installing.</p><p>FixTallow.cs</p><pre class="csharpcode"><span class="kwrd">    public</span><span class="kwrd">class</span> FixTallow<br />    {<br /><span class="kwrd">  private</span><span class="kwrd">readonly</span><span class="kwrd">string</span> _filename;<br /><span class="kwrd">    private</span><span class="kwrd">readonly</span><span class="kwrd">string</span> _componentGroupName;<br />        XmlDocument _document = <span class="kwrd">new</span> XmlDocument();<br />        XmlNamespaceManager _manager;<br />        XmlElement _compGroup;<br /><br /><span class="kwrd">   public</span> FixTallow(<span class="kwrd">string</span> filename, <span class="kwrd">string</span> componentGroupName)<br />        {<br />            _filename = filename;<br />            _componentGroupName = componentGroupName;<br /><br />            _manager = <span class="kwrd">new</span> XmlNamespaceManager(_document.NameTable);<br />            _manager.AddNamespace(<span class="kwrd">string</span>.Empty, <span class="str">"http://schemas.microsoft.com/wix/2003/01/wi"</span>);<br />            _manager.AddNamespace(<span class="str">"ns"</span>, <span class="str">"http://schemas.microsoft.com/wix/2003/01/wi"</span>);<br />        }<br /><br /><span class="kwrd"> public</span> FixTallow UpdateFile()<br />        {<br />            _document.Load(_filename);<br /><br />            AppendComponentGroupElement();<br /><br /><span class="kwrd">        foreach</span> (XmlElement element <span class="kwrd">in</span> _document.SelectNodes(<span class="str">"//ns:Component"</span>, _manager))<br />            {<br />                element.Attributes[<span class="str">"Guid"</span>].Value = Guid.NewGuid().ToString().ToUpper();<br />                AppendComponentToGroup(element.Attributes[<span class="str">"Id"</span>].Value);<br />            }<br /><br />            ChangeDirectoryRefId();<br /><br />            UpdateDirectoryIds();<br /><br />            _document.Save(_filename);<br /><br /><span class="kwrd">      return</span><span class="kwrd">this</span>;<br />        }<br /><br /><span class="kwrd">        private</span><span class="kwrd">void</span> UpdateDirectoryIds()<br />        {<br /><span class="kwrd">            foreach</span> (XmlElement directory <span class="kwrd">in</span> _document.SelectNodes(<span class="str">"//ns:Directory"</span>, _manager))<br />            {<br /><span class="kwrd">                string</span> directoryName = (directory.Attributes[<span class="str">"LongName"</span>] == <span class="kwrd">null</span>)<br />                                           ?<br />                                       directory.Attributes[<span class="str">"Name"</span>].Value<br />                                           :<br />                                       directory.Attributes[<span class="str">"LongName"</span>].Value;<br />                directory.Attributes[<span class="str">"Id"</span>].Value = directoryName + <span class="str">".Dir"</span>;<br />            }<br />        }<br /><br /><span class="kwrd">        private</span><span class="kwrd">void</span> ChangeDirectoryRefId()<br />        {<br />            _document.SelectSingleNode(<span class="str">"/ns:Wix/ns:Fragment/ns:DirectoryRef/@Id"</span>, _manager).Value = <span class="str">"INSTALLDIR"</span>;<br />        }<br /><br /><span class="kwrd">        private</span><span class="kwrd">void</span> AppendComponentToGroup(<span class="kwrd">string</span> componentId)<br />        {<br />            XmlElement componentRef = _document.CreateElement(<span class="str">"ComponentRef"</span>, _manager.DefaultNamespace);<br />            XmlAttribute componentRefId = _document.CreateAttribute(<span class="str">"Id"</span>);<br />            componentRefId.Value = componentId;<br />            componentRef.Attributes.Append(componentRefId);<br />            _compGroup.AppendChild(componentRef);<br />        }<br /><br /><span class="kwrd">        private</span><span class="kwrd">void</span> AppendComponentGroupElement()<br />        {<br />            _compGroup = _document.CreateElement(<span class="str">"ComponentGroup"</span>, _manager.DefaultNamespace);<br />            XmlAttribute compGroupId = _document.CreateAttribute(<span class="str">"Id"</span>);<br />            compGroupId.Value = _componentGroupName;<br />            _compGroup.Attributes.Append(compGroupId);<br />            _document.SelectSingleNode(<span class="str">"/ns:Wix/ns:Fragment"</span>, _manager).AppendChild(_compGroup);<br />        }<br />    }</pre><p>The main WIX file needs to include a few things for this to work. First, it much have a diretory element with INSTALLDIR as it's Id. Second, a ComponentGroupRef element pointing the component group name specified in the FixTallow constructor needs to be included in the Feature element.</p><pre class="csharpcode">...<br /><span class="kwrd">&lt;</span><span class="html">Directory</span><span class="attr">Id</span><span class="kwrd">="TARGETDIR"</span><span class="attr">Name</span><span class="kwrd">="SourceDir"</span><span class="kwrd">&gt;</span><br /><span class="kwrd">&lt;</span><span class="html">Directory</span><span class="attr">Id</span><span class="kwrd">="ProgramFilesFolder"</span><span class="kwrd">&gt;</span><br /><span class="kwrd">&lt;</span><span class="html">Directory</span><span class="attr">Id</span><span class="kwrd">="INSTALLDIR"</span><span class="attr">Name</span><span class="kwrd">="myapp"</span><span class="attr">LongName</span><span class="kwrd">="MyApplicationName"</span><span class="kwrd">&gt;</span><br /><span class="kwrd">&lt;/</span><span class="html">Directory</span><span class="kwrd">&gt;</span><br /><span class="kwrd">&lt;/</span><span class="html">Directory</span><span class="kwrd">&gt;</span><br /><span class="kwrd">&lt;/</span><span class="html">Directory</span><span class="kwrd">&gt;</span><br />...<br /><span class="kwrd">&lt;</span><span class="html">Feature</span><span class="attr">Id</span><span class="kwrd">="Complete"</span><span class="attr">Level</span><span class="kwrd">="1"</span><span class="kwrd">&gt;</span><br /><span class="kwrd">&lt;</span><span class="html">ComponentGroupRef</span><span class="attr">Id</span><span class="kwrd">="My.ComponentGroup.Name"</span><span class="kwrd">/&gt;</span><br /><span class="kwrd">&lt;/</span><span class="html">Feature</span><span class="kwrd">&gt;</span><br />...</pre>Lastly, the tallow output needs to be passed to the candle and light applications when building the msi file with something like this:<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">exec</span><br /><span class="attr">program</span><span class="kwrd">="${wix.bin}\candle.exe"</span><br /><span class="attr">workingdir</span><span class="kwrd">="${build.output.install}"</span><br /><span class="attr">commandline</span><span class="kwrd">="Main.wsx website-fragment.wsx"</span><span class="kwrd">/&gt;</span><br />...<br /><span class="kwrd">&lt;</span><span class="html">exec</span><br /><span class="attr">program</span><span class="kwrd">="${wix.bin}\light.exe"</span><br /><span class="attr">workingdir</span><span class="kwrd">="${build.output.install}"</span><br /><span class="attr">commandline</span><span class="kwrd">="-out MyApplication.msi Main.wixobj website-fragment.wixobj"</span><span class="kwrd">/&gt;</span></pre><span class="kwrd">There was a lot of setup here, but once completed changes can be made to the web application without modifying the WIX files, resulting in an up to date MSI on each build.</span><br /><div style="clear: both; padding-bottom: 0.25em;"></div>
  • Adding wix support for VS.NET

     the .xsd files in the wix\doc directory to C:\Program Files\Microsoft Visual Studio 8\Xml\Schemas directory.<div style="clear: both; padding-bottom: 0.25em;"></div>