Devlico.Us
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @devlicious

Sergio Pereira

There are no half-solutions because there isn't half a problem

April 2008 - Posts

  • Designing With Lambdas - Part III

    In the previous two installments of the series we discussed how we can use lambdas to encapsulate more processing logic and to create contextual APIs. In this post I will show another example of the latter.

    Navigating directory structures

    This time around we will try to create a safe way to browse and create directories without losing track of the current location. When we write code to read files or directory information from a directory structure, and we need to look into more than one directory, we have to be careful to always be sure of what the current working directory is or use only absolute paths. Neither approach is without its inconveniences.

    What I'll try to show here is a way to enforce the working directory as a lambda context. That can be a mouthful so let me try to put it in simpler terms. I'd like to have a way to assert that when a particular code runs, the working directory will be changed to a specified location, and after that code finishes the working directory is restored automatically.

    Without lambdas, the context setting could resemble the following:

    string previousDir = Environment.CurrentDirectory;
    try
    {
    	Environment.CurrentDirectory = @"c:\myapp";
    	DoStuff();
    
    	try
    	{
    		Environment.CurrentDirectory = 
    				@"c:\myapp\subdirs\resources\images\toolbar";
    		DoOtherStuff();
    	}
    	finally
    	{
    		Environment.CurrentDirectory = @"c:\myapp";
    	}
    
    	DoMoreStuff();
    }
    finally
    {
    	Environment.CurrentDirectory = previousDir;
    }

    All those try and finally are there to make sure we restore the appropriate working directory after we are done with each one. I don't know about you, but having a lot of those in my code would add a lot of noise, obscuring the real intent of the code.

    What if we could, once again, encapsulate this pattern in a function that accepts a delegate? Here's what a way more revealing code would look like.

    Dir.Change(@"c:\myapp", path =>
    {
    	//we're in c:\myapp
    	Dir.Change(subdir =>
    	{
    		//we're in c:\myapp\subdir
    		string dirName = DateTime.Now.ToString("yyyy-MM-dd");
    		//we can ask it to create the directory if 
    		//  not found (the "true" parameter)
    		Dir.Change(dirName, true, dailyLogDir =>
    		{
    			//we're in c:\myapp\subdir\2008-04-29 (for example)
    			using(StreamWriter wr = File.CreateText("logfile.txt"))
    			{
    				wr.WriteLine("Hello file.");
    			}
    		});
    
    		//we're back in c:\myapp\subdir
    
    		//we can pass in a deeper path
    		Dir.Change(@"resources\images\toolbar", imagesDir =>
    		{
    			//we're in c:\myapp\subdir\resources\images\toolbar
    			//listing all files here
    			foreach(string file in imagesDir.GetFiles("*.png"))
    				Console.WriteLine("Toolbar icon: " + file);
    
    		});
    	});
    });

    Within each Dir.Change block we can be certain that the current working directory will be the one we specified (unless your own code intentionally changes it.) When the code block finishes, we will be back to whatever directory we were before the block, guaranteed.

    Note in line 4 that the name of the directory can be gathered from the parameter's name subdir. This is not always possible because we could be dealing with multi-level directory changes (line 22) or dynamically generated directory names (line 10). Additionally, the rules for naming directories are not the same as for naming C# identifiers. For these reasons, it's also possible to pass a string containing the name of the desired directory.

    Here's the code that makes this possible.

    public static class Dir
    {
    	public static void Change(Action<DirectoryInfo> execute)
    	{
    		Change(false, execute);
    	}
    
    	public static void Change(string path, Action<DirectoryInfo> execute)
    	{
    		Change(path, false, execute);
    	}
    
    	public static void Change(bool createIfNeeded, Action<DirectoryInfo> execute)
    	{
    		string path = execute.Method.GetParameters()[0].Name;
    		Change(path, createIfNeeded, execute);
    	}
    
    	public static void Change(string path, bool createIfNeeded, 
    							Action<DirectoryInfo> execute)
    	{
    		string previousDir = Environment.CurrentDirectory;
    
    		try
    		{
    			if(createIfNeeded && !Directory.Exists(path))
    				Directory.CreateDirectory(path);
    
    			var di = new DirectoryInfo(path);
    			Environment.CurrentDirectory = path;
    			execute(di);
    		}
    		finally
    		{
    			Environment.CurrentDirectory = previousDir;
    		}
    	}
    
    	public static bool TryChange(string path, Action<DirectoryInfo> execute)
    	{
    		if(Directory.Exists(path))
    		{
    			Change(path, false, execute);
    			return true;
    		}
    		else
    		{
    			return false;
    		}
    	}
    }

    So there you have it. Another example of incorporating lambdas to design APIs that attempt to reduce code noise and eventually read more naturally. Hopefully you're starting to see a pattern here in terms of what a context can be and how lambda-aware APIs can help formalizing that context.

  • Wrong .Net Version being loaded

    At work one application has this intermittend problem that started when the developer started to use telerik's r.a.d. web controls. Once in a while, for some (until today) unexplained reasons, the telerik controls would start throwing this error:

    This control is complied for ASP.NET 1.x. 
    Please use the ASP.NET 2.0 native version: RadTabStrip.Net2.dll 
    

    For reasons that are not relevant for this post, the application runs under ASP.NET 1.1, not 2.0. What the error message reveals is that sometimes .Net v2.0 was being loaded first in that appDomain. Resetting the app and hitting /default.aspx would be enough to make that error go away. Until it happened again a few days after that.

    The application developers and the webmaster spent quite a bit of time checking IIS settings, .Net settings, other apps in the same appPool. Everything seemed correct.

    Today I joined the effort to get rid of that problem and as soon as I saw some .asp files mixed with the .aspx ones it struck me. "We don't happen to have VB6 code doing interop with .Net code, do you?". That's right, we did. There are valid reasons for this but again it doesn't matter here.

    I immediately brought up Scott Hanselman's two posts where he describes a similar situation. Different symptom, but similar enough to help us.

    Basically, if the very first page to be hit in the application is an .asp file that does interop with .Net, it will load the .Net runtime and the default behavior is to load the newest version possible, which is version 2.0 in our case. Once loaded, that version stays throughout the lifespan of the appDomain, leaving Telerik's code flipping.

    There are a few possible solutions, which are discussed in Scott's posts and comments. In our case it boiled down to the following alternatives:

    1. Update the application to .Net 2.0 or 3.5, migrate the telerik assemblies, and get rid of the ASP/VB6 code: This is the ideal scenario. It is possible, but a little bit too time consuming in our case because of the amount of VB6 stuff there (old app, important app.) But if we could afford the time, that would be the best route to go.

    2. Update the application to .Net 2.0 or 3.5 and migrate the telerik assemblies: The next best thing considering the VB6 problem mentioned above.

    3. Just get rid of the ASP/VB6 code: This could work too. But it seems like too much work to keep supporting .Net 1.x.

    4. Try the ISAPI filter suggested by Scott here: Looks like a quick and effective solution. I would be willing to try it out. Unfortunately we have no C++ expertise in the house and the developer felt a little uncomfortable deploying this solution and creating one more dirty little secret in this already convoluted application.

    5. Bootstrap the classic ASP engine to start ASP.NET the right way: The idea here is to add a global.asa file to the application and use the Application_Start event to call a dummy ASP.NET url. The trick is to invoke some /dummy.aspx file via HTTP, like shown in this article.

    They are leaning toward #5 (path of least resistance, I know) but the mid-term solution will be #2 followed by #1 (schedules and budget permitting.)

    Anyway, I just wanted to share this in case someone is also tasked with maintaining their own version of the worst application in the world. Thanks Hanselman for making me look good once again.

    Update: We chose to go with #5 until we can afford to do #1. The solution was to add the following to the global.asa file (remember those?). The file bootstrap.aspx can be an empty file. It's there only to, erm..., bootstrap ASP.NET.
    <script language="vbscript" runat="server">
    Sub Application_OnStart
    	Dim url, inet, s, xmlhttp 
    	'the url must be absolute (i.e. start with http://)
    	url = "http://127.0.0.1/myapplication/bootstrap.aspx"
    
    	Set xmlhttp = CreateObject("MSXML2.ServerXMLHTTP") 
    	xmlhttp.open "GET", url, false 
    	xmlhttp.send "" 
    	Set xmlhttp = Nothing 
    
    End Sub
    </script>
  • ALT.NET Conference Recap

    ALT.NET Conference, take two. When I signed for this conference for the second time I didn't honestly think it was going to be as good as the first one. Boy was I wrong. I got the feeling that the attendees came incredibly prepared. Prepared to stand up and voice their opinions instead of simply watching. Prepared to listen diverging point of views. Prepared to take part in spontaneous conversations, in the conference rooms, in the corridors, in the shared rides, in the hotel lobby, in the restaurants, in the frigging airport waiting to board the plane. And, most of all, prepared to be surprised. I was surprised at so many different levels. Who would have thought that a discussion around JavaScript would spark so much interest? I was certain that the participants that came straight out of the MVP Summit would be all geeked out, but no. I was surprised to see a few MVPs that chose to fly in only for the ALT.NET event and not the summit. I was also surprised to see that some of the greatest talks happened not during the conference hours, but late in the night after a few drinks. Maybe if I start drinking I will become one of the smart guys? From the sessions that I stopped by, several discussions and questions came back with me for further processing.
    • Microsoft v 1.0 vs Stable OSS
      • Is that decision based only on risk assessment?
      • MS is clearly happy with OSS built with .Net. Brad Abrams and ScottGu were there to assure that.
      • Are we lacking a corporation (not-MS) to back OSS, like Canonical, Red Hat, mySQL AB, etc?
      • Too many questions, no clear conclusion


    • Functional Programming: Great talk. As you may or may not know, I am interested in this type of stuff. Just to reiterate, I think FP has its place and we are just seeing the beginning of it in the .Net universe.

    • ASP.NET MVC update: Among all the surprises in the conference, this was the most intriguing one. I went in as a MVC believer and got out happier with webforms. Weird. Some of the upcoming changes in webforms will address important annoyances, like the id munging and routing for urls.

    • Innovation: I arrived late at this discussion and was kind of shocked to hear Scott Hanselman question (or even suggest) that we already have enough implementation of OSS alternatives for many things and maybe there's nothing left to be innovated there, maybe we should just move on instead of creating another mock framework or another blog engine. I think this is kind of absurd. A great part of the innovation is powered by lower level innovations. My example: we didn't seem to need Moq, but now that we have lambdas in .Net, Moq could innovate in that area. As long as the CLR and the language teams keep feeding us new tools, we will keep using the tools in new and creative ways. Anyway, the central point of the discussion was supposed to be if there's innovation in .Net or if we are only porting existing projects from other languages.

    • JavaScript tools and patterns
      • JSUnit - this is slow. too slow.
      • Do we need a JS-specific test runner?
      • We felt that we lack some guidance and some patterns
      • Watch for a new community around these premises


  • Redmond, the center of the ALT.NET universe

    ...at least for the next three days

    Tomorrow I'm hopping on a plane to Seattle/Redmond, WA to take part in the second ALT.NET Open Spaces Conference. I had the chance to be at the first one last October in Austin, TX and what a great experience that was.

    My main motivation to attend the event in Austin was to learn from the more experienced folks how they adopted these practices and culture in their organizations. I wanted to participate in discussion about creating interest in self-improvement in my organization, my local .Net community, and eventually in the global .Net ecosystem.

    The sessions I took part in included mostly these topics, like how can we help MSDN and MSDN Magazine become a great vehicle for spreading into the .Net community, among other things, practices that go beyond what Visual Studio shows in its Add » New Item, and the lessons that we can learn from the non-.Net space. The March 2008 issue of the magazine was a glimpse at what types of techniques and tools we could be seeing applied by more .Net developers, helping create more maintainable applications and more scalable development and support processes.

    This time around I'm hoping to be in discussions that are more specific of Agile processes. I want to understand how to get started and how demonstrable Agile value really is. I'm tired of reading from people that quickly attached themselves to the Agile label just because it looks like the thing to do at the moment. I, for one have never experienced Agile in any organization I worked at. This event will give us a great opportunity to hear and question some of the people that are really employing Agile and experiencing some form of benefit from it. I want to make sure Agile isn't just another bandwagon.

    There's always the risk that events like this become the proverbial echo chamber, where folks that think alike tap each other's back, celebrate their common thinking, and waste time discussion irrelevant technicalities. I'm happy to see a lot of blue badges and even people that I'm sure will be there to challenge ALT.NET to put up or shut up. One such individual is JDN — if you read the altdotnet mailing list you're familiar with his point of view. I think that is a good thing.

    So, if you happen to be there too and see me, come and talk. That's why we are there for, right. And I'm not one of these guys that can only talk about software. I could spend hours chatting about other things like soccer and .... and ... darn it! Nevermind :)

  • And my point is

    It's nice when you're trying to say something and find out that it has already been said by someone way more qualified than you.

    In the end it's good to know it happens because we like this software development thing. It's all in good spirit.

  • Designing With Lambdas - Part II

    In my last post I went through a very simple example of applying lambdas to achieve more DRY.

    In this installment I'll cheat a little and rehash a previous article I wrote before this blog existed. The article fits rather nicely in this series.

    Creating XML with .Net

    In .Net two of the most popular ways of creating XML are the System.Xml.XmlDocument, which implements the XML DOM, and System.Xml.XmlTextWriter. There's a new interesting way in VB9 using Xml Literals, but it is hardly popular at the time of this writing.

    These APIs are obviously old-timers in .Net and were created before lambdas were available. For the sake of comparison, let's see how we would write the following XML document using these two APIs.

    <?xml version="1.0" encoding="utf-8"?>
    <children>
        <!--Children below...-->
        <child age="1" referenceNumber="ref-1">child &amp; content #1</child>
    
        <child age="2" referenceNumber="ref-2">child &amp; content #2</child>
        <child age="3" referenceNumber="ref-3">child &amp; content #3</child>
        <child age="4" referenceNumber="ref-4">child &amp; content #4</child>
    
        <child age="5" referenceNumber="ref-5">child &amp; content #5</child>
        <child age="6" referenceNumber="ref-6">child &amp; content #6</child>
        <child age="7" referenceNumber="ref-7">child &amp; content #7</child>
    
        <child age="8" referenceNumber="ref-8">child &amp; content #8</child>
        <child age="9" referenceNumber="ref-9">child &amp; content #9</child>
    </children>

    With the good ol' DOM, this document could be produced using something like this.

    XmlDocument xml = new XmlDocument();
    XmlElement root = xml.CreateElement("children");
    xml.AppendChild(root);
    
    XmlComment comment = xml.CreateComment("Children below...");
    root.AppendChild(comment);
    
    for(int i = 1; i < 10; i++)
    {
    	XmlElement child = xml.CreateElement("child");
    	child.SetAttribute("age", i.ToString());
    	child.SetAttribute("referenceNumber", "ref-" + i);
    	child.InnerText = "child & content #" + i;
    	root.AppendChild(child);
    }
    
    string s = xml.OuterXml;

    Nothing too dramatic here. But my argument is that the only thing the DOM API has going for it is its ubiquitousness, which is not a minor feat considering how clunky the API is. Look at all those set this and append that. Can you still remember when you were first learning the DOM and never remembering how attributes were set?

    Now it's the XmlTextWriter's turn. Here's the code to write the same XML document.

    StringWriter sw = new StringWriter();
    XmlTextWriter wr = new XmlTextWriter(sw);
    
    wr.WriteStartDocument();
    wr.WriteComment("Children below...");
    wr.WriteStartElement("children");
    
    for(int i=1; i<10; i++)
    {
    	wr.WriteStartElement("child");
    	wr.WriteAttributeString("age", i.ToString());
    	wr.WriteAttributeString("referenceNumber", "ref-" + i);
    	wr.WriteString("child & content #" + i);
    	wr.WriteEndElement();
    }
    
    wr.WriteEndElement();
    wr.WriteEndDocument();
    
    
    wr.Flush();
    wr.Close();
    string s = sw.ToString();

    The XmlTextWriter API is rather efficient but, golly, is it a b!tch to use. No kidding, folks. Miss one of those WriteEndXXXXXX and you're toast. Good luck in your debugging session.

    But enough of bashing our favorite APIs. The point here is just to show a draft of what an API like this could be designed in the era of lambdas.

    XmlBuilder - let the lambdas in

    What if we could somehow wrap the XmlTextWriter in a way that we could never forget to close an element? Remember how we wrapped the code in FileUtil.EachLine in the first installment of this series? We wrote that method in such a way that the file will never be left open by accident. I think we could do the same with the XmlTextWriter API.

    Take a moment to inspect the following code. Put yourself in the shoes of a developer that is trying to write XML for the first time and needs to choose an XML API.

    string s = XmlBuilder.Build(xml =>
    {
    	xml.Root(children =>
    	{
    		children.Comment("Children below...");
    
    		for(int i = 1; i < 10; i++)
    		{
    			children.Element(child =>
    			{
    				child["age"] = i.ToString();
    				child["referenceNumber"] = "ref-" + i;
    				child.AppendText("child & content #" + i);
    			});
    		}
    	});
    });

    Did you notice how the code structure maps nicely to the XML document structure? See how there's no way for you to forget one of those AppendChild calls from the DOM or WriteEndElement from the XmlTextWriter?

    I particularly like the way the attributes are defined using the indexer syntax. Do you see how I chose to format the lambdas so that they look like C# control blocks? Placing the opening brace of the lambda in the next line created this indented block of code that defines some form of context. The context in this case is "inside this block I'll be building one XML element. When the block ends, the element ends."

    You can download the code and play with it. It's only a proof of concept and there's a lot of missing functionality that I hope to implement one day, probably when I decide to use it in some real project.

    Explanation of the code

    Below you can see an excerpt from the code, showing how the Element() method was implemented. Let's discuss it.

    public virtual void Element(Action<XmlElementBuilder> build)
    {
    	string name = build.Method.GetParameters()[0].Name;
    	Element(name, new Dictionary<string, string>(), build);
    }
    
    public virtual void Element(string localName, 
    			Action<XmlElementBuilder> build)
    {
    	Element(localName, new Dictionary<string, string>(), build);
    }
    
    public virtual void Element(string localName, 
    			IDictionary<string, string> attributes, 
    			Action<XmlElementBuilder> build)
    {
    	XmlElementBuilder child = new XmlElementBuilder(localName, Writer);
    	
    	Writer.WriteStartElement(localName);
    	child._tagStarted = true;
    
    	foreach(var att in attributes)
    		child[att.Key] = att.Value;
    
    	build(child);// <-- element content is generated here
    	Writer.WriteEndElement();
    	_contentAdded = true;
    }

    Looking at the various overload of this method we can see how the lambda comes into play and also at least one more trick. The very first method reflects into the given delegate (the lambda) to determine the name that was used for the single parameter of Action<XmlElementBuilder>. That's how we did not need to specify the children and child node names. Of course this is not always desirable or possible because the naming rules or XML elements is different than C# identifiers, so the other overloads let us specify the node name.

    In the last overload of Element() is where the real code is. Line #19 Writer.WriteStartElement(localName); opens the element, line #25 build(child); invokes the lambda passing a builder instance for what goes inside the element. Line #26 Writer.WriteEndElement(); makes sure we keep synch with the element we started in line #19, by ending it before the method exits.

    For easier reference I'm including the code for XmlElementBuilder and its base class.

    public class XmlElementBuilder : XmlBuilderBase
    {
    	internal XmlElementBuilder(string localName, XmlTextWriter writer)
    		: base(writer)
    	{
    		Name = localName;
    	}
    
    	public string Name { get; protected set; }
    
    	public void AppendText(string text)
    	{
    		Writer.WriteString(text);
    	}
    }
    public abstract class XmlBuilderBase
    {
    	protected XmlBuilderBase(XmlTextWriter writer)
    	{
    		Writer = writer;
    	}
    
    	internal XmlTextWriter Writer { get; set; }
    	private bool _contentAdded = false;
    	private bool _tagStarted = false;
    
    	public virtual void Comment(string comment)
    	{
    		Writer.WriteComment(comment);
    		_contentAdded = true;
    	}
    
    	public virtual void Element(Action<XmlElementBuilder> build)
    	{
    		string name = build.Method.GetParameters()[0].Name;
    		Element(name, new Dictionary<string, string>(), build);
    	}
    
    	public virtual void Element(string localName, Action<XmlElementBuilder> build)
    	{
    		Element(localName, new Dictionary<string, string>(), build);
    	}
    
    	public virtual void Element(string localName, IDictionary<string, string> attributes, Action<XmlElementBuilder> build)
    	{
    		XmlElementBuilder child = new XmlElementBuilder(localName, Writer);
    		
    		Writer.WriteStartElement(localName);
    		child._tagStarted = true;
    
    		foreach(var att in attributes)
    			child[att.Key] = att.Value;
    
    		build(child);// <-- element content is generated here
    		Writer.WriteEndElement();
    		_contentAdded = true;
    	}
    
    	Dictionary<string, string> _attributes = new Dictionary<string, string>();
    	
    	public string this[string attributeName] 
    	{
    		get
    		{
    			if(_attributes.ContainsKey(attributeName))
    				return _attributes[attributeName];
    			return null;
    		}
    		set
    		{
    			if(_contentAdded)
    				throw new InvalidOperationException(
    					"Cannot add attributes after" + 
    					" content has been added to the element.");
    
    			_attributes[attributeName] = value;
    
    			if(_tagStarted)
    				Writer.WriteAttributeString(attributeName, value);
    		}
    	}
    }

    I realize the code I'm providing here is not a complete solution for all XML creation needs, but that's also not the point of this series. The idea here is to explore ways to incorporate lambdas in the API. When you think about it, this design has been possible all along via delegates since .Net 1.0. Anonymous delegates made this a much, much better. But only with the expressive lambda syntax we are seeing an explosion of this type of delegate usage.

  • Designing With Lambdas - Part I

    When our programming language of choice gets a new feature, it's usually not that hard to start using that feature right away from a consumer's point of view.

    I could use the introduction of generics in .Net 2.0 as an example. When I wrote my first C# 2.0 piece of code, it already made use of the existing generic classes and methods, especially the ones in the System.Collections.Generic namespace such as List<T> and Dictionary<TKey,TValue>.

    But it took a little more time until I learned how to design my own classes offering generic functionality. Reaching the balance of when to create generic classes, when to create generic methods, or when not to use generics only comes with some exercise.

    I think this will be the case with lambdas for many people, including myself. Detecting opportunities to apply lambdas can make all the difference between a class that is a joy to use and one that is just the same old thing.

    Processing lines in a file

    My first example will be a more concise and less error-prone way of processing lines in a text file. Consider this hopefully familiar piece of code.

    using(StreamReader rd = File.OpenText("Data.txt"))
    {
    	string line = rd.ReadLine();
    	while(line != null)
    	{
    		DoSomething(line);
    		// do more stuff with the line text
    
    		//move on
    		line = rd.ReadLine();
    	}
    }

    How many times have you written something like this over and over? I know I did. If I were to compare the various times I implemented this, I would probably notice that the only thing that is different is the logic inside the while block. This should be a clue that a delegate or lambda could help make this pattern reusable.

    But how do we create a reusable method that performs this common task without providing the logic inside the while? The last paragraph gave away the answer: delegates.

    Let's create a helper class with a method to encapsulate the pattern at hand.

    public static class FileUtil
    {
    	public static void EachLine(string fileName, Action<string> process)
    	{
    		using(StreamReader rd = File.OpenText(fileName))
    		{
    			string line = rd.ReadLine();
    			while(line != null)
    			{
    				process(line);
    				line = rd.ReadLine();
    			}
    		}
    	}
    }

    The body of the EachLine method is almost the same as the original implementation we started with. The difference, as expected, is that we replaced the DoSomething(line) with a call to process, which is a delegate of type Action<string>, meaning that it expects a function that accepts a single parameter of type string and does not have a return value.

    Using our new method, we can rewrite the original example like this.

    FileUtil.EachLine("Data.txt", line => DoSomething(line));

    Not bad. In this particular case, because we are just forwarding the line parameter to DoSomething, the call can be further simplified taking advantage of C#'s new shortened delegate creation syntax.

    FileUtil.EachLine("Data.txt", DoSomething );

    There you have it. Hopefully this assists someone in their journey in this new lambda thing.

  • Trying to get rid of MS Access

    I have this small personal organizer application that helps me keeping track of where my hard earned money is going. There's nothing special about this application other that it was designed to be used only by myself and it works exactly the way I think it should.

    This application has been a trusty companion for the last 10 years and it needs its well deserved retirement. This is the last piece of VB6 that I have installed on my system. Since I stopped installing Visual Studio 6 years ago, this means I have been dealing with a couple of known bugs. I also have not added any new feature in a long time (maybe since the year 2000).

    This year I decided to finally rewrite this app in .Net and I have an interesting choice to make. The old app uses MS Access for its database and, while I know I could very well keep using Access, I just don't want to deal with Access anymore. It's a technology from the last century and I think there must be something better out there.

    A few things I need the database to support:

    • I need to be able to carry the app in a thumb drive and run in any system that only has .Net installed
    • Must be in-process (no service, sorry SQL Express, mySQL)
    • Must be as much compatible with SQL-92 as possible
    • Even better if it's supported by the popular ORM tools

    After a brief research I chose a few candidates that seemed convenient: SQLce (because of my familiarity with SQL Server) and SQLite (because it's everywhere, comes on the mac, trivial to install in Linux, it's the new Rails 2.0 default database).

    As I'm increasingly living in a multi-platform environment, I think I'm leaning towards SQLite, but I'll welcome other suggestions that fit in the requirements.

    I'll return to this topic with my findings and overall development experience with the chosen database in the near future. For now I'll leave these useful SQLite links.

  • The new data types in SQL Server 2008

    I can't wait to use SQL 2008. I wish I could convince my DBA to jump on it as soon as it goes RTM, but the data peeps don't suffer of the same short attention span as us developers.

    Reading a recent Technet Magazine article and attending the launch event in Chicago made me drool for the new features. And I don't usually care that much for database technologies.

    The new features that are more within reach for developers are the new data types.

    Spatial Data Types

    A good part of my work involves GIS databases and overlaying business intelligence on top of it (or deriving BI from it). As such, it's with great interest that I see the addition of spatial data types in SQL 2008.

    With SQL 2008 I'll be able to treat all those latitude/longitude pairs as first class citizens in my tables and stored procedures. Add to that all the new supporting functions that come with these new data types. That means I do not have to write my own functions to determine the bounding rectangles around a collection of points or shapes. Nor will I have to create my own function to calculate the distance between two coordinate points considering the Earth's shape. Believe me, this can be huge.

    Suppose I have some oddly-shaped polygon that represents a geometric region like a mining field, a flood zone, or a pizza delivery service area (or anything small enough that can be considered flat, discarding the Earth's curvature).

    DECLARE @shape geometry
    SET @shape = geometry::STPolyFromText('POLYGON ((
                     47.653 -122.358, 
                     47.653 -122.354, 
                     47.657 -122.354, 
                     47.653 -122.350, 
                     47.645 -122.350, 
                     ... (snip)
                     47.651 -122.355, 
                     47.653 -122.358))',  0)

    First of all, it's nice to have a data type to represent this polygon, and not having to use my own parsing mechanism or using other tables to store that. Another good thing is that these data types follow the OGC standards.

    To determine the bounding rectangle for the shape defined above, it's as simple as calling a method on that shape object.

    SELECT @shape.STEnvelope().ToString()
    -- outputs something like
    /*
     POLYGON (( 
    	47.657 -122.358,
    	47.657 -122.350,
    	47.645 -122.350,
    	47.645 -122.358,
    	47.657 -122.358))
    */

    Did I say object? Doesn't the syntax above look like plain old .Net? Exactly. The spatial data types were implemented in .Net, leveraging the capability of adding .Net user defined types, which was introduced in SQL 2005.

    Spatial data types is a large topic, maybe I'll come back to it with a longer post once I have a chance to build an actual application with them. For now, I'll just point you to this nice series from Jason Follas.

    The DATE type

    When you don't need the time portion of a DATETIME, you can use the new 3-byte DATE type to store dates from 1/1/0001 to 12/31/9999. This coincides with the range (minus time) of the .Net System.DateTime structure.

    DECLARE @d DATE
    SET @d = GETDATE()
    SELECT @d -- outputs '2008-04-06 00:00:00.000'
    
    SET @d = '1234-03-22 11:25:09'
    SELECT @d  -- outputs '1234-03-22  00:00:00.000'

    The TIME type

    There are also scenarios when we only need the time portion of a DATETIME, that's where the new TIME type comes in handy.

    The TIME data type's size can be 3, 4, or 5 bytes, depending on the chosen precision. The default precision is 7 digits, but you can specify the precision you need when declaring the data.

    CREATE TABLE #times(
    	T 	TIME,
    	T1	TIME(1),
    	T5	TIME(5),
    	T7	TIME(7)
    	)
    
    INSERT INTO #times VALUES (
    	'01:02:03.1234567',
    	'01:02:03.1234567',
    	'01:02:03.1234567',
    	'01:02:03.1234567')
    
    SELECT * FROM #times
    
    T                T1               T5               T7
    ---------------- ---------------- ---------------- ----------------
    01:02:03.1234567 01:02:03.1000000 01:02:03.1234600 01:02:03.1234567

    The DATETIME2 type

    If you liked the increased precision of the TIME type and the increased date range of the DATE type, you'll be happy to learn that the new DATETIME2 stored date and time, with greater precision and range, basically combining those other 2 new data types.

    DECLARE @dateA DATETIME2 = '2008-04-05 01:02:03.12345'
    PRINT @dateA -- outputs 2008-04-05 01:02:03.1234500
    DECLARE @dateB DATETIME2(4) = '2008-04-05 01:02:03.12345'
    PRINT @dateB -- outputs 2008-04-05 01:02:03.1235

    With this new data type you can have your dates range from 0001-01-01 00:00:00.0000000 to 9999-12-31 23:59:59.9999999. Again, this works well with .Net applications. You can initialize the DATETIME2 with string literals as shown above. These literal can be either ODBC format or ISO-8601 (sortable date time format, same as DateTime.ToString("s") in .Net).

    The DATETIMEOFFSET type

    With this new data type, SQL Server learns about time-zones. This is of particular interest to me because of the globally distributed data and users that I have to deal with.

    The DATETIMEOFFSET type ranges in size from 8 to 10 bytes. It's precision is also defined at declaration time, just like the other new types shown above.

    -- time stamp on Central Daylight Time
    DECLARE @today DATETIMEOFFSET = '2008-04-05T01:02:03.1234567-05:00'
    PRINT @today -- outputs 2008-04-05 01:02:03.1234567 -05:00
    DECLARE @today2 DATETIMEOFFSET(2) = '2008-04-05T01:02:03.1234567-05:00'
    PRINT @today2 -- outputs 2008-04-05 01:02:03.12 -05:00

    We can initialize the DATETIMEOFFSET values using literal strings in ISO-8601 YYYY-MM-DDThh:mm:ss[.nnnnnnn][{+|-}hh:mm] or YYYY-MM-DDThh:mm:ss[.nnnnnnn]Z (for times exclusively in UTC.)

    The HIERARCHYID type

    About time, thank you. That's all I'm going to say. After having to endure the pain of representing, traversing, and querying hierarchical information stored in flat tables, I plan to use this data type extensively and never having to look back ever again.

    You probably know what I'm talking about. All those foreign keys that point to the same table, like ParentCategoryID in a Categories table or ReportsToID in an Employees table.

    Now we can simply define a column of type HIERARCHYID that will keep track of the record's position within the hierarchy being managed.

    -- our Categories table
    CREATE TABLE #Categories (
    	CategoryID INT IDENTITY(1,1),
    	CategoryNode HIERARCHYID NOT NULL,
    	CategName NVARCHAR(40) NOT NULL
    	)

    We will need to populate the CategoyNode field with the correct hierarchy information. The first element (the root) is the odd man out. After the root node, the process is quite repetitive.

    -- the root category
    DECLARE @root HIERARCHYID = hierarchyid::GetRoot()
    INSERT INTO #Categories (CategoryNode, CategName) 
    	VALUES (@root, 'All #Categories')
    
    -- insert the 'Electronics' category
    DECLARE @electronics HIERARCHYID
    SELECT @electronics = @root.GetDescendant(NULL, NULL)
    INSERT INTO #Categories (CategoryNode, CategName) 
    	VALUES (@electronics, 'Electronics')
    
    -- insert the 'Music' category after 'Electronics'
    DECLARE @music HIERARCHYID
    SELECT @music = @root.GetDescendant(NULL, @electronics)
    INSERT INTO #Categories (CategoryNode, CategName) 
    	VALUES (@music, 'Music')
    
    -- insert the 'Apparel' category between 'Electronics' and 'Music'
    SELECT @music = @root.GetDescendant(@music, @electronics)
    INSERT INTO #Categories (CategoryNode, CategName) 
    	VALUES (@music, 'Apparel')
    
    -- insert some children under 'Electronics'
    DECLARE @video HIERARCHYID
    --   We could do a simple @category.GetDescendant() but, let's
    --      show something that is more likely to happen
    SELECT @video = CategoryNode.GetDescendant(NULL, NULL)
      FROM #Categories WHERE CategName ='Electronics'
    INSERT INTO #Categories (CategoryNode, CategName) 
    	VALUES (@video, 'Video Equipment')
    
    -- insert some children under 'Video Equipment'
    DECLARE @tvs HIERARCHYID
    SELECT @tvs = @video.GetDescendant(NULL, NULL)
    INSERT INTO #Categories (CategoryNode, CategName) 
    	VALUES (@tvs, 'Televisions')
    
    DECLARE @players HIERARCHYID
    SELECT @players = @video.GetDescendant(NULL, @tvs)
    INSERT INTO #Categories (CategoryNode, CategName) 
    	VALUES (@players, 'DVD - BluRay')

    When we query the table, the output from the CategoryNode column reflects the position of the record in the hierarchy, similar to directory paths.

    SELECT 
    	CategoryID, CategName, 
    	CategoryNode, 
    	CategoryNode.ToString() AS Path
    FROM #Categories
    Output:
    CategoryID  CategName         CategoryNode   Path
    ----------- ----------------- -------------- ---------
    1           All #Categories   0x             /
    2           Electronics       0x58           /1/
    3           Music             0x48           /0/
    4           Apparel           0x52C0         /0.1/
    5           Video Equipment   0x5AC0         /1/1/
    6           Televisions       0x5AD6         /1/1/1/
    7           DVD - BluRay      0x5AD2         /1/1/0/

    Note that the numbers that are separated by / in the Path column are not the CategoryID values. They are values that represent the sequence of the record within its siblings. The value is directly related to where we positioned the node when we called GetDescendant. The HIERARCHYID data type stores a binary value, as shown in the above output.

    Now let's see how we would return all the items under a given category, recursively.

    DECLARE @electronics_Categ HIERARCHYID
    SELECT @electronics_Categ=CategoryNode 
    	FROM #Categories WHERE CategoryID=2
    SELECT CategoryID, CategName, CategoryNode.ToString() AS Path 
    	FROM #Categories 
    	WHERE @electronics_Categ.IsDescendant(CategoryNode)=1
    Output:
    CategoryID  CategName       Path
    ----------- --------------- --------
    2           Electronics     /1/
    5           Video Equipment /1/1/
    6           Televisions     /1/1/1/
    7           DVD - BluRay    /1/1/0/

    Being able to perform these sorts of queries without having to resort to Common Table Expressions makes the queries so much simpler. I need this now.

    You can get more details on the HIERARCHYID data type here.

    Wrapping up

    This post is by no means an extensive overview of these data types, but I hope it serves as a brief introduction to what is available in terms of data in the upcoming release of SQL 2008.

  • XHTML Validation Script using Ruby

    In one of the projects I'm working on we produce a number of XHTML documents and we want these documents to be valid XHTML 1.0 Strict. As an example of how automation will set you free, I promptly thought that there was no way I would be submitting several dozens of documents to the W3C XHTML validator.

    Instead of go looking for an web service or something that could provide that validation, I thought it would be more interesting and educational for me to try to automate the usage of the W3C validator using some Ruby goodness. I know, there are probably quicker ways of doing that, but I want to get better at Ruby, so sue me.

    I'll do my best to explain how the script works, I don't think it turned out too complicated. If anyone has tips for improving it, I'll be glad to hear about and learn even more.

    The W3C Markup Validation Service page as of this writing offers the option of uploading a file and have it validated. It's a simple HTTP form POST to the URL http://validator.w3.org/check . The only not-so-trivial task is how to post a file form field. This is when I though I will probably need this type of code again in the future, so let's just write it in a separate file to reuse later. After some research and trials I ended up with the following helper file, called form_post.rb (I'll dissect it in the sequence).

    require 'rubygems'
    require 'mime/types'
    require 'net/http'
    require 'CGI'
     
    class FormField
      attr_accessor :name, :value
      def initialize( name, value )
        @name = name
        @value = value
      end
     
      def to_form_data
        field = CGI::escape(@name)
        "Content-Disposition: form-data; name=\"#{field}\"" + 
          "\r\n\r\n#{@value}\r\n"
      end
    end
     
    class FileField
      attr_accessor :name, :path, :content
      def initialize( name, path, content )
        @name = name
        @path = path
        @content = content
      end
     
      def to_form_data
        "Content-Disposition: form-data; " + 
        "name=\"#{CGI::escape(@name)}\"; " + 
        "filename=\"#{@path}\"\r\n" +
        "Content-Transfer-Encoding: binary\r\n" +
        "Content-Type: #{MIME::Types.type_for(@path)}" + 
        "\r\n\r\n#{@content}\r\n"
      end
    end
    
    class MultipartPost
      SEPARATOR = 'willvalidate-aaaaaabbbb0000'
      REQ_HEADER = {
          "Content-type" => "multipart/form-data, boundary=#{SEPARATOR} "
       }
     
      def self.build_form_data ( form_fields )
        fields = []
        form_fields.each do |key, value|
          if value.instance_of?(File)
            fields << FileField.new(key.to_s, value.path, value.read)
          else
            fields << FormField.new(key.to_s, value)
          end
        end
        fields.collect {|f| "--#{SEPARATOR}\r\n#{f.to_form_data}" }.join("") + 
             "--#{SEPARATOR}--"
      end
    end

    Right at the top, we see.

    require 'rubygems'
    require 'mime/types'
    require 'net/http'
    require 'CGI'

    This is roughly equivalent to assembly references you have in your Visual Studio projects. We are just saying that we will need each of the listed libraries. Just like the .Net Framework, Ruby comes with a wealth of core and utility classes, organized in libraries. The rest of the code in this file will use classes and modules defined in these libraries.

    Then comes the FormField class, which represents one simple form field, a name/value pair basically.

    class FormField
      attr_accessor :name, :value
      def initialize( name, value )
        @name = name
        @value = value
      end
     
      def to_form_data
        field = CGI::escape(@name)
        "Content-Disposition: form-data; name=\"#{field}\"\r\n\r\n#{@value}\r\n"
      end
    end

    I won't explain the details of the class declaration syntax because I think Joe Ocampo already did a good job at that (link). Our FormField class has two properties FormField#name and FormField#value (see how we refer to the instance properties and methods in Ruby? We use the Class#method notation.), which represent a form field with name and its value, but only for simple input fields, not a file field yet.

    The FormField#to_form_data method (again, note the Ruby convention to have methods in lower case, words separated by underscores). This method will convert the name/value pair into the appropriate HTTP form data POST format. The CGI::escape is simply a class method (static method in C# terms) that will escape any especial characters in the field name.

    After that we just return a string with the expected form data layout. In Ruby, the return value of a method does not need to be provided by the return statement, it is optional. If no return statement is used, the return value will be the last evaluated expression — the string in our case. When But wait, there's something interesting in this string. Do you see #{field} and #{@value}? These will be automatically substituted by name and @value, respectively. You can use anything that is in scope and the substitution will be done via a process that is called String Interpolation. This only works with double-quoted strings (other delimiters can be used in Ruby to denote string literals.)

    OK, now on to the next class, FileField.

    class FileField
      attr_accessor :name, :path, :content
      def initialize( name, path, content )
        @name = name
        @path = path
        @content = content
      end
     
      def to_form_data
        "Content-Disposition: form-data; " + 
        "name=\"#{CGI::escape(@name)}\"; " + 
        "filename=\"#{@path}\"\r\n" +
        "Content-Transfer-Encoding: binary\r\n" +
        "Content-Type: #{MIME::Types.type_for(@path)}" + 
         "\r\n\r\n#{@content}\r\n"
      end
    end

    After seeing the FormField class, the FileField class becomes easier to understand. It represents one file that we want to include in the form posting as a file input field. It has the field name, the file path, and the file contents. The FileField#to_form_data also converts the file information to the appropriate posting format.

    This leads us to the last class in this file.

    class MultipartPost
      SEPARATOR = 'willvalidate-aaaaaabbbb0000'
      REQ_HEADER = {
          "Content-type" => "multipart/form-data, boundary=#{SEPARATOR} "
      }
     
      def self.build_form_data ( form_fields )
        fields = []
        form_fields.each do |key, value|
          if value.instance_of?(File)
            fields << FileField.new(key.to_s, value.path, value.read)
          else
            fields << FormField.new(key.to_s, value)
          end
        end
        fields.collect {|f| "--#{SEPARATOR}\r\n#{f.to_form_data}" }.join("") + 
          "--#{SEPARATOR}--"
      end

    The MultipartPost class starts by defining two constants SEPARATOR and REQ_HEADER that are strings. The simple fact that these identifiers start with an upper case character makes them constants. From outside the class' code these constants are accessed by prefixing with the class name, as in MultipartPost::SEPARATOR. Then comes the interesting part, the MultipartPost.build_form_data method (by the way, that is the notation for class methods). In this method, we are passed a Hash (like a Hashtable in .Net) containing all the fields that we want to post. We start the method by declaring a variable called fields as an empty Array.

    Almost anything that can be enumerated over in Ruby will have an each method, which is a common way of performing for loops and also one of the most fundamental Ruby idioms. When we iterate over a Hash with Hash#each, we provide a block of code, isolated in the snippet below.

                          do |key, value|
          if value.instance_of?(File)
            fields << FileField.new(key.to_s, value.path, value.read)
          else
            fields << FormField.new(key.to_s, value)
          end
        end

    Since C# 2.0 we have had anonymous methods, and more so now that C# 3.0 has lambdas, the job of explaining the above code is probably easier than what it used to be in .Net 1.x days. This code is more or less the equivalent of the following C# syntax.

    (key, value) => {
        FileInfo fi = value as FileInfo;
        if(fi != null)
            arrayList.Add(new FileField(key.ToString(), fi.Name, File.ReadAllText(fi.Name));
        else
            arrayList.Add(new FormField(key.ToString(), value);
    }

    What this code is doing in checking each key/value pair in the Hash, and if the value is an instance of the File class, a new instance of FileField will be added to the fields array, otherwise a new FormField will.

    At this point the fields array will be a mixed bag of FileField and FormField objects, which would be very undesirable if we were in C# and these classes not being related to each other. Not so much in a Ruby. The last line in this method goes to town with that array.

    fields.collect {|f| "--#{SEPARATOR}\r\n#{f.to_form_data}" }.join("") + 
         "--#{SEPARATOR}--"

    The Array#collect method (same as Array#map) will convert each item in the array to a pre-formatted string, producing another array with all these strings. Then the Array#join method is called to concatenate all these strings. The end result is a long string with all the form fields formatted appropriately. One thing to note in the array conversion is that the to_form_data method is called for both FormField and FileField items even though the method is not defined in a common base class. That's the power of Duck Typing.

    We still need to write the code to post a form to the W3C validator, but fear not, that will be very simple when we use the above classes. Here's code that will do the trick, let's save it to a file called w3c_validation.rb.

    require 'net/http'
    require 'form_post'
    
    def post_file_to_w3c_validator(file_path, doc_type)
      query = MultipartPost.build_form_data(
            :uploaded_file  => File.new(file_path, 'r'),
            :charset        => '(detect automatically)',
            :doctype        => doc_type,   
            :group          => '0'
            )
    
      Net::HTTP.start('validator.w3.org') do |http|
        http.post2("/check", query, MultipartPost::REQ_HEADER)
      end
    end
    
    def valid_response?(w3c_response)
      html = w3c_response.read_body
      html.include? "[Valid]"
    end
    
    def w3c_valid?(file_path)
      resp = post_file_to_w3c_validator(file_path, 'XHTML 1.0 Strict')
      valid_response?(resp)
    end
    
    file = "c:/temp/invalid.html"
    #file = "c:/temp/valid.html"
    result = w3c_valid?(file)
    puts "File is valid? #{result}"
    

    Again, at the top of the file we declare which libraries we will need. Note that (line 2) we are asking for form_post, that happens to be the previous file we just examined. As long as you save both files in the same directory, they will be able to reference each other if needed. That line will make all three classes we created available in this file.

    The post_file_to_w3c_validator method uses MultipartPost.build_form_data to prepare the contents to post to http://validator.w3.org/check.

    def post_file_to_w3c_validator(file_path, doc_type)
      query = MultipartPost.build_form_data(
            :uploaded_file  => File.new(file_path, 'r'),
            :charset        => '(detect automatically)',
            :doctype        => doc_type,   
            :group          => '0'
            )
    
      Net::HTTP.start('validator.w3.org') do |http|
        http.post2("/check", query, MultipartPost::REQ_HEADER)
      end
    end

    Remember that we said MultipartPost.build_form_data takes a Hash as its parameter? Well, this is how we create a Hash.

    my_hash = { :key1 => value1, :key2 => value2 , ..... }

    When the only (or the last non-block) parameter of the method is a Hash we can omit the curlies { } and make the hash look like a list of key/value pairs. Note how we are passing a File object in the :uploaded_file key. You may be asking "what's up with those colon-prefixed identifiers?" Well, they are Symbols, Ruby's way of creating interned strings. Think of them as string constants or "the name of something". They are used a lot as hash keys.

    Next up, the actual POST operation.

      Net::HTTP.start('validator.w3.org') do |http|
        http.post2("/check", query, MultipartPost::REQ_HEADER)
      end

    I won't explain too much this code but it should be easy to realize that it is posting the query data to the W3C validator URL. Since this is the last statement in the method, the returned value of the method will be the result from the call to Net::HTTP#post2, which happens to be a Net::HTTPResponse object.

    def valid_response?(w3c_response)
      html = w3c_response.read_body
      html.include? "[Valid]"
    end

    The valid_response? method, as indicated by the trailing question mark (yes, you can use question marks in Ruby identifiers,) returns true or false. It takes one of those Net::HTTPResponse objects as a parameter and does a very low-tech analysis of the returned response text. It just checks if the text contains [Valid]. Hey, look, another method that ends in question mark: String#include?.

    It's funny how the last method I will explain is the first one to be called. It's the w3c_valid? method. It takes in a file path, posts that file to the validator, and tests the response gotten from that.

    def w3c_valid?(file_path)
      resp = post_file_to_w3c_validator(file_path, 'XHTML 1.0 Strict')
      valid_response?(resp)
    end

    But all these are just a bunch of methods, we still need to invoke them. That's what the last few lines do.

    file = "c:/temp/invalid.html"
    #file = "c:/temp/valid.html"
    result = w3c_valid?(file)
    puts "File is valid? #{result}"

    The call to puts prints the given string on the screen (std output to be more precise.) The code is trivial and it passes a file path to the w3c_valid? method, then prints the result.

    To run this code, first go to line 27 and change the file variable to point to some XHTML file you have (valid or invalid, note the forward slashes) then just execute:

    ruby w3c_validation.rb

    I will leave as an exercise to the reader the enhancement of the script to find all XHTML files in a given directory, process one by one, and log the result to the screen or to a text file.

    Note Note that you may get an error when you try to run the script because you don't have the mime/types library (a Ruby Gem). It's easy to get it installed, just run this from the command line.
    gem install mime-types

    Note 2 I forgot to mention that the true/false validation output is only the first step. My idea is to parse the entire response and collect the errors and warnings.

  • The fun continues

    By now you either realized that my last post was a joke, not even written by me, or you are not even reading this post because I was automatically dropped from your feed list.

    The joke was obvious, but more interesting is trying to discover who wrote what, where. Make your guesses. Here is a list of the April Fool's items I came across today (so far). Any other funny one that you'd like to share?

    Alt.Net Pursefight meme

    1. My blog
    2. Dave's blog
    3. Tom's blog
    4. Bil's blog
    5. Derik's blog
    6. Donald's blog
    7. D'Arcy's blog
    8. Kyle's blog
    9. Sean's blog

    Development Community in general

    Other sightings


  • Attention! Major Announcement That Will Change *Everything*

    Update This post is obviously not serious.

    I have a major announcement to make on my blog...one that I'm sure will bring much wrath and hatred to myself and my family...but one that I must make. I've enlisted the help of my long time friend, the Mad Mexican, to bring to light a secret that I've kept hidden for far too long.


    Watch the video  

    Yes mon-ami, I'm the guy behind Alt.Net Pursefight. There...I've said it...we can move on...well, I have a bit of housecleaning to do.

    David Laribee, I'm sorry I called you an @$$hole for Twittering that you went to Mix. It was the tequila talking, honest. All I wanted was a hug at the last Alt.NET conference...

    Derek Greer, you're still an A-1 jackass.

    Stewart Robertson, you are still the owner of the Ace Muthafuckah of '08 award. What's John McDowall's official title at your company: Beyatch who spellchecks blog posts about me?

    Bellware, you owe me mad props for keeping you relevant by having so many assume that you were behind Alt.Net Pursefight. Get whatever smurf does the cooking in your village to bake me some pie!

    Seriously...I feel a weight has been lifted from my shoulders! *sigh*

More Posts

Our Sponsors

Red-Gate!

Proudly Partnered With