<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description>an addiction to or an obsession with acquiring, manipulating, and sharing information</description><title>layer:11</title><generator>Tumblr (3.0; @layer11)</generator><link>http://blog.crt.lv/</link><item><title>Connecting to Cassandra with C# and Thrift</title><description>&lt;p&gt;Here’s something I wanted to write down for a long time now, because every time I have to do this (when Cassandra changes its interface), I have already forgotten what and exactly how needs to be done. Let’s assume that we have &lt;a href="http://cassandra.apache.org/" title="The Apache Cassandra Project"&gt;Cassandra&lt;/a&gt; up and running, because most distributions should have a package ready to use, or at least a build script. And now we want to connect to it with C#. What we need is two C# libraries, &lt;a href="http://thrift.apache.org/" title="Apache Thrift"&gt;Thrift&lt;/a&gt; and Cassandra. So, let’s build them from source.&lt;/p&gt;

&lt;p&gt;What exactly is Thrift? It’s a framework for building services and clients for those services - you write a file that describes what you want, then use the Thrift compiler to get a server skeleton and a &lt;abbr title="Remote Procedure Call"&gt;RPC&lt;/abbr&gt; client in any language that Thrift supports.&lt;/p&gt;

&lt;p&gt;First thing we need is a Thrift compiler and a Thrift library for C#. Let’s &lt;a href="http://thrift.apache.org/download/"&gt;download the Thrift source&lt;/a&gt; and simply &lt;code&gt;./configure &amp;&amp; make&lt;/code&gt; it, no need to install. You might want to disable support for other languages, they don’t get in the way, but I had problems building a Ruby library from Thrift 0.7.0. Now we have a C# Thrift library (&lt;code&gt;lib/csharp/Thrift.dll&lt;/code&gt;) and a Thrift compiler (&lt;code&gt;compiler/cpp/thrift&lt;/code&gt;). This library doesn’t give us much by itself, but it’s required for the Cassandra library, that we’ll generate with the Thrift compiler.&lt;/p&gt;

&lt;p&gt;Let’s get the Thrift definition file, that describes how Cassandra works, it’s &lt;code&gt;interface/cassandra.thrift&lt;/code&gt; from &lt;a href="http://cassandra.apache.org/download/"&gt;the Cassandra source&lt;/a&gt;. Now we can use the Thrift compiler, to generate C# source files for Cassandra client: &lt;code&gt;./thrift -gen csharp cassandra.thrift&lt;/code&gt;. Output is in &lt;code&gt;gen-csharp/Apache/Cassandra&lt;/code&gt;, just &lt;code&gt;cd&lt;/code&gt; there and build it all: &lt;code&gt;dmcs -r:Thrift -t:library -out:Apache.Cassandra.dll *.cs&lt;/code&gt;. Don’t forget to copy &lt;code&gt;Thrift.dll&lt;/code&gt; there, or add the appropriate &lt;code&gt;-lib:&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That should be it, we have all we need - a Thrift library (&lt;code&gt;Thrift.dll&lt;/code&gt;) and a Cassandra client library (&lt;code&gt;Apache.Cassandra.dll&lt;/code&gt;).&lt;/p&gt;</description><link>http://blog.crt.lv/post/10597492250</link><guid>http://blog.crt.lv/post/10597492250</guid><pubDate>Sat, 24 Sep 2011 17:42:00 +0300</pubDate><category>C Sharp</category><category>Mono</category><category>Cassandra</category><category>Thrift</category></item><item><title>Web Server In 50 Lines</title><description>&lt;p&gt;Web servers are useful, but not always you want or can install and configure one. Here’s a self contained, functional, multi-threaded and extensible web server in just few lines of C#.&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;
&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="Statement"&gt;using&lt;/span&gt; System;
&lt;span class="lnr"&gt; 2 &lt;/span&gt;&lt;span class="Statement"&gt;using&lt;/span&gt; System.IO;
&lt;span class="lnr"&gt; 3 &lt;/span&gt;&lt;span class="Statement"&gt;using&lt;/span&gt; System.Net;
&lt;span class="lnr"&gt; 4 &lt;/span&gt;&lt;span class="Statement"&gt;using&lt;/span&gt; System.Text;
&lt;span class="lnr"&gt; 5 &lt;/span&gt;
&lt;span class="lnr"&gt; 6 &lt;/span&gt;
&lt;span class="lnr"&gt; 7 &lt;/span&gt;&lt;span class="Type"&gt;class&lt;/span&gt; Server {
&lt;span class="lnr"&gt; 8 &lt;/span&gt;
&lt;span class="lnr"&gt; 9 &lt;/span&gt;  &lt;span class="Type"&gt;static&lt;/span&gt; String root = &lt;span class="Constant"&gt;"/home/you/web/root/"&lt;/span&gt;;
&lt;span class="lnr"&gt;10 &lt;/span&gt;
&lt;span class="lnr"&gt;11 &lt;/span&gt;  &lt;span class="Type"&gt;static&lt;/span&gt; String prefix = &lt;span class="Constant"&gt;"&lt;a href="http://localhost:8000/"&gt;http://localhost:8000/&lt;/a&gt;"&lt;/span&gt;;
&lt;span class="lnr"&gt;12 &lt;/span&gt;
&lt;span class="lnr"&gt;13 &lt;/span&gt;  &lt;span class="Type"&gt;static&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; Main(String[] args) {
&lt;span class="lnr"&gt;14 &lt;/span&gt;    &lt;span class="Statement"&gt;using&lt;/span&gt; (var http = &lt;span class="Statement"&gt;new&lt;/span&gt; HttpListener()) {
&lt;span class="lnr"&gt;15 &lt;/span&gt;      http.Prefixes.Add(prefix);
&lt;span class="lnr"&gt;16 &lt;/span&gt;      http.Start();
&lt;span class="lnr"&gt;17 &lt;/span&gt;      &lt;span class="Statement"&gt;while&lt;/span&gt; (http.IsListening) {
&lt;span class="lnr"&gt;18 &lt;/span&gt;        var callback = &lt;span class="Statement"&gt;new&lt;/span&gt; AsyncCallback(dispatch);
&lt;span class="lnr"&gt;19 &lt;/span&gt;        var result = http.BeginGetContext(callback, http);
&lt;span class="lnr"&gt;20 &lt;/span&gt;        result.AsyncWaitHandle.WaitOne();
&lt;span class="lnr"&gt;21 &lt;/span&gt;      }
&lt;span class="lnr"&gt;22 &lt;/span&gt;    }
&lt;span class="lnr"&gt;23 &lt;/span&gt;  }
&lt;span class="lnr"&gt;24 &lt;/span&gt;
&lt;span class="lnr"&gt;25 &lt;/span&gt;  &lt;span class="Type"&gt;static&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; dispatch(IAsyncResult result) {
&lt;span class="lnr"&gt;26 &lt;/span&gt;    var http = (HttpListener)result.AsyncState;
&lt;span class="lnr"&gt;27 &lt;/span&gt;    var context = http.EndGetContext(result);
&lt;span class="lnr"&gt;28 &lt;/span&gt;    &lt;span class="Statement"&gt;using&lt;/span&gt; (var responseStream = &lt;span class="Statement"&gt;new&lt;/span&gt; MemoryStream()) {
&lt;span class="lnr"&gt;29 &lt;/span&gt;      var localPath = Path.Combine(root, context.Request.Url.LocalPath.Substring(&lt;span class="Constant"&gt;1&lt;/span&gt;));
&lt;span class="lnr"&gt;30 &lt;/span&gt;      &lt;span class="Statement"&gt;if&lt;/span&gt; (File.Exists(localPath)) {
&lt;span class="lnr"&gt;31 &lt;/span&gt;        &lt;span class="Statement"&gt;using&lt;/span&gt; (var file = File.OpenRead(localPath)) {
&lt;span class="lnr"&gt;32 &lt;/span&gt;          file.CopyTo(responseStream);
&lt;span class="lnr"&gt;33 &lt;/span&gt;        }
&lt;span class="lnr"&gt;34 &lt;/span&gt;      }
&lt;span class="lnr"&gt;35 &lt;/span&gt;      &lt;span class="Statement"&gt;else&lt;/span&gt; {
&lt;span class="lnr"&gt;36 &lt;/span&gt;        var text = Encoding.UTF8.GetBytes(&lt;span class="Constant"&gt;"404"&lt;/span&gt;);
&lt;span class="lnr"&gt;37 &lt;/span&gt;        responseStream.Write(text, &lt;span class="Constant"&gt;0&lt;/span&gt;, text.Length);
&lt;span class="lnr"&gt;38 &lt;/span&gt;      }
&lt;span class="lnr"&gt;39 &lt;/span&gt;      context.Response.ContentLength64 = responseStream.Length;
&lt;span class="lnr"&gt;40 &lt;/span&gt;      responseStream.WriteTo(context.Response.OutputStream);
&lt;span class="lnr"&gt;41 &lt;/span&gt;      context.Response.OutputStream.Close();
&lt;span class="lnr"&gt;42 &lt;/span&gt;    }
&lt;span class="lnr"&gt;43 &lt;/span&gt;  }
&lt;span class="lnr"&gt;44 &lt;/span&gt;}
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;So, you start up a &lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.net.httplistener.aspx" title="HttpListener Class (System.Net)"&gt;HttpListener&lt;/a&gt;&lt;/code&gt; and pass every request it receives to &lt;code&gt;dispatch()&lt;/code&gt;, there you can get a context that holds a &lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.web.httprequest.aspx" title="HttpRequest Class (System.Web)"&gt;HttpRequest&lt;/a&gt;&lt;/code&gt; and a &lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.web.httpresponse.aspx" title="HttpResponse Class (System.Web)"&gt;HttpResponse&lt;/a&gt;&lt;/code&gt;, that you know and love, from there on, you’re free on how exactly you create the response, I check, if the requested URL can be mapped to a file, if so, I return that file, if not, I simply write “404”. That should give you a good idea, on how to expand this to match your needs.&lt;/p&gt;

&lt;p&gt;Works quite well in my experience. One thing you have to be careful about, is exceptions in &lt;code&gt;dispatch()&lt;/code&gt;, as they are in a new thread, you obviously won’t see them in &lt;code&gt;Main()&lt;/code&gt;.&lt;/p&gt;</description><link>http://blog.crt.lv/post/10246233617</link><guid>http://blog.crt.lv/post/10246233617</guid><pubDate>Thu, 15 Sep 2011 22:07:00 +0300</pubDate><category>C Sharp</category><category>.NET</category><category>Mono</category></item><item><title>Transpose Rows To Columns</title><description>&lt;p&gt;One very common problem when making reports from a &lt;abbr title="Relational Database Management System"&gt;RDBMS&lt;/abbr&gt;, is that you need to show, data that’s stored in rows, in columns. For example, from data like this:&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;
&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="Statement"&gt;CREATE&lt;/span&gt; &lt;span class="Statement"&gt;TABLE&lt;/span&gt; #data_a (
&lt;span class="lnr"&gt; 2 &lt;/span&gt;  cat &lt;span class="Type"&gt;varchar&lt;/span&gt;(&lt;span class="Constant"&gt;20&lt;/span&gt;) &lt;span class="Statement"&gt;NOT&lt;/span&gt; &lt;span class="Constant"&gt;NULL&lt;/span&gt;,
&lt;span class="lnr"&gt; 3 &lt;/span&gt;  mon &lt;span class="Type"&gt;date&lt;/span&gt; &lt;span class="Statement"&gt;NOT&lt;/span&gt; &lt;span class="Constant"&gt;NULL&lt;/span&gt;,
&lt;span class="lnr"&gt; 4 &lt;/span&gt;  val &lt;span class="Type"&gt;int&lt;/span&gt; &lt;span class="Statement"&gt;NOT&lt;/span&gt; &lt;span class="Constant"&gt;NULL&lt;/span&gt;
&lt;span class="lnr"&gt; 5 &lt;/span&gt;);
&lt;span class="lnr"&gt; 6 &lt;/span&gt;&lt;span class="Statement"&gt;INSERT&lt;/span&gt; &lt;span class="Statement"&gt;INTO&lt;/span&gt; #data_a
&lt;span class="lnr"&gt; 7 &lt;/span&gt;&lt;span class="Statement"&gt;VALUES&lt;/span&gt;
&lt;span class="lnr"&gt; 8 &lt;/span&gt;  (&lt;span class="Constant"&gt;'Foo'&lt;/span&gt;, &lt;span class="Constant"&gt;'2011-02-01'&lt;/span&gt;, &lt;span class="Constant"&gt;'752'&lt;/span&gt;),
&lt;span class="lnr"&gt; 9 &lt;/span&gt;  (&lt;span class="Constant"&gt;'Qux'&lt;/span&gt;, &lt;span class="Constant"&gt;'2011-03-01'&lt;/span&gt;, &lt;span class="Constant"&gt;'700'&lt;/span&gt;),
&lt;span class="lnr"&gt;10 &lt;/span&gt;  (&lt;span class="Constant"&gt;'Qux'&lt;/span&gt;, &lt;span class="Constant"&gt;'2011-03-01'&lt;/span&gt;, &lt;span class="Constant"&gt;'936'&lt;/span&gt;),
&lt;span class="lnr"&gt;11 &lt;/span&gt;  (&lt;span class="Constant"&gt;'Bar'&lt;/span&gt;, &lt;span class="Constant"&gt;'2011-02-01'&lt;/span&gt;, &lt;span class="Constant"&gt;'899'&lt;/span&gt;),
&lt;span class="lnr"&gt;12 &lt;/span&gt;  (&lt;span class="Constant"&gt;'Foo'&lt;/span&gt;, &lt;span class="Constant"&gt;'2011-01-01'&lt;/span&gt;, &lt;span class="Constant"&gt;'482'&lt;/span&gt;),
&lt;span class="lnr"&gt;13 &lt;/span&gt;  (&lt;span class="Constant"&gt;'Qux'&lt;/span&gt;, &lt;span class="Constant"&gt;'2011-01-01'&lt;/span&gt;, &lt;span class="Constant"&gt;'349'&lt;/span&gt;),
&lt;span class="lnr"&gt;14 &lt;/span&gt;  (&lt;span class="Constant"&gt;'Foo'&lt;/span&gt;, &lt;span class="Constant"&gt;'2011-03-01'&lt;/span&gt;, &lt;span class="Constant"&gt;'67'&lt;/span&gt;),
&lt;span class="lnr"&gt;15 &lt;/span&gt;  (&lt;span class="Constant"&gt;'Bar'&lt;/span&gt;, &lt;span class="Constant"&gt;'2011-02-01'&lt;/span&gt;, &lt;span class="Constant"&gt;'999'&lt;/span&gt;),
&lt;span class="lnr"&gt;16 &lt;/span&gt;  (&lt;span class="Constant"&gt;'Bar'&lt;/span&gt;, &lt;span class="Constant"&gt;'2011-01-01'&lt;/span&gt;, &lt;span class="Constant"&gt;'183'&lt;/span&gt;);
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;You would need to show, for example, the first three months, of the current year, in a table with a column for each month. A straightforward way to achieve this would be:&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;
&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="Statement"&gt;SELECT&lt;/span&gt;
&lt;span class="lnr"&gt; 2 &lt;/span&gt;  d.cat,
&lt;span class="lnr"&gt; 3 &lt;/span&gt;  &lt;span class="Function"&gt;SUM&lt;/span&gt;(&lt;span class="Statement"&gt;CASE WHEN&lt;/span&gt; &lt;span class="Function"&gt;MONTH&lt;/span&gt;(d.mon) = &lt;span class="Constant"&gt;1&lt;/span&gt; &lt;span class="Statement"&gt;THEN&lt;/span&gt; d.val &lt;span class="Statement"&gt;ELSE&lt;/span&gt; &lt;span class="Constant"&gt;0&lt;/span&gt; &lt;span class="Statement"&gt;END&lt;/span&gt;) &lt;span class="Statement"&gt;AS&lt;/span&gt; january_sum,
&lt;span class="lnr"&gt; 4 &lt;/span&gt;  &lt;span class="Function"&gt;SUM&lt;/span&gt;(&lt;span class="Statement"&gt;CASE WHEN&lt;/span&gt; &lt;span class="Function"&gt;MONTH&lt;/span&gt;(d.mon) = &lt;span class="Constant"&gt;2&lt;/span&gt; &lt;span class="Statement"&gt;THEN&lt;/span&gt; d.val &lt;span class="Statement"&gt;ELSE&lt;/span&gt; &lt;span class="Constant"&gt;0&lt;/span&gt; &lt;span class="Statement"&gt;END&lt;/span&gt;) &lt;span class="Statement"&gt;AS&lt;/span&gt; february_sum,
&lt;span class="lnr"&gt; 5 &lt;/span&gt;  &lt;span class="Function"&gt;SUM&lt;/span&gt;(&lt;span class="Statement"&gt;CASE WHEN&lt;/span&gt; &lt;span class="Function"&gt;MONTH&lt;/span&gt;(d.mon) = &lt;span class="Constant"&gt;3&lt;/span&gt; &lt;span class="Statement"&gt;THEN&lt;/span&gt; d.val &lt;span class="Statement"&gt;ELSE&lt;/span&gt; &lt;span class="Constant"&gt;0&lt;/span&gt; &lt;span class="Statement"&gt;END&lt;/span&gt;) &lt;span class="Statement"&gt;AS&lt;/span&gt; march_sum
&lt;span class="lnr"&gt; 6 &lt;/span&gt;&lt;span class="Statement"&gt;FROM&lt;/span&gt; #data_a &lt;span class="Statement"&gt;AS&lt;/span&gt; d
&lt;span class="lnr"&gt; 7 &lt;/span&gt;&lt;span class="Statement"&gt;WHERE&lt;/span&gt;
&lt;span class="lnr"&gt; 8 &lt;/span&gt;  &lt;span class="Function"&gt;YEAR&lt;/span&gt;(d.mon) = &lt;span class="Function"&gt;YEAR&lt;/span&gt;(&lt;span class="Constant"&gt;CURRENT_TIMESTAMP&lt;/span&gt;) &lt;span class="Statement"&gt;AND&lt;/span&gt;
&lt;span class="lnr"&gt; 9 &lt;/span&gt;  &lt;span class="Function"&gt;MONTH&lt;/span&gt;(d.mon) &lt;span class="Statement"&gt;IN&lt;/span&gt; (&lt;span class="Constant"&gt;1&lt;/span&gt;, &lt;span class="Constant"&gt;2&lt;/span&gt;, &lt;span class="Constant"&gt;3&lt;/span&gt;)
&lt;span class="lnr"&gt;10 &lt;/span&gt;&lt;span class="Statement"&gt;GROUP&lt;/span&gt; &lt;span class="Statement"&gt;BY&lt;/span&gt; d.cat
&lt;span class="lnr"&gt;11 &lt;/span&gt;&lt;span class="Statement"&gt;ORDER&lt;/span&gt; &lt;span class="Statement"&gt;BY&lt;/span&gt; d.cat;
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;Works fine, easy to use and understand. A bit more advanced solution would be with &lt;a href="http://msdn.microsoft.com/en-us/library/ms177410.aspx" title="Using PIVOT and UNPIVOT"&gt;&lt;code&gt;PIVOT()&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;
&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="Statement"&gt;SELECT&lt;/span&gt;
&lt;span class="lnr"&gt; 2 &lt;/span&gt;  p.cat,
&lt;span class="lnr"&gt; 3 &lt;/span&gt;  &lt;span class="Function"&gt;COALESCE&lt;/span&gt;(p.January, &lt;span class="Constant"&gt;0&lt;/span&gt;) &lt;span class="Statement"&gt;AS&lt;/span&gt; january_sum,
&lt;span class="lnr"&gt; 4 &lt;/span&gt;  &lt;span class="Function"&gt;COALESCE&lt;/span&gt;(p.February, &lt;span class="Constant"&gt;0&lt;/span&gt;) &lt;span class="Statement"&gt;AS&lt;/span&gt; february_sum,
&lt;span class="lnr"&gt; 5 &lt;/span&gt;  &lt;span class="Function"&gt;COALESCE&lt;/span&gt;(p.March, &lt;span class="Constant"&gt;0&lt;/span&gt;) &lt;span class="Statement"&gt;AS&lt;/span&gt; march_sum
&lt;span class="lnr"&gt; 6 &lt;/span&gt;&lt;span class="Statement"&gt;FROM&lt;/span&gt; (
&lt;span class="lnr"&gt; 7 &lt;/span&gt;  &lt;span class="Statement"&gt;SELECT&lt;/span&gt;
&lt;span class="lnr"&gt; 8 &lt;/span&gt;    d.cat,
&lt;span class="lnr"&gt; 9 &lt;/span&gt;    &lt;span class="Function"&gt;DATENAME&lt;/span&gt;(&lt;span class="Constant"&gt;MONTH&lt;/span&gt;, d.mon) &lt;span class="Statement"&gt;AS&lt;/span&gt; col,
&lt;span class="lnr"&gt;10 &lt;/span&gt;    d.val
&lt;span class="lnr"&gt;11 &lt;/span&gt;  &lt;span class="Statement"&gt;FROM&lt;/span&gt; #data_a &lt;span class="Statement"&gt;AS&lt;/span&gt; d
&lt;span class="lnr"&gt;12 &lt;/span&gt;  &lt;span class="Statement"&gt;WHERE&lt;/span&gt;
&lt;span class="lnr"&gt;13 &lt;/span&gt;    &lt;span class="Function"&gt;YEAR&lt;/span&gt;(d.mon) = &lt;span class="Function"&gt;YEAR&lt;/span&gt;(&lt;span class="Constant"&gt;CURRENT_TIMESTAMP&lt;/span&gt;) &lt;span class="Statement"&gt;AND&lt;/span&gt;
&lt;span class="lnr"&gt;14 &lt;/span&gt;    &lt;span class="Function"&gt;MONTH&lt;/span&gt;(d.mon) &lt;span class="Statement"&gt;IN&lt;/span&gt; (&lt;span class="Constant"&gt;1&lt;/span&gt;, &lt;span class="Constant"&gt;2&lt;/span&gt;, &lt;span class="Constant"&gt;3&lt;/span&gt;)
&lt;span class="lnr"&gt;15 &lt;/span&gt;) &lt;span class="Statement"&gt;AS&lt;/span&gt; d
&lt;span class="lnr"&gt;16 &lt;/span&gt;&lt;span class="Function"&gt;PIVOT&lt;/span&gt;(
&lt;span class="lnr"&gt;17 &lt;/span&gt;  &lt;span class="Function"&gt;SUM&lt;/span&gt;(d.val)
&lt;span class="lnr"&gt;18 &lt;/span&gt;  &lt;span class="Statement"&gt;FOR&lt;/span&gt; d.col &lt;span class="Statement"&gt;IN&lt;/span&gt; (
&lt;span class="lnr"&gt;19 &lt;/span&gt;    January,
&lt;span class="lnr"&gt;20 &lt;/span&gt;    February,
&lt;span class="lnr"&gt;21 &lt;/span&gt;    March
&lt;span class="lnr"&gt;22 &lt;/span&gt;  )
&lt;span class="lnr"&gt;23 &lt;/span&gt;) &lt;span class="Statement"&gt;AS&lt;/span&gt; p
&lt;span class="lnr"&gt;24 &lt;/span&gt;&lt;span class="Statement"&gt;ORDER&lt;/span&gt; &lt;span class="Statement"&gt;BY&lt;/span&gt; p.cat;
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;But I don’t feel like there’s a good reason to use it, no benefit and more awkward syntax. I’ll try to give a short explanation on what goes into &lt;code&gt;PIVOT()&lt;/code&gt;. &lt;code&gt;SUM(d.val)&lt;/code&gt; says to aggregate &lt;code&gt;d.val&lt;/code&gt; by summing it, &lt;code&gt;FOR d.col&lt;/code&gt; means that you want to move values from &lt;code&gt;d.col&lt;/code&gt; to new columns, &lt;code&gt;IN (January, February, March)&lt;/code&gt; determines which values get moved to new columns (and the name of those columns). Another thing to note, &lt;code&gt;p.cat&lt;/code&gt; in &lt;code&gt;SELECT&lt;/code&gt;, not &lt;code&gt;d.cat&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;OK, how about a bit different situation:&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;
&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="Statement"&gt;CREATE&lt;/span&gt; &lt;span class="Statement"&gt;TABLE&lt;/span&gt; #data_b (
&lt;span class="lnr"&gt; 2 &lt;/span&gt;  cat &lt;span class="Type"&gt;varchar&lt;/span&gt;(&lt;span class="Constant"&gt;20&lt;/span&gt;) &lt;span class="Statement"&gt;NOT&lt;/span&gt; &lt;span class="Constant"&gt;NULL&lt;/span&gt;,
&lt;span class="lnr"&gt; 3 &lt;/span&gt;  mon &lt;span class="Type"&gt;date&lt;/span&gt; &lt;span class="Statement"&gt;NOT&lt;/span&gt; &lt;span class="Constant"&gt;NULL&lt;/span&gt;,
&lt;span class="lnr"&gt; 4 &lt;/span&gt;  val &lt;span class="Type"&gt;char&lt;/span&gt;(&lt;span class="Constant"&gt;5&lt;/span&gt;) &lt;span class="Statement"&gt;NOT&lt;/span&gt; &lt;span class="Constant"&gt;NULL&lt;/span&gt;,
&lt;span class="lnr"&gt; 5 &lt;/span&gt;  &lt;span class="Statement"&gt;UNIQUE&lt;/span&gt; (cat, mon)
&lt;span class="lnr"&gt; 6 &lt;/span&gt;);
&lt;span class="lnr"&gt; 7 &lt;/span&gt;&lt;span class="Statement"&gt;INSERT&lt;/span&gt; &lt;span class="Statement"&gt;INTO&lt;/span&gt; #data_b
&lt;span class="lnr"&gt; 8 &lt;/span&gt;&lt;span class="Statement"&gt;VALUES&lt;/span&gt;
&lt;span class="lnr"&gt; 9 &lt;/span&gt;  (&lt;span class="Constant"&gt;'Foo'&lt;/span&gt;, &lt;span class="Constant"&gt;'2011-01-01'&lt;/span&gt;, &lt;span class="Constant"&gt;'CDHDE'&lt;/span&gt;),
&lt;span class="lnr"&gt;10 &lt;/span&gt;  (&lt;span class="Constant"&gt;'Qux'&lt;/span&gt;, &lt;span class="Constant"&gt;'2011-01-01'&lt;/span&gt;, &lt;span class="Constant"&gt;'DTDLI'&lt;/span&gt;),
&lt;span class="lnr"&gt;11 &lt;/span&gt;  (&lt;span class="Constant"&gt;'Qux'&lt;/span&gt;, &lt;span class="Constant"&gt;'2011-03-01'&lt;/span&gt;, &lt;span class="Constant"&gt;'PIQXG'&lt;/span&gt;),
&lt;span class="lnr"&gt;12 &lt;/span&gt;  (&lt;span class="Constant"&gt;'Bar'&lt;/span&gt;, &lt;span class="Constant"&gt;'2011-02-01'&lt;/span&gt;, &lt;span class="Constant"&gt;'TVDDI'&lt;/span&gt;),
&lt;span class="lnr"&gt;13 &lt;/span&gt;  (&lt;span class="Constant"&gt;'Foo'&lt;/span&gt;, &lt;span class="Constant"&gt;'2011-02-01'&lt;/span&gt;, &lt;span class="Constant"&gt;'VJKRC'&lt;/span&gt;),
&lt;span class="lnr"&gt;14 &lt;/span&gt;  (&lt;span class="Constant"&gt;'Bar'&lt;/span&gt;, &lt;span class="Constant"&gt;'2011-03-01'&lt;/span&gt;, &lt;span class="Constant"&gt;'XWMAG'&lt;/span&gt;),
&lt;span class="lnr"&gt;15 &lt;/span&gt;  (&lt;span class="Constant"&gt;'Qux'&lt;/span&gt;, &lt;span class="Constant"&gt;'2011-02-01'&lt;/span&gt;, &lt;span class="Constant"&gt;'GCIPP'&lt;/span&gt;);
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;As we can’t aggregate those values, we end up with something like this:&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;
&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="Statement"&gt;SELECT&lt;/span&gt;
&lt;span class="lnr"&gt; 2 &lt;/span&gt;  d.cat,
&lt;span class="lnr"&gt; 3 &lt;/span&gt;  j.val &lt;span class="Statement"&gt;AS&lt;/span&gt; january_val,
&lt;span class="lnr"&gt; 4 &lt;/span&gt;  f.val &lt;span class="Statement"&gt;AS&lt;/span&gt; february_val,
&lt;span class="lnr"&gt; 5 &lt;/span&gt;  m.val &lt;span class="Statement"&gt;AS&lt;/span&gt; march_val
&lt;span class="lnr"&gt; 6 &lt;/span&gt;&lt;span class="Statement"&gt;FROM&lt;/span&gt; (
&lt;span class="lnr"&gt; 7 &lt;/span&gt;  &lt;span class="Statement"&gt;SELECT&lt;/span&gt; &lt;span class="Statement"&gt;DISTINCT&lt;/span&gt; d.cat
&lt;span class="lnr"&gt; 8 &lt;/span&gt;  &lt;span class="Statement"&gt;FROM&lt;/span&gt; #data_b &lt;span class="Statement"&gt;AS&lt;/span&gt; d
&lt;span class="lnr"&gt; 9 &lt;/span&gt;) &lt;span class="Statement"&gt;AS&lt;/span&gt; d
&lt;span class="lnr"&gt;10 &lt;/span&gt;&lt;span class="Statement"&gt;LEFT&lt;/span&gt; &lt;span class="Statement"&gt;JOIN&lt;/span&gt; #data_b &lt;span class="Statement"&gt;AS&lt;/span&gt; j ON
&lt;span class="lnr"&gt;11 &lt;/span&gt;  j.cat = d.cat &lt;span class="Statement"&gt;AND&lt;/span&gt;
&lt;span class="lnr"&gt;12 &lt;/span&gt;  &lt;span class="Function"&gt;YEAR&lt;/span&gt;(j.mon) = &lt;span class="Function"&gt;YEAR&lt;/span&gt;(&lt;span class="Constant"&gt;CURRENT_TIMESTAMP&lt;/span&gt;) &lt;span class="Statement"&gt;AND&lt;/span&gt;
&lt;span class="lnr"&gt;13 &lt;/span&gt;  &lt;span class="Function"&gt;MONTH&lt;/span&gt;(j.mon) = &lt;span class="Constant"&gt;1&lt;/span&gt;
&lt;span class="lnr"&gt;14 &lt;/span&gt;&lt;span class="Statement"&gt;LEFT&lt;/span&gt; &lt;span class="Statement"&gt;JOIN&lt;/span&gt; #data_b &lt;span class="Statement"&gt;AS&lt;/span&gt; f ON
&lt;span class="lnr"&gt;15 &lt;/span&gt;  f.cat = d.cat &lt;span class="Statement"&gt;AND&lt;/span&gt;
&lt;span class="lnr"&gt;16 &lt;/span&gt;  &lt;span class="Function"&gt;YEAR&lt;/span&gt;(f.mon) = &lt;span class="Function"&gt;YEAR&lt;/span&gt;(&lt;span class="Constant"&gt;CURRENT_TIMESTAMP&lt;/span&gt;) &lt;span class="Statement"&gt;AND&lt;/span&gt;
&lt;span class="lnr"&gt;17 &lt;/span&gt;  &lt;span class="Function"&gt;MONTH&lt;/span&gt;(f.mon) = &lt;span class="Constant"&gt;2&lt;/span&gt;
&lt;span class="lnr"&gt;18 &lt;/span&gt;&lt;span class="Statement"&gt;LEFT&lt;/span&gt; &lt;span class="Statement"&gt;JOIN&lt;/span&gt; #data_b &lt;span class="Statement"&gt;AS&lt;/span&gt; m ON
&lt;span class="lnr"&gt;19 &lt;/span&gt;  m.cat = d.cat &lt;span class="Statement"&gt;AND&lt;/span&gt;
&lt;span class="lnr"&gt;20 &lt;/span&gt;  &lt;span class="Function"&gt;YEAR&lt;/span&gt;(m.mon) = &lt;span class="Function"&gt;YEAR&lt;/span&gt;(&lt;span class="Constant"&gt;CURRENT_TIMESTAMP&lt;/span&gt;) &lt;span class="Statement"&gt;AND&lt;/span&gt;
&lt;span class="lnr"&gt;21 &lt;/span&gt;  &lt;span class="Function"&gt;MONTH&lt;/span&gt;(m.mon) = &lt;span class="Constant"&gt;3&lt;/span&gt;
&lt;span class="lnr"&gt;22 &lt;/span&gt;&lt;span class="Statement"&gt;ORDER&lt;/span&gt; &lt;span class="Statement"&gt;BY&lt;/span&gt; d.cat;
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;Not pretty, but works fine and is very simple.&lt;/p&gt;

&lt;p&gt;Now to what I actually wanted to write down. While these three solutions work perfectly for some cases, they aren’t useful for others. What if you didn’t know the columns beforehand? Say, maybe you need to have a column for every day in a month? In one month you would have 31 column, in other 28 columns. Also, you have to have relative column names. In previous examples, you can’t name a column like “2011-01-01”, because that would work only for this year. That’s not a big problem with dates, but what if you’re moving user entered text into columns? It wouldn’t be possible to make sense of the result. So, here’s a decent solution for all that:&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;
&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="Statement"&gt;DECLARE&lt;/span&gt; @s &lt;span class="Type"&gt;varchar&lt;/span&gt;(&lt;span class="Function"&gt;MAX&lt;/span&gt;);
&lt;span class="lnr"&gt; 2 &lt;/span&gt;&lt;span class="Statement"&gt;DECLARE&lt;/span&gt; @j &lt;span class="Type"&gt;varchar&lt;/span&gt;(&lt;span class="Function"&gt;MAX&lt;/span&gt;);
&lt;span class="lnr"&gt; 3 &lt;/span&gt;
&lt;span class="lnr"&gt; 4 &lt;/span&gt;&lt;span class="Statement"&gt;SELECT&lt;/span&gt;
&lt;span class="lnr"&gt; 5 &lt;/span&gt;  @s = &lt;span class="Function"&gt;COALESCE&lt;/span&gt;(@s + &lt;span class="Constant"&gt;', '&lt;/span&gt;, &lt;span class="Constant"&gt;''&lt;/span&gt;) + &lt;span class="Constant"&gt;'['&lt;/span&gt; + t.col + &lt;span class="Constant"&gt;'].val AS ['&lt;/span&gt; + t.col + &lt;span class="Constant"&gt;']'&lt;/span&gt;,
&lt;span class="lnr"&gt; 6 &lt;/span&gt;  @j = &lt;span class="Function"&gt;COALESCE&lt;/span&gt;(@j + &lt;span class="Constant"&gt;' '&lt;/span&gt;, &lt;span class="Constant"&gt;''&lt;/span&gt;) + &lt;span class="Constant"&gt;'LEFT JOIN #data_b AS ['&lt;/span&gt; + t.col + &lt;span class="Constant"&gt;'] ON ['&lt;/span&gt; + t.col + &lt;span class="Constant"&gt;'].cat = d.cat AND ['&lt;/span&gt; + t.col + &lt;span class="Constant"&gt;'].mon = '''&lt;/span&gt; + &lt;span class="Function"&gt;CAST&lt;/span&gt;(t.m&lt;span class="Statement"&gt;on AS&lt;/span&gt; &lt;span class="Type"&gt;varchar&lt;/span&gt;) + &lt;span class="Constant"&gt;''''&lt;/span&gt;
&lt;span class="lnr"&gt; 7 &lt;/span&gt;&lt;span class="Statement"&gt;FROM&lt;/span&gt; (
&lt;span class="lnr"&gt; 8 &lt;/span&gt;  &lt;span class="Statement"&gt;SELECT&lt;/span&gt; &lt;span class="Statement"&gt;DISTINCT&lt;/span&gt;
&lt;span class="lnr"&gt; 9 &lt;/span&gt;    d.mon,
&lt;span class="lnr"&gt;10 &lt;/span&gt;    &lt;span class="Function"&gt;LOWER&lt;/span&gt;(&lt;span class="Function"&gt;DATENAME&lt;/span&gt;(&lt;span class="Function"&gt;MONTH&lt;/span&gt;, d.mon)) + &lt;span class="Constant"&gt;'_val'&lt;/span&gt; &lt;span class="Statement"&gt;AS&lt;/span&gt; col
&lt;span class="lnr"&gt;11 &lt;/span&gt;    &lt;span class="Statement"&gt;FROM&lt;/span&gt; #data_b &lt;span class="Statement"&gt;AS&lt;/span&gt; d
&lt;span class="lnr"&gt;12 &lt;/span&gt;    &lt;span class="Statement"&gt;WHERE&lt;/span&gt;
&lt;span class="lnr"&gt;13 &lt;/span&gt;      &lt;span class="Function"&gt;YEAR&lt;/span&gt;(d.mon) = &lt;span class="Function"&gt;YEAR&lt;/span&gt;(&lt;span class="Constant"&gt;CURRENT_TIMESTAMP&lt;/span&gt;) &lt;span class="Statement"&gt;AND&lt;/span&gt;
&lt;span class="lnr"&gt;14 &lt;/span&gt;      &lt;span class="Function"&gt;MONTH&lt;/span&gt;(d.mon) &lt;span class="Statement"&gt;IN&lt;/span&gt; (&lt;span class="Constant"&gt;1&lt;/span&gt;, &lt;span class="Constant"&gt;2&lt;/span&gt;, &lt;span class="Constant"&gt;3&lt;/span&gt;)
&lt;span class="lnr"&gt;15 &lt;/span&gt;) &lt;span class="Statement"&gt;AS&lt;/span&gt; t
&lt;span class="lnr"&gt;16 &lt;/span&gt;&lt;span class="Statement"&gt;ORDER&lt;/span&gt; &lt;span class="Statement"&gt;BY&lt;/span&gt; t.mon;
&lt;span class="lnr"&gt;17 &lt;/span&gt;
&lt;span class="lnr"&gt;18 &lt;/span&gt;&lt;span class="Function"&gt;EXEC&lt;/span&gt;(&lt;span class="Constant"&gt;'&lt;/span&gt;
&lt;span class="lnr"&gt;19 &lt;/span&gt;&lt;span class="Constant"&gt;  SELECT&lt;/span&gt;
&lt;span class="lnr"&gt;20 &lt;/span&gt;&lt;span class="Constant"&gt;    d.cat,&lt;/span&gt;
&lt;span class="lnr"&gt;21 &lt;/span&gt;&lt;span class="Constant"&gt;    '&lt;/span&gt; + @s + &lt;span class="Constant"&gt;'&lt;/span&gt;
&lt;span class="lnr"&gt;22 &lt;/span&gt;&lt;span class="Constant"&gt;  FROM (&lt;/span&gt;
&lt;span class="lnr"&gt;23 &lt;/span&gt;&lt;span class="Constant"&gt;    SELECT DISTINCT d.cat&lt;/span&gt;
&lt;span class="lnr"&gt;24 &lt;/span&gt;&lt;span class="Constant"&gt;    FROM #data_b AS d&lt;/span&gt;
&lt;span class="lnr"&gt;25 &lt;/span&gt;&lt;span class="Constant"&gt;  ) AS d&lt;/span&gt;
&lt;span class="lnr"&gt;26 &lt;/span&gt;&lt;span class="Constant"&gt;  '&lt;/span&gt; + @j + &lt;span class="Constant"&gt;'&lt;/span&gt;
&lt;span class="lnr"&gt;27 &lt;/span&gt;&lt;span class="Constant"&gt;  ORDER BY d.cat;&lt;/span&gt;
&lt;span class="lnr"&gt;28 &lt;/span&gt;&lt;span class="Constant"&gt;'&lt;/span&gt;);
&lt;/pre&gt;
&lt;/code&gt;

&lt;p&gt;I wouldn’t go as far as calling a dynamic &lt;abbr title="Structured Query Language"&gt;SQL&lt;/abbr&gt; solution elegant, but I do think it’s simple and easy to fallow. Basically, you just dynamically create a query similar to the third solution. The cute trick here is how &lt;code&gt;COALESCE()&lt;/code&gt; and &lt;code&gt;SELECT @foo =&lt;/code&gt; works, it concatenates each row into one string. No need to use ugly &lt;code&gt;WHILE&lt;/code&gt; loops, that I see everywhere. That’s it. &lt;abbr title="By The Way"&gt;BTW&lt;/abbr&gt;, as &lt;code&gt;EXEC()&lt;/code&gt; executes in it’s own context, to get data out of it, you may want to use a global temporary table.&lt;/p&gt;</description><link>http://blog.crt.lv/post/9924935760</link><guid>http://blog.crt.lv/post/9924935760</guid><pubDate>Wed, 07 Sep 2011 21:52:00 +0300</pubDate><category>SQL</category><category>SQL Server</category></item><item><title>Error Logging</title><description>&lt;p&gt;One of the very first things I do, for a new ASP.NET application, is to setup a decent error logging. I want to know when and why my application crashes and I don’t want to relay on users accurately reporting every error. It’s quite easy to do this using &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.httpapplication.error.aspx" title="HttpApplication.Error Event (System.Web)"&gt;&lt;code&gt;HttpApplication.Error&lt;/code&gt;&lt;/a&gt; event:&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;
&lt;span class="lnr"&gt;  1 &lt;/span&gt;&lt;span class="Statement"&gt;using&lt;/span&gt; System;
&lt;span class="lnr"&gt;  2 &lt;/span&gt;&lt;span class="Statement"&gt;using&lt;/span&gt; System.Configuration;
&lt;span class="lnr"&gt;  3 &lt;/span&gt;&lt;span class="Statement"&gt;using&lt;/span&gt; System.Data;
&lt;span class="lnr"&gt;  4 &lt;/span&gt;&lt;span class="Statement"&gt;using&lt;/span&gt; System.Data.SqlClient;
&lt;span class="lnr"&gt;  5 &lt;/span&gt;&lt;span class="Statement"&gt;using&lt;/span&gt; System.Security.Cryptography;
&lt;span class="lnr"&gt;  6 &lt;/span&gt;&lt;span class="Statement"&gt;using&lt;/span&gt; System.Text;
&lt;span class="lnr"&gt;  7 &lt;/span&gt;&lt;span class="Statement"&gt;using&lt;/span&gt; System.Web;
&lt;span class="lnr"&gt;  8 &lt;/span&gt;
&lt;span class="lnr"&gt;  9 &lt;/span&gt;
&lt;span class="lnr"&gt; 10 &lt;/span&gt;&lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;class&lt;/span&gt; Application : HttpApplication {
&lt;span class="lnr"&gt; 11 &lt;/span&gt;
&lt;span class="lnr"&gt; 12 &lt;/span&gt;  &lt;span class="Type"&gt;private&lt;/span&gt; String Md5Sum(String message) {
&lt;span class="lnr"&gt; 13 &lt;/span&gt;    var bytes = Encoding.UTF8.GetBytes(message);
&lt;span class="lnr"&gt; 14 &lt;/span&gt;    var digest = (&lt;span class="Statement"&gt;new&lt;/span&gt; MD5CryptoServiceProvider()).ComputeHash(bytes);
&lt;span class="lnr"&gt; 15 &lt;/span&gt;    var checksum = &lt;span class="Statement"&gt;new&lt;/span&gt; StringBuilder();
&lt;span class="lnr"&gt; 16 &lt;/span&gt;    &lt;span class="Statement"&gt;foreach&lt;/span&gt; (var b &lt;span class="Statement"&gt;in&lt;/span&gt; digest) {
&lt;span class="lnr"&gt; 17 &lt;/span&gt;      checksum.Append(b.ToString(&lt;span class="Constant"&gt;"X2"&lt;/span&gt;));
&lt;span class="lnr"&gt; 18 &lt;/span&gt;    }
&lt;span class="lnr"&gt; 19 &lt;/span&gt;    &lt;span class="Statement"&gt;return&lt;/span&gt; checksum.ToString();
&lt;span class="lnr"&gt; 20 &lt;/span&gt;  }
&lt;span class="lnr"&gt; 21 &lt;/span&gt;
&lt;span class="lnr"&gt; 22 &lt;/span&gt;  &lt;span class="Type"&gt;private&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; LogError(String checksum, Int32 httpCode, String type, String message, String stack, String source, String url, String user, String machine, String os, String version) {
&lt;span class="lnr"&gt; 23 &lt;/span&gt;    var connectionString = ConfigurationManager.ConnectionStrings[&lt;span class="Constant"&gt;"DB"&lt;/span&gt;].ConnectionString;
&lt;span class="lnr"&gt; 24 &lt;/span&gt;    &lt;span class="Statement"&gt;using&lt;/span&gt; (var connection = &lt;span class="Statement"&gt;new&lt;/span&gt; SqlConnection(connectionString)) {
&lt;span class="lnr"&gt; 25 &lt;/span&gt;      connection.Open();
&lt;span class="lnr"&gt; 26 &lt;/span&gt;      var command = connection.CreateCommand();
&lt;span class="lnr"&gt; 27 &lt;/span&gt;      command.CommandText = &lt;span class="Special"&gt;@&lt;/span&gt;&lt;span class="Constant"&gt;"&lt;/span&gt;
&lt;span class="lnr"&gt; 28 &lt;/span&gt;        &lt;span class="Constant"&gt;UPDATE errors&lt;/span&gt;
&lt;span class="lnr"&gt; 29 &lt;/span&gt;        &lt;span class="Constant"&gt;SET&lt;/span&gt;
&lt;span class="lnr"&gt; 30 &lt;/span&gt;          &lt;span class="Constant"&gt;last_occurrence = current_timestamp,&lt;/span&gt;
&lt;span class="lnr"&gt; 31 &lt;/span&gt;          &lt;span class="Constant"&gt;occurrences = occurrences + &lt;span class="Constant"&gt;1&lt;/span&gt;,&lt;/span&gt;
&lt;span class="lnr"&gt; 32 &lt;/span&gt;          &lt;span class="Constant"&gt;http_code = @http_code,&lt;/span&gt;
&lt;span class="lnr"&gt; 33 &lt;/span&gt;          &lt;span class="Constant"&gt;type = @type,&lt;/span&gt;
&lt;span class="lnr"&gt; 34 &lt;/span&gt;          &lt;span class="Constant"&gt;message = @message,&lt;/span&gt;
&lt;span class="lnr"&gt; 35 &lt;/span&gt;          &lt;span class="Constant"&gt;source = @source,&lt;/span&gt;
&lt;span class="lnr"&gt; 36 &lt;/span&gt;          &lt;span class="Constant"&gt;url = @url,&lt;/span&gt;
&lt;span class="lnr"&gt; 37 &lt;/span&gt;          &lt;span class="Constant"&gt;[user] = @user,&lt;/span&gt;
&lt;span class="lnr"&gt; 38 &lt;/span&gt;          &lt;span class="Constant"&gt;machine = @machine,&lt;/span&gt;
&lt;span class="lnr"&gt; 39 &lt;/span&gt;          &lt;span class="Constant"&gt;os = @os,&lt;/span&gt;
&lt;span class="lnr"&gt; 40 &lt;/span&gt;          &lt;span class="Constant"&gt;version = @version&lt;/span&gt;
&lt;span class="lnr"&gt; 41 &lt;/span&gt;        &lt;span class="Constant"&gt;WHERE&lt;/span&gt;
&lt;span class="lnr"&gt; 42 &lt;/span&gt;          &lt;span class="Constant"&gt;checksum = @checksum;&lt;/span&gt;
&lt;span class="lnr"&gt; 43 &lt;/span&gt;      &lt;span class="Constant"&gt;";&lt;/span&gt;
&lt;span class="lnr"&gt; 44 &lt;/span&gt;      command.Parameters.Add(&lt;span class="Constant"&gt;"http_code"&lt;/span&gt;, SqlDbType.SmallInt).Value = httpCode;
&lt;span class="lnr"&gt; 45 &lt;/span&gt;      command.Parameters.Add(&lt;span class="Constant"&gt;"type"&lt;/span&gt;, SqlDbType.VarChar, &lt;span class="Constant"&gt;250&lt;/span&gt;).Value = type;
&lt;span class="lnr"&gt; 46 &lt;/span&gt;      command.Parameters.Add(&lt;span class="Constant"&gt;"message"&lt;/span&gt;, SqlDbType.VarChar, &lt;span class="Constant"&gt;1000&lt;/span&gt;).Value = message;
&lt;span class="lnr"&gt; 47 &lt;/span&gt;      command.Parameters.Add(&lt;span class="Constant"&gt;"source"&lt;/span&gt;, SqlDbType.VarChar, &lt;span class="Constant"&gt;100&lt;/span&gt;).Value = source;
&lt;span class="lnr"&gt; 48 &lt;/span&gt;      command.Parameters.Add(&lt;span class="Constant"&gt;"url"&lt;/span&gt;, SqlDbType.VarChar, &lt;span class="Constant"&gt;150&lt;/span&gt;).Value = url;
&lt;span class="lnr"&gt; 49 &lt;/span&gt;      command.Parameters.Add(&lt;span class="Constant"&gt;"user"&lt;/span&gt;, SqlDbType.VarChar, &lt;span class="Constant"&gt;50&lt;/span&gt;).Value = user;
&lt;span class="lnr"&gt; 50 &lt;/span&gt;      command.Parameters.Add(&lt;span class="Constant"&gt;"machine"&lt;/span&gt;, SqlDbType.VarChar, &lt;span class="Constant"&gt;50&lt;/span&gt;).Value = machine;
&lt;span class="lnr"&gt; 51 &lt;/span&gt;      command.Parameters.Add(&lt;span class="Constant"&gt;"os"&lt;/span&gt;, SqlDbType.VarChar, &lt;span class="Constant"&gt;100&lt;/span&gt;).Value = os;
&lt;span class="lnr"&gt; 52 &lt;/span&gt;      command.Parameters.Add(&lt;span class="Constant"&gt;"version"&lt;/span&gt;, SqlDbType.VarChar, &lt;span class="Constant"&gt;100&lt;/span&gt;).Value = version;
&lt;span class="lnr"&gt; 53 &lt;/span&gt;      command.Parameters.Add(&lt;span class="Constant"&gt;"checksum"&lt;/span&gt;, SqlDbType.VarChar, &lt;span class="Constant"&gt;32&lt;/span&gt;).Value = checksum;
&lt;span class="lnr"&gt; 54 &lt;/span&gt;      &lt;span class="Statement"&gt;if&lt;/span&gt; (command.ExecuteNonQuery() == &lt;span class="Constant"&gt;0&lt;/span&gt;) {
&lt;span class="lnr"&gt; 55 &lt;/span&gt;        command.CommandText = &lt;span class="Special"&gt;@&lt;/span&gt;&lt;span class="Constant"&gt;"&lt;/span&gt;
&lt;span class="lnr"&gt; 56 &lt;/span&gt;          &lt;span class="Constant"&gt;INSERT INTO errors (checksum, http_code, type, message, stack, source, url, [user], machine, os, version)&lt;/span&gt;
&lt;span class="lnr"&gt; 57 &lt;/span&gt;          &lt;span class="Constant"&gt;VALUES (@checksum, @http_code, @type, @message, @stack, @source, @url, @user, @machine, @os, @version);&lt;/span&gt;
&lt;span class="lnr"&gt; 58 &lt;/span&gt;        &lt;span class="Constant"&gt;";&lt;/span&gt;
&lt;span class="lnr"&gt; 59 &lt;/span&gt;        command.Parameters.Add(&lt;span class="Constant"&gt;"stack"&lt;/span&gt;, SqlDbType.Text).Value = stack;
&lt;span class="lnr"&gt; 60 &lt;/span&gt;        command.ExecuteNonQuery();
&lt;span class="lnr"&gt; 61 &lt;/span&gt;      }
&lt;span class="lnr"&gt; 62 &lt;/span&gt;    }
&lt;span class="lnr"&gt; 63 &lt;/span&gt;  }
&lt;span class="lnr"&gt; 64 &lt;/span&gt;
&lt;span class="lnr"&gt; 65 &lt;/span&gt;  &lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; Application_Error(Object sender, EventArgs e) {
&lt;span class="lnr"&gt; 66 &lt;/span&gt;    Server.ClearError();
&lt;span class="lnr"&gt; 67 &lt;/span&gt;    Response.Clear();
&lt;span class="lnr"&gt; 68 &lt;/span&gt;    var exception = Server.GetLastError().GetBaseException();
&lt;span class="lnr"&gt; 69 &lt;/span&gt;    var stack = exception.StackTrace;
&lt;span class="lnr"&gt; 70 &lt;/span&gt;    var checksum = Md5Sum(stack);
&lt;span class="lnr"&gt; 71 &lt;/span&gt;    var httpCode = ((HttpException)Server.GetLastError()).GetHttpCode();
&lt;span class="lnr"&gt; 72 &lt;/span&gt;    var httpMessage = Response.StatusDescription;
&lt;span class="lnr"&gt; 73 &lt;/span&gt;    var type = exception.GetType().ToString();
&lt;span class="lnr"&gt; 74 &lt;/span&gt;    var message = exception.Message;
&lt;span class="lnr"&gt; 75 &lt;/span&gt;    var source = exception.Source;
&lt;span class="lnr"&gt; 76 &lt;/span&gt;    var url = Request.Path;
&lt;span class="lnr"&gt; 77 &lt;/span&gt;    var user = Environment.UserName;
&lt;span class="lnr"&gt; 78 &lt;/span&gt;    &lt;span class="Comment"&gt;//var user = Request.ServerVariables["AUTH_USER"];&lt;/span&gt;
&lt;span class="lnr"&gt; 79 &lt;/span&gt;    var machine = Environment.MachineName;
&lt;span class="lnr"&gt; 80 &lt;/span&gt;    var os = Environment.OSVersion.ToString();
&lt;span class="lnr"&gt; 81 &lt;/span&gt;    var version = Environment.Version.ToString();
&lt;span class="lnr"&gt; 82 &lt;/span&gt;    var dateTime = DateTime.UtcNow.ToString(&lt;span class="Constant"&gt;"o"&lt;/span&gt;);
&lt;span class="lnr"&gt; 83 &lt;/span&gt;    var details = &lt;span class="Constant"&gt;""&lt;/span&gt;;
&lt;span class="lnr"&gt; 84 &lt;/span&gt;    var developers = ConfigurationManager.AppSettings[&lt;span class="Constant"&gt;"Developers"&lt;/span&gt;].Split(&lt;span class="Constant"&gt;';'&lt;/span&gt;);
&lt;span class="lnr"&gt; 85 &lt;/span&gt;    &lt;span class="Comment"&gt;//if (Array.IndexOf(developers, Request.ServerVariables["REMOTE_ADDR"]) &gt; -1) {&lt;/span&gt;
&lt;span class="lnr"&gt; 86 &lt;/span&gt;    &lt;span class="Statement"&gt;if&lt;/span&gt; (Array.IndexOf(developers, user) &gt; -&lt;span class="Constant"&gt;1&lt;/span&gt;) {
&lt;span class="lnr"&gt; 87 &lt;/span&gt;      details = String.Format(&lt;span class="Special"&gt;@&lt;/span&gt;&lt;span class="Constant"&gt;"&lt;/span&gt;
&lt;span class="lnr"&gt; 88 &lt;/span&gt;        &lt;span class="Constant"&gt;&lt;p&gt;[&lt;b&gt;{0}&lt;/b&gt;: {1}]&lt;/p&gt;&lt;/span&gt;
&lt;span class="lnr"&gt; 89 &lt;/span&gt;        &lt;span class="Constant"&gt;&lt;pre&gt;&lt;code&gt;{2}&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;
&lt;span class="lnr"&gt; 90 &lt;/span&gt;        &lt;span class="Constant"&gt;&lt;hr/&gt;&lt;/span&gt;
&lt;span class="lnr"&gt; 91 &lt;/span&gt;        &lt;span class="Constant"&gt;&lt;p&gt;{3} ({4}), {5}&lt;i&gt; -- {6} @ {7} ({8}/{9})&lt;/i&gt;&lt;/p&gt;&lt;/span&gt;
&lt;span class="lnr"&gt; 92 &lt;/span&gt;      &lt;span class="Constant"&gt;"&lt;/span&gt;, type, message, stack, source, url, dateTime, user, machine, os, version);
&lt;span class="lnr"&gt; 93 &lt;/span&gt;    }
&lt;span class="lnr"&gt; 94 &lt;/span&gt;    var page = String.Format(&lt;span class="Special"&gt;@&lt;/span&gt;&lt;span class="Constant"&gt;"&lt;/span&gt;
&lt;span class="lnr"&gt; 95 &lt;/span&gt;      &lt;span class="Constant"&gt;&lt;?xml version=""1.0"" encoding=""UTF-8""?&gt;&lt;/span&gt;
&lt;span class="lnr"&gt; 96 &lt;/span&gt;      &lt;span class="Constant"&gt;&lt;!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.1//EN"" ""http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd""&gt;&lt;/span&gt;
&lt;span class="lnr"&gt; 97 &lt;/span&gt;      &lt;span class="Constant"&gt;&lt;html xmlns=""http://www.w3.org/1999/xhtml"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xsi:schemaLocation=""http://www.w3.org/MarkUp/SCHEMA/xhtml11.xsd"" xml:lang=""en""&gt;&lt;/span&gt;
&lt;span class="lnr"&gt; 98 &lt;/span&gt;        &lt;span class="Constant"&gt;&lt;head&gt;&lt;/span&gt;
&lt;span class="lnr"&gt; 99 &lt;/span&gt;          &lt;span class="Constant"&gt;&lt;title&gt;{0} - {1}&lt;/title&gt;&lt;/span&gt;
&lt;span class="lnr"&gt;100 &lt;/span&gt;        &lt;span class="Constant"&gt;&lt;/head&gt;&lt;/span&gt;
&lt;span class="lnr"&gt;101 &lt;/span&gt;        &lt;span class="Constant"&gt;&lt;body style=""font-size:smaller;""&gt;&lt;/span&gt;
&lt;span class="lnr"&gt;102 &lt;/span&gt;          &lt;span class="Constant"&gt;&lt;p style=""text-align:center;color:white;background:orangered;""&gt;&lt;b&gt;{2}&lt;/b&gt;&lt;/p&gt;&lt;/span&gt;
&lt;span class="lnr"&gt;103 &lt;/span&gt;          &lt;span class="Constant"&gt;{3}&lt;/span&gt;
&lt;span class="lnr"&gt;104 &lt;/span&gt;        &lt;span class="Constant"&gt;&lt;/body&gt;&lt;/span&gt;
&lt;span class="lnr"&gt;105 &lt;/span&gt;      &lt;span class="Constant"&gt;&lt;/html&gt;&lt;/span&gt;
&lt;span class="lnr"&gt;106 &lt;/span&gt;    &lt;span class="Constant"&gt;"&lt;/span&gt;, httpCode, httpMessage, checksum, details);
&lt;span class="lnr"&gt;107 &lt;/span&gt;    Response.Write(page);
&lt;span class="lnr"&gt;108 &lt;/span&gt;    Response.StatusCode = httpCode;
&lt;span class="lnr"&gt;109 &lt;/span&gt;    LogError(checksum, httpCode, type, message, stack, source, url, user, machine, os, version);
&lt;span class="lnr"&gt;110 &lt;/span&gt;  }
&lt;span class="lnr"&gt;111 &lt;/span&gt;
&lt;span class="lnr"&gt;112 &lt;/span&gt;}
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;You could put these methods directly into &lt;code&gt;global.asax&lt;/code&gt;, but I prefer to compile and drop the &lt;abbr title="Dynamic-Link Library"&gt;DLL&lt;/abbr&gt; into &lt;code&gt;/bin&lt;/code&gt;, or to save everything as a file with &lt;code&gt;.cs&lt;/code&gt; extension into &lt;code&gt;/app_code&lt;/code&gt;. Two later cases requires this one line in &lt;code&gt;global.asax&lt;/code&gt;:&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;
&lt;span class="lnr"&gt;1 &lt;/span&gt;&lt;span class="Special"&gt;&lt;%&lt;/span&gt;@ &lt;span class="Identifier"&gt;Inherits&lt;/span&gt;=&lt;span class="Constant"&gt;"&lt;/span&gt;&lt;span class="Constant"&gt;Application&lt;/span&gt;&lt;span class="Constant"&gt;"&lt;/span&gt; &lt;span class="Special"&gt;%&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;It’s probably not a good idea to display error details to every user, just a checksum should be enough, so we’ll put users that need to see full errors into &lt;code&gt;web.config&lt;/code&gt;:&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;
&lt;span class="lnr"&gt;1 &lt;/span&gt;&lt;span class="Comment"&gt;&lt;?&lt;/span&gt;&lt;span class="Type"&gt;xml&lt;/span&gt;&lt;span class="Type"&gt; &lt;/span&gt;&lt;span class="Type"&gt;version&lt;/span&gt;=&lt;span class="Constant"&gt;"1.0"&lt;/span&gt;&lt;span class="Type"&gt; &lt;/span&gt;&lt;span class="Type"&gt;encoding&lt;/span&gt;=&lt;span class="Constant"&gt;"utf-8"&lt;/span&gt;&lt;span class="Comment"&gt;?&gt;&lt;/span&gt;
&lt;span class="lnr"&gt;2 &lt;/span&gt;&lt;configuration&gt;
&lt;span class="lnr"&gt;3 &lt;/span&gt;  &lt;appSettings&gt;
&lt;span class="lnr"&gt;4 &lt;/span&gt;    &lt;add &lt;span class="Type"&gt;key&lt;/span&gt;=&lt;span class="Constant"&gt;"Developers"&lt;/span&gt; &lt;span class="Type"&gt;value&lt;/span&gt;=&lt;span class="Constant"&gt;"Alice;Bob"&lt;/span&gt; /&gt;
&lt;span class="lnr"&gt;5 &lt;/span&gt;  &lt;/appSettings&gt;
&lt;span class="lnr"&gt;6 &lt;/span&gt;&lt;/configuration&gt;
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;One tricky thing about all this, is exceptions thrown from &lt;code&gt;Application_Error()&lt;/code&gt; method. It would make sense, if these exceptions would show up as regular ASP.NET errors, but that’s not how it works in my experience. To show our own error page, we need to clear the error that resulted in &lt;code&gt;Application_Error()&lt;/code&gt; being called, if we don’t call &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.httpserverutility.clearerror.aspx" title="HttpServerUtility.ClearError Method  (System.Web)"&gt;&lt;code&gt;ClearError()&lt;/code&gt;&lt;/a&gt;, the original error will get displayed instead of our own, this also means that, if an exception gets thrown before &lt;code&gt;ClearError()&lt;/code&gt;, you won’t see it. Situation with exceptions after &lt;code&gt;ClearError()&lt;/code&gt; is a bit mysterious, on .NET I get a blank page, on Mono I get a regular ASP.NET error. Just know that, if something isn’t working as expected, first thing to try is to wrap everything in &lt;code&gt;try-catch&lt;/code&gt;, to see if there’s any hidden exceptions.&lt;/p&gt;

&lt;p&gt;Here’s the table definition, if you decide to use something similar:&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;
&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="Statement"&gt;CREATE TABLE&lt;/span&gt; errors (
&lt;span class="lnr"&gt; 2 &lt;/span&gt;  id &lt;span class="Type"&gt;smallint&lt;/span&gt; &lt;span class="Statement"&gt;IDENTITY&lt;/span&gt; &lt;span class="Statement"&gt;NOT&lt;/span&gt; &lt;span class="Statement"&gt;NULL&lt;/span&gt;,
&lt;span class="lnr"&gt; 3 &lt;/span&gt;  checksum &lt;span class="Type"&gt;char&lt;/span&gt;(&lt;span class="Constant"&gt;32&lt;/span&gt;) &lt;span class="Statement"&gt;NOT&lt;/span&gt; &lt;span class="Statement"&gt;NULL&lt;/span&gt; &lt;span class="Statement"&gt;UNIQUE&lt;/span&gt;,
&lt;span class="lnr"&gt; 4 &lt;/span&gt;  last_occurrence &lt;span class="Type"&gt;smalldatetime&lt;/span&gt; &lt;span class="Statement"&gt;NOT&lt;/span&gt; &lt;span class="Statement"&gt;NULL&lt;/span&gt; &lt;span class="Statement"&gt;DEFAULT&lt;/span&gt; &lt;span class="Statement"&gt;current_timestamp&lt;/span&gt;,
&lt;span class="lnr"&gt; 5 &lt;/span&gt;  occurrences &lt;span class="Type"&gt;int&lt;/span&gt; &lt;span class="Statement"&gt;NOT&lt;/span&gt; &lt;span class="Statement"&gt;NULL&lt;/span&gt; &lt;span class="Statement"&gt;DEFAULT&lt;/span&gt; &lt;span class="Constant"&gt;1&lt;/span&gt;,
&lt;span class="lnr"&gt; 6 &lt;/span&gt;  http_code &lt;span class="Type"&gt;smallint&lt;/span&gt; &lt;span class="Statement"&gt;NOT&lt;/span&gt; &lt;span class="Statement"&gt;NULL&lt;/span&gt;,
&lt;span class="lnr"&gt; 7 &lt;/span&gt;  type &lt;span class="Type"&gt;varchar&lt;/span&gt;(&lt;span class="Constant"&gt;250&lt;/span&gt;) &lt;span class="Statement"&gt;NOT&lt;/span&gt; &lt;span class="Statement"&gt;NULL&lt;/span&gt;,
&lt;span class="lnr"&gt; 8 &lt;/span&gt;  message &lt;span class="Type"&gt;varchar&lt;/span&gt;(&lt;span class="Constant"&gt;1000&lt;/span&gt;) &lt;span class="Statement"&gt;NOT&lt;/span&gt; &lt;span class="Statement"&gt;NULL&lt;/span&gt;,
&lt;span class="lnr"&gt; 9 &lt;/span&gt;  stack &lt;span class="Type"&gt;text&lt;/span&gt; &lt;span class="Statement"&gt;NOT&lt;/span&gt; &lt;span class="Statement"&gt;NULL&lt;/span&gt;,
&lt;span class="lnr"&gt;10 &lt;/span&gt;  source &lt;span class="Type"&gt;varchar&lt;/span&gt;(&lt;span class="Constant"&gt;100&lt;/span&gt;) &lt;span class="Statement"&gt;NOT&lt;/span&gt; &lt;span class="Statement"&gt;NULL&lt;/span&gt;,
&lt;span class="lnr"&gt;11 &lt;/span&gt;  url &lt;span class="Type"&gt;varchar&lt;/span&gt;(&lt;span class="Constant"&gt;150&lt;/span&gt;) &lt;span class="Statement"&gt;NOT&lt;/span&gt; &lt;span class="Statement"&gt;NULL&lt;/span&gt;,
&lt;span class="lnr"&gt;12 &lt;/span&gt;  [user] &lt;span class="Type"&gt;varchar&lt;/span&gt;(&lt;span class="Constant"&gt;50&lt;/span&gt;) &lt;span class="Statement"&gt;NOT&lt;/span&gt; &lt;span class="Statement"&gt;NULL&lt;/span&gt;,
&lt;span class="lnr"&gt;13 &lt;/span&gt;  machine &lt;span class="Type"&gt;varchar&lt;/span&gt;(&lt;span class="Constant"&gt;50&lt;/span&gt;) &lt;span class="Statement"&gt;NOT&lt;/span&gt; &lt;span class="Statement"&gt;NULL&lt;/span&gt;,
&lt;span class="lnr"&gt;14 &lt;/span&gt;  os &lt;span class="Type"&gt;varchar&lt;/span&gt;(&lt;span class="Constant"&gt;100&lt;/span&gt;) &lt;span class="Statement"&gt;NOT&lt;/span&gt; &lt;span class="Statement"&gt;NULL&lt;/span&gt;,
&lt;span class="lnr"&gt;15 &lt;/span&gt;  version &lt;span class="Type"&gt;varchar&lt;/span&gt;(&lt;span class="Constant"&gt;100&lt;/span&gt;) &lt;span class="Statement"&gt;NOT&lt;/span&gt; &lt;span class="Statement"&gt;NULL&lt;/span&gt;,
&lt;span class="lnr"&gt;16 &lt;/span&gt;  &lt;span class="Statement"&gt;CONSTRAINT&lt;/span&gt; PK_errors &lt;span class="Statement"&gt;PRIMARY&lt;/span&gt; &lt;span class="Statement"&gt;KEY&lt;/span&gt; &lt;span class="Statement"&gt;CLUSTERED&lt;/span&gt; (id)
&lt;span class="lnr"&gt;17 &lt;/span&gt;);
&lt;/pre&gt;&lt;/code&gt;</description><link>http://blog.crt.lv/post/435553887</link><guid>http://blog.crt.lv/post/435553887</guid><pubDate>Tue, 09 Mar 2010 02:00:00 +0200</pubDate><category>C Sharp</category><category>.NET</category><category>Mono</category><category>ASP.NET</category></item><item><title>Undo Tree</title><description>&lt;p&gt;A while ago, when I played around with &lt;a href="http://www.e-texteditor.com/" title="E Text Editor | The Power of Textmate on Windows"&gt;E Text Editor&lt;/a&gt;, I was impressed by what they call a “Personal Revision Control”. It’s a nice concept, where instead of linear list of changes, which you can undo and redo, you can have branches.&lt;/p&gt;
&lt;p&gt;For example, if you type “one”, then change it to “two”, then undo back to “one” and change it to “three”. In a typical text editor, now you would be able to go back to “one”, but not “two”. With E, you could switch between all changes, because it creates a new branch, when you go back and add a change.&lt;/p&gt;
&lt;p&gt;Recently I discovered that Vim has had a feature like this (sans the pretty &lt;abbr title="User Interface"&gt;UI&lt;/abbr&gt;) for a long time, it’s called “undo tree”. Check out the &lt;a href="http://vimdoc.sourceforge.net/htmldoc/usr_32.html" title="Vim documentation: usr_32"&gt;documentation&lt;/a&gt;, but basically you can view branches with &lt;code&gt;:undolist&lt;/code&gt; and time travel with &lt;code&gt;:earlier&lt;/code&gt; and &lt;code&gt;:later&lt;/code&gt;.&lt;/p&gt;</description><link>http://blog.crt.lv/post/407488862</link><guid>http://blog.crt.lv/post/407488862</guid><pubDate>Tue, 23 Feb 2010 22:25:43 +0200</pubDate><category>Vim</category></item><item><title>Objects</title><description>&lt;p&gt;Trying to understand how objects work in JavaScript can be confusing, not because it’s complicated or difficult, but because the language is flexible enough to allow different approaches and also because many programmers simply aren’t familiar with &lt;a href="http://en.wikipedia.org/wiki/Prototype-based_programming" title="Prototype-based programming - Wikipedia, the free encyclopedia"&gt;prototype-based programming&lt;/a&gt;. I’ll try to demonstrate, what I think is the simplest and cleanest way to work with objects in JavaScript. You can simply copy, paste and run in &lt;a href="http://getfirebug.com/" title="The most popular web development tool for Firefox"&gt;Firebug&lt;/a&gt; all of the following code.&lt;/p&gt;

&lt;p&gt;So, lets define our own object, with one property and a method:&lt;/p&gt;
&lt;code&gt;&lt;pre&gt;
&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="Identifier"&gt;var&lt;/span&gt; Box = &lt;span class="Function"&gt;function&lt;/span&gt;() &lt;span class="Function"&gt;{&lt;/span&gt;
&lt;span class="lnr"&gt; 2 &lt;/span&gt;
&lt;span class="lnr"&gt; 3 &lt;/span&gt;  &lt;span class="Identifier"&gt;this&lt;/span&gt;.element = &lt;span class="Statement"&gt;null&lt;/span&gt;;
&lt;span class="lnr"&gt; 4 &lt;/span&gt;
&lt;span class="lnr"&gt; 5 &lt;/span&gt;  &lt;span class="Identifier"&gt;this&lt;/span&gt;.create = &lt;span class="Function"&gt;function&lt;/span&gt;() &lt;span class="Function"&gt;{&lt;/span&gt;
&lt;span class="lnr"&gt; 6 &lt;/span&gt;    &lt;span class="Statement"&gt;if&lt;/span&gt; (!&lt;span class="Identifier"&gt;this&lt;/span&gt;.element) &lt;span class="Function"&gt;{&lt;/span&gt;
&lt;span class="lnr"&gt; 7 &lt;/span&gt;      &lt;span class="Identifier"&gt;this&lt;/span&gt;.element = &lt;span class="Statement"&gt;document&lt;/span&gt;.createElement(&lt;span class="Constant"&gt;'div'&lt;/span&gt;);
&lt;span class="lnr"&gt; 8 &lt;/span&gt;      &lt;span class="Statement"&gt;with&lt;/span&gt; (&lt;span class="Identifier"&gt;this&lt;/span&gt;.element.style) &lt;span class="Function"&gt;{&lt;/span&gt;
&lt;span class="lnr"&gt; 9 &lt;/span&gt;        position = &lt;span class="Constant"&gt;'absolute'&lt;/span&gt;;
&lt;span class="lnr"&gt;10 &lt;/span&gt;        width = &lt;span class="Constant"&gt;'100px'&lt;/span&gt;;
&lt;span class="lnr"&gt;11 &lt;/span&gt;        height = &lt;span class="Constant"&gt;'100px'&lt;/span&gt;;
&lt;span class="lnr"&gt;12 &lt;/span&gt;        top = &lt;span class="Constant"&gt;'0'&lt;/span&gt;;
&lt;span class="lnr"&gt;13 &lt;/span&gt;        left = &lt;span class="Constant"&gt;'0'&lt;/span&gt;;
&lt;span class="lnr"&gt;14 &lt;/span&gt;        backgroundColor = &lt;span class="Constant"&gt;'deepskyblue'&lt;/span&gt;;
&lt;span class="lnr"&gt;15 &lt;/span&gt;        border = &lt;span class="Constant"&gt;'1px solid dodgerblue'&lt;/span&gt;;
&lt;span class="lnr"&gt;16 &lt;/span&gt;      &lt;span class="Function"&gt;}&lt;/span&gt;
&lt;span class="lnr"&gt;17 &lt;/span&gt;      &lt;span class="Statement"&gt;document&lt;/span&gt;.body.appendChild(&lt;span class="Identifier"&gt;this&lt;/span&gt;.element);
&lt;span class="lnr"&gt;18 &lt;/span&gt;    &lt;span class="Function"&gt;}&lt;/span&gt;
&lt;span class="lnr"&gt;19 &lt;/span&gt;  &lt;span class="Function"&gt;}&lt;/span&gt;;
&lt;span class="lnr"&gt;20 &lt;/span&gt;
&lt;span class="lnr"&gt;21 &lt;/span&gt;&lt;span class="Function"&gt;}&lt;/span&gt;;
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;Now you can instantiate this &lt;code&gt;Box&lt;/code&gt; with:&lt;/p&gt;
&lt;code&gt;&lt;pre&gt;
&lt;span class="lnr"&gt;1 &lt;/span&gt;&lt;span class="Identifier"&gt;var&lt;/span&gt; myBox = &lt;span class="Statement"&gt;new&lt;/span&gt; Box();
&lt;span class="lnr"&gt;2 &lt;/span&gt;myBox.create();
&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;What’s nice is that you can extend it at any time, for example, if we wanted to, not only create, but also remove boxes:&lt;/p&gt;
&lt;code&gt;&lt;pre&gt;
&lt;span class="lnr"&gt;1 &lt;/span&gt;Box.prototype.destroy = &lt;span class="Function"&gt;function&lt;/span&gt;() &lt;span class="Function"&gt;{&lt;/span&gt;
&lt;span class="lnr"&gt;2 &lt;/span&gt;  &lt;span class="Statement"&gt;if&lt;/span&gt; (&lt;span class="Identifier"&gt;this&lt;/span&gt;.element) &lt;span class="Function"&gt;{&lt;/span&gt;
&lt;span class="lnr"&gt;3 &lt;/span&gt;    &lt;span class="Identifier"&gt;this&lt;/span&gt;.element.parentNode.removeChild(&lt;span class="Identifier"&gt;this&lt;/span&gt;.element);
&lt;span class="lnr"&gt;4 &lt;/span&gt;    &lt;span class="Identifier"&gt;this&lt;/span&gt;.element = &lt;span class="Statement"&gt;null&lt;/span&gt;;
&lt;span class="lnr"&gt;5 &lt;/span&gt;  &lt;span class="Function"&gt;}&lt;/span&gt;
&lt;span class="lnr"&gt;6 &lt;/span&gt;&lt;span class="Function"&gt;}&lt;/span&gt;
&lt;span class="lnr"&gt;7 &lt;/span&gt;myBox.destroy();
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;And inheritance isn’t difficult either - here’s how to create &lt;code&gt;Circle&lt;/code&gt; that inherits properties and methods from &lt;code&gt;Box&lt;/code&gt; and also we’ll override &lt;code&gt;create&lt;/code&gt; method:&lt;/p&gt;
&lt;code&gt;&lt;pre&gt;
&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="Identifier"&gt;var&lt;/span&gt; Circle = &lt;span class="Function"&gt;function&lt;/span&gt;() &lt;span class="Function"&gt;{&lt;/span&gt;
&lt;span class="lnr"&gt; 2 &lt;/span&gt;
&lt;span class="lnr"&gt; 3 &lt;/span&gt;  &lt;span class="Identifier"&gt;this&lt;/span&gt;.create = &lt;span class="Function"&gt;function&lt;/span&gt;() &lt;span class="Function"&gt;{&lt;/span&gt;
&lt;span class="lnr"&gt; 4 &lt;/span&gt;    &lt;span class="Statement"&gt;if&lt;/span&gt; (!&lt;span class="Identifier"&gt;this&lt;/span&gt;.element) &lt;span class="Function"&gt;{&lt;/span&gt;
&lt;span class="lnr"&gt; 5 &lt;/span&gt;      &lt;span class="Identifier"&gt;this&lt;/span&gt;.element = &lt;span class="Statement"&gt;document&lt;/span&gt;.createElement(&lt;span class="Constant"&gt;'div'&lt;/span&gt;);
&lt;span class="lnr"&gt; 6 &lt;/span&gt;      &lt;span class="Statement"&gt;with&lt;/span&gt; (&lt;span class="Identifier"&gt;this&lt;/span&gt;.element.style) &lt;span class="Function"&gt;{&lt;/span&gt;
&lt;span class="lnr"&gt; 7 &lt;/span&gt;        position = &lt;span class="Constant"&gt;'absolute'&lt;/span&gt;;
&lt;span class="lnr"&gt; 8 &lt;/span&gt;        width = &lt;span class="Constant"&gt;'100px'&lt;/span&gt;;
&lt;span class="lnr"&gt; 9 &lt;/span&gt;        height = &lt;span class="Constant"&gt;'100px'&lt;/span&gt;;
&lt;span class="lnr"&gt;10 &lt;/span&gt;        top = &lt;span class="Constant"&gt;'0'&lt;/span&gt;;
&lt;span class="lnr"&gt;11 &lt;/span&gt;        left = &lt;span class="Constant"&gt;'0'&lt;/span&gt;;
&lt;span class="lnr"&gt;12 &lt;/span&gt;        MozBorderRadius = &lt;span class="Constant"&gt;'50px'&lt;/span&gt;;
&lt;span class="lnr"&gt;13 &lt;/span&gt;        WebkitBorderRadius = &lt;span class="Constant"&gt;'50px'&lt;/span&gt;;
&lt;span class="lnr"&gt;14 &lt;/span&gt;        backgroundColor = &lt;span class="Constant"&gt;'hotpink'&lt;/span&gt;;
&lt;span class="lnr"&gt;15 &lt;/span&gt;        border = &lt;span class="Constant"&gt;'1px solid red'&lt;/span&gt;;
&lt;span class="lnr"&gt;16 &lt;/span&gt;      &lt;span class="Function"&gt;}&lt;/span&gt;
&lt;span class="lnr"&gt;17 &lt;/span&gt;      &lt;span class="Statement"&gt;document&lt;/span&gt;.body.appendChild(&lt;span class="Identifier"&gt;this&lt;/span&gt;.element);
&lt;span class="lnr"&gt;18 &lt;/span&gt;    &lt;span class="Function"&gt;}&lt;/span&gt;
&lt;span class="lnr"&gt;19 &lt;/span&gt;  &lt;span class="Function"&gt;}&lt;/span&gt;;
&lt;span class="lnr"&gt;20 &lt;/span&gt;
&lt;span class="lnr"&gt;21 &lt;/span&gt;&lt;span class="Function"&gt;}&lt;/span&gt;;
&lt;span class="lnr"&gt;22 &lt;/span&gt;Circle.prototype = &lt;span class="Statement"&gt;new&lt;/span&gt; Box();
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;And that’s really it, we’re done. Now something fun like this is possible:&lt;/p&gt;
&lt;code&gt;&lt;pre&gt;
&lt;span class="lnr"&gt; 1 &lt;/span&gt;Box.prototype.moveTo = &lt;span class="Function"&gt;function&lt;/span&gt;(aTop, aLeft) &lt;span class="Function"&gt;{&lt;/span&gt;
&lt;span class="lnr"&gt; 2 &lt;/span&gt;  &lt;span class="Statement"&gt;if&lt;/span&gt; (&lt;span class="Identifier"&gt;this&lt;/span&gt;.element) &lt;span class="Function"&gt;{&lt;/span&gt;
&lt;span class="lnr"&gt; 3 &lt;/span&gt;    &lt;span class="Identifier"&gt;this&lt;/span&gt;.element.style.&lt;span class="Statement"&gt;top&lt;/span&gt; = aTop;
&lt;span class="lnr"&gt; 4 &lt;/span&gt;    &lt;span class="Identifier"&gt;this&lt;/span&gt;.element.style.left = aLeft;
&lt;span class="lnr"&gt; 5 &lt;/span&gt;  &lt;span class="Function"&gt;}&lt;/span&gt;
&lt;span class="lnr"&gt; 6 &lt;/span&gt;&lt;span class="Function"&gt;}&lt;/span&gt;
&lt;span class="lnr"&gt; 7 &lt;/span&gt;&lt;span class="Identifier"&gt;var&lt;/span&gt; objects = &lt;span class="Function"&gt;[]&lt;/span&gt;;
&lt;span class="lnr"&gt; 8 &lt;/span&gt;&lt;span class="Identifier"&gt;var&lt;/span&gt; createObject = &lt;span class="Function"&gt;function&lt;/span&gt;() &lt;span class="Function"&gt;{&lt;/span&gt;
&lt;span class="lnr"&gt; 9 &lt;/span&gt;  &lt;span class="Identifier"&gt;var&lt;/span&gt; obj = Math.random() &gt; 0.5 ? &lt;span class="Statement"&gt;new&lt;/span&gt; Box() : &lt;span class="Statement"&gt;new&lt;/span&gt; Circle();
&lt;span class="lnr"&gt;10 &lt;/span&gt;  obj.create();
&lt;span class="lnr"&gt;11 &lt;/span&gt;  &lt;span class="Identifier"&gt;var&lt;/span&gt; top = (Math.random() * &lt;span class="Statement"&gt;window&lt;/span&gt;.innerHeight).toString() + &lt;span class="Constant"&gt;'px'&lt;/span&gt;;
&lt;span class="lnr"&gt;12 &lt;/span&gt;  &lt;span class="Identifier"&gt;var&lt;/span&gt; left = (Math.random() * &lt;span class="Statement"&gt;window&lt;/span&gt;.innerWidth).toString() + &lt;span class="Constant"&gt;'px'&lt;/span&gt;;
&lt;span class="lnr"&gt;13 &lt;/span&gt;  obj.moveTo(top, left);
&lt;span class="lnr"&gt;14 &lt;/span&gt;  objects.push(obj);
&lt;span class="lnr"&gt;15 &lt;/span&gt;  &lt;span class="Statement"&gt;if&lt;/span&gt; (objects.length &gt; 100) &lt;span class="Function"&gt;{&lt;/span&gt;
&lt;span class="lnr"&gt;16 &lt;/span&gt;    &lt;span class="Identifier"&gt;var&lt;/span&gt; i = Math.floor(Math.random() * objects.length);
&lt;span class="lnr"&gt;17 &lt;/span&gt;    objects&lt;span class="Function"&gt;[&lt;/span&gt;i&lt;span class="Function"&gt;]&lt;/span&gt;.destroy();
&lt;span class="lnr"&gt;18 &lt;/span&gt;    objects.splice(i, 1);
&lt;span class="lnr"&gt;19 &lt;/span&gt;  &lt;span class="Function"&gt;}&lt;/span&gt;
&lt;span class="lnr"&gt;20 &lt;/span&gt;  setTimeout(createObject, 100);
&lt;span class="lnr"&gt;21 &lt;/span&gt;&lt;span class="Function"&gt;}&lt;/span&gt;
&lt;span class="lnr"&gt;22 &lt;/span&gt;setTimeout(createObject, 100);
&lt;/pre&gt;&lt;/code&gt;</description><link>http://blog.crt.lv/post/378658852</link><guid>http://blog.crt.lv/post/378658852</guid><pubDate>Mon, 08 Feb 2010 23:31:00 +0200</pubDate><category>JavaScript</category></item><item><title>Latvian Keyboard Layout</title><description>&lt;p&gt;Recently I got Nokia N900, but it doesn’t come with Latvian keyboard layout, not a big deal, since it’s running Linux and Xorg. This is a recollection of my journey into &lt;abbr title="X keyboard extension"&gt;XKB&lt;/abbr&gt; configuration.&lt;/p&gt;

&lt;p&gt;All of the fallowing code goes into &lt;code&gt;/usr/share/X11/xkb/symbols/nokia_vndr/rx-51&lt;/code&gt;, after making changes, you run &lt;code&gt;setxkbmap lv&lt;/code&gt; to activate the layout.&lt;/p&gt;

&lt;p&gt;This was my first try:&lt;/p&gt;
&lt;code&gt;&lt;pre&gt;
&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="PreProc"&gt;partial&lt;/span&gt; &lt;span class="Type"&gt;alphanumeric_keys&lt;/span&gt; &lt;span class="Type"&gt;modifier_keys&lt;/span&gt;
&lt;span class="lnr"&gt; 2 &lt;/span&gt;&lt;span class="Type"&gt;xkb_symbols&lt;/span&gt; &lt;span class="String"&gt;"lv"&lt;/span&gt; {
&lt;span class="lnr"&gt; 3 &lt;/span&gt;
&lt;span class="lnr"&gt; 4 &lt;/span&gt;  &lt;span class="PreProc"&gt;include&lt;/span&gt; &lt;span class="String"&gt;"nokia_vndr/rx-51(english_base)"&lt;/span&gt;
&lt;span class="lnr"&gt; 5 &lt;/span&gt;  &lt;span class="PreProc"&gt;include&lt;/span&gt; &lt;span class="String"&gt;"nokia_vndr/rx-51(arrows_4btns)"&lt;/span&gt;
&lt;span class="lnr"&gt; 6 &lt;/span&gt;
&lt;span class="lnr"&gt; 7 &lt;/span&gt;  &lt;span class="Keyword"&gt;name&lt;/span&gt;[Group1]= &lt;span class="String"&gt;"Latvian"&lt;/span&gt;;
&lt;span class="lnr"&gt; 8 &lt;/span&gt;
&lt;span class="lnr"&gt; 9 &lt;/span&gt;  &lt;span class="Keyword"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;AD03&gt;&lt;/span&gt; { [e, E, emacron, Emacron] };
&lt;span class="lnr"&gt;10 &lt;/span&gt;  &lt;span class="Keyword"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;AD07&gt;&lt;/span&gt; { [u, U, umacron, Umacron] };
&lt;span class="lnr"&gt;11 &lt;/span&gt;  &lt;span class="Keyword"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;AD08&gt;&lt;/span&gt; { [i, I, imacron, Imacron] };
&lt;span class="lnr"&gt;12 &lt;/span&gt;  &lt;span class="Keyword"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;AC01&gt;&lt;/span&gt; { [a, A, amacron, Amacron] };
&lt;span class="lnr"&gt;13 &lt;/span&gt;  &lt;span class="Keyword"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;AC02&gt;&lt;/span&gt; { [s, S, scaron, Scaron] };
&lt;span class="lnr"&gt;14 &lt;/span&gt;  &lt;span class="Keyword"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;AC05&gt;&lt;/span&gt; { [g, G, gcedilla, Gcedilla] };
&lt;span class="lnr"&gt;15 &lt;/span&gt;  &lt;span class="Keyword"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;AC08&gt;&lt;/span&gt; { [k, K, kcedilla, Kcedilla] };
&lt;span class="lnr"&gt;16 &lt;/span&gt;  &lt;span class="Keyword"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;AC09&gt;&lt;/span&gt; { [l, L, lcedilla, Lcedilla] };
&lt;span class="lnr"&gt;17 &lt;/span&gt;  &lt;span class="Keyword"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;AB01&gt;&lt;/span&gt; { [z, Z, zcaron, Zcaron] };
&lt;span class="lnr"&gt;18 &lt;/span&gt;  &lt;span class="Keyword"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;AB03&gt;&lt;/span&gt; { [c, C, ccaron, Ccaron] };
&lt;span class="lnr"&gt;19 &lt;/span&gt;  &lt;span class="Keyword"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;AB06&gt;&lt;/span&gt; { [n, N, ncedilla, Ncedilla] };
&lt;span class="lnr"&gt;20 &lt;/span&gt;
&lt;span class="lnr"&gt;21 &lt;/span&gt;};
&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;This works as expected, you can type both Latin and Latvian letters, but the problem is that you lose some numbers and special characters, that are defined on the third level in &lt;code&gt;english_base&lt;/code&gt;. Something like this would work perfectly, if you need to simply replace one letter with another. What’s interesting is that the fourth level isn’t actually necessary, it doesn’t get used. Looking at the &lt;code&gt;modifiers&lt;/code&gt; symbols definition, you can see that there’s no way to switch to the fourth level, I don’t know why most keys have four levels defined, I did it just because that’s how Nokia does it. What’s interesting is that with three levels, you can get six different symbols:&lt;/p&gt;
&lt;code&gt;&lt;pre&gt;
&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="PreProc"&gt;partial&lt;/span&gt; &lt;span class="Type"&gt;alphanumeric_keys&lt;/span&gt; &lt;span class="Type"&gt;modifier_keys&lt;/span&gt;
&lt;span class="lnr"&gt; 2 &lt;/span&gt;&lt;span class="Type"&gt;xkb_symbols&lt;/span&gt; &lt;span class="String"&gt;"lv"&lt;/span&gt; {
&lt;span class="lnr"&gt; 3 &lt;/span&gt;
&lt;span class="lnr"&gt; 4 &lt;/span&gt;  &lt;span class="PreProc"&gt;include&lt;/span&gt; &lt;span class="String"&gt;"nokia_vndr/rx-51(english_base)"&lt;/span&gt;
&lt;span class="lnr"&gt; 5 &lt;/span&gt;  &lt;span class="PreProc"&gt;include&lt;/span&gt; &lt;span class="String"&gt;"nokia_vndr/rx-51(arrows_4btns)"&lt;/span&gt;
&lt;span class="lnr"&gt; 6 &lt;/span&gt;
&lt;span class="lnr"&gt; 7 &lt;/span&gt;  &lt;span class="Keyword"&gt;name&lt;/span&gt;[Group1]= &lt;span class="String"&gt;"Latvian"&lt;/span&gt;;
&lt;span class="lnr"&gt; 8 &lt;/span&gt;
&lt;span class="lnr"&gt; 9 &lt;/span&gt;  &lt;span class="Keyword"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;AD03&gt;&lt;/span&gt; { [e, emacron, 3, 3] };
&lt;span class="lnr"&gt;10 &lt;/span&gt;  &lt;span class="Keyword"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;AD07&gt;&lt;/span&gt; { [u, umacron, 7, 7] };
&lt;span class="lnr"&gt;11 &lt;/span&gt;  &lt;span class="Keyword"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;AD08&gt;&lt;/span&gt; { [i, imacron, 8, 8] };
&lt;span class="lnr"&gt;12 &lt;/span&gt;  &lt;span class="Keyword"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;AC01&gt;&lt;/span&gt; { [a, amacron, asterisk, asterisk] };
&lt;span class="lnr"&gt;13 &lt;/span&gt;  &lt;span class="Keyword"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;AC02&gt;&lt;/span&gt; { [s, scaron, plus, plus] };
&lt;span class="lnr"&gt;14 &lt;/span&gt;  &lt;span class="Keyword"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;AC05&gt;&lt;/span&gt; { [g, gcedilla, underscore, underscore] };
&lt;span class="lnr"&gt;15 &lt;/span&gt;  &lt;span class="Keyword"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;AC08&gt;&lt;/span&gt; { [k, kcedilla, ampersand, ampersand] };
&lt;span class="lnr"&gt;16 &lt;/span&gt;  &lt;span class="Keyword"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;AC09&gt;&lt;/span&gt; { [l, lcedilla, exclam, exclam] };
&lt;span class="lnr"&gt;17 &lt;/span&gt;  &lt;span class="Keyword"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;AB01&gt;&lt;/span&gt; { [z, zcaron, sterling, sterling] };
&lt;span class="lnr"&gt;18 &lt;/span&gt;  &lt;span class="Keyword"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;AB03&gt;&lt;/span&gt; { [c, ccaron, EuroSign, EuroSign] };
&lt;span class="lnr"&gt;19 &lt;/span&gt;  &lt;span class="Keyword"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;AB06&gt;&lt;/span&gt; { [n, ncedilla, quotedbl, quotedbl] };
&lt;span class="lnr"&gt;20 &lt;/span&gt;
&lt;span class="lnr"&gt;21 &lt;/span&gt;};
&lt;/pre&gt;&lt;/code&gt;
That’s my second attempt, it works like this:
&lt;ul&gt;&lt;li&gt;press &lt;code&gt;e&lt;/code&gt; - level one - returns “e”&lt;/li&gt;
&lt;li&gt;press &lt;code&gt;Shift&lt;/code&gt;, then &lt;code&gt;e&lt;/code&gt; - level one - returns “E”&lt;/li&gt;
&lt;li&gt;hold &lt;code&gt;Shift&lt;/code&gt; and press &lt;code&gt;e&lt;/code&gt; - level two - returns “ē”&lt;/li&gt;
&lt;li&gt;press &lt;code&gt;Shift&lt;/code&gt;, then hold &lt;code&gt;Shift&lt;/code&gt; and press &lt;code&gt;e&lt;/code&gt; - level two - returns “Ē”&lt;/li&gt;
&lt;li&gt;press or hold &lt;code&gt;Fn&lt;/code&gt;, then &lt;code&gt;e&lt;/code&gt;  - level three - returns “3”&lt;/li&gt;
&lt;/ul&gt;
This is better than the first attempt, but very confusing to type, I don’t think you would want to use something like this, illustrates how the levels work though.

&lt;p&gt;Another try:&lt;/p&gt;
&lt;code&gt;&lt;pre&gt;
&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="PreProc"&gt;partial&lt;/span&gt; &lt;span class="Type"&gt;alphanumeric_keys&lt;/span&gt; &lt;span class="Type"&gt;modifier_keys&lt;/span&gt;
&lt;span class="lnr"&gt; 2 &lt;/span&gt;&lt;span class="Type"&gt;xkb_symbols&lt;/span&gt; &lt;span class="Constant"&gt;"lv"&lt;/span&gt; {
&lt;span class="lnr"&gt; 3 &lt;/span&gt;
&lt;span class="lnr"&gt; 4 &lt;/span&gt;  &lt;span class="PreProc"&gt;include&lt;/span&gt; &lt;span class="Constant"&gt;"nokia_vndr/rx-51(english_base)"&lt;/span&gt;
&lt;span class="lnr"&gt; 5 &lt;/span&gt;
&lt;span class="lnr"&gt; 6 &lt;/span&gt;  &lt;span class="Statement"&gt;name&lt;/span&gt;[Group1]= &lt;span class="Constant"&gt;"Latvian"&lt;/span&gt;;
&lt;span class="lnr"&gt; 7 &lt;/span&gt;
&lt;span class="lnr"&gt; 8 &lt;/span&gt;  &lt;span class="Statement"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;UP&gt;&lt;/span&gt; { &lt;span class="Statement"&gt;type&lt;/span&gt;[Group1] = &lt;span class="Constant"&gt;"PC_FN_LEVEL2"&lt;/span&gt;, &lt;span class="Statement"&gt;symbols&lt;/span&gt;[Group1] = [Up] };
&lt;span class="lnr"&gt; 9 &lt;/span&gt;  &lt;span class="Statement"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;LEFT&gt;&lt;/span&gt; { &lt;span class="Statement"&gt;type&lt;/span&gt;[Group1] = &lt;span class="Constant"&gt;"PC_FN_LEVEL2"&lt;/span&gt;, &lt;span class="Statement"&gt;symbols&lt;/span&gt;[Group1] = [Left, dead_caron] };
&lt;span class="lnr"&gt;10 &lt;/span&gt;  &lt;span class="Statement"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;DOWN&gt;&lt;/span&gt; { &lt;span class="Statement"&gt;type&lt;/span&gt;[Group1] = &lt;span class="Constant"&gt;"PC_FN_LEVEL2"&lt;/span&gt;, &lt;span class="Statement"&gt;symbols&lt;/span&gt;[Group1] = [Down, dead_cedilla] };
&lt;span class="lnr"&gt;11 &lt;/span&gt;  &lt;span class="Statement"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;RGHT&gt;&lt;/span&gt; { &lt;span class="Statement"&gt;type&lt;/span&gt;[Group1] = &lt;span class="Constant"&gt;"PC_FN_LEVEL2"&lt;/span&gt;, &lt;span class="Statement"&gt;symbols&lt;/span&gt;[Group1] = [Right, dead_macron] };
&lt;span class="lnr"&gt;12 &lt;/span&gt;
&lt;span class="lnr"&gt;13 &lt;/span&gt;};
&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;Here we set the second level of arrow keys to work as &lt;a href="http://en.wikipedia.org/wiki/Dead_key" title="Dead key - Wikipedia"&gt;dead keys&lt;/a&gt;. I’m not sure why you needed to assign a special type, but this won’t work otherwise. If your language has one diacritic, this would be a good solution, more than that and this gets confusing.&lt;/p&gt;

&lt;p&gt;Here’s the best and final configuration:&lt;/p&gt;
&lt;code&gt;&lt;pre&gt;
&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="PreProc"&gt;partial&lt;/span&gt; &lt;span class="Type"&gt;alphanumeric_keys&lt;/span&gt; &lt;span class="Type"&gt;modifier_keys&lt;/span&gt;
&lt;span class="lnr"&gt; 2 &lt;/span&gt;&lt;span class="Type"&gt;xkb_symbols&lt;/span&gt; &lt;span class="Constant"&gt;"lv"&lt;/span&gt; {
&lt;span class="lnr"&gt; 3 &lt;/span&gt;
&lt;span class="lnr"&gt; 4 &lt;/span&gt;  &lt;span class="PreProc"&gt;include&lt;/span&gt; &lt;span class="Constant"&gt;"nokia_vndr/rx-51(english_base)"&lt;/span&gt;
&lt;span class="lnr"&gt; 5 &lt;/span&gt;  &lt;span class="PreProc"&gt;include&lt;/span&gt; &lt;span class="Constant"&gt;"nokia_vndr/rx-51(arrows_4btns)"&lt;/span&gt;
&lt;span class="lnr"&gt; 6 &lt;/span&gt;
&lt;span class="lnr"&gt; 7 &lt;/span&gt;  &lt;span class="Statement"&gt;name&lt;/span&gt;[Group1] = &lt;span class="Constant"&gt;"Latin"&lt;/span&gt;;
&lt;span class="lnr"&gt; 8 &lt;/span&gt;  &lt;span class="Statement"&gt;name&lt;/span&gt;[Group2] = &lt;span class="Constant"&gt;"Latvian"&lt;/span&gt;;
&lt;span class="lnr"&gt; 9 &lt;/span&gt;
&lt;span class="lnr"&gt;10 &lt;/span&gt;  &lt;span class="Statement"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;AD03&gt;&lt;/span&gt; { &lt;span class="Statement"&gt;symbols&lt;/span&gt;[Group2] = [emacron, Emacron, 3, 3] };
&lt;span class="lnr"&gt;11 &lt;/span&gt;  &lt;span class="Statement"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;AD07&gt;&lt;/span&gt; { &lt;span class="Statement"&gt;symbols&lt;/span&gt;[Group2] = [umacron, Umacron, 7, 7] };
&lt;span class="lnr"&gt;12 &lt;/span&gt;  &lt;span class="Statement"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;AD08&gt;&lt;/span&gt; { &lt;span class="Statement"&gt;symbols&lt;/span&gt;[Group2] = [imacron, Imacron, 8, 8] };
&lt;span class="lnr"&gt;13 &lt;/span&gt;  &lt;span class="Statement"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;AC01&gt;&lt;/span&gt; { &lt;span class="Statement"&gt;symbols&lt;/span&gt;[Group2] = [amacron, Amacron, asterisk, asterisk] };
&lt;span class="lnr"&gt;14 &lt;/span&gt;  &lt;span class="Statement"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;AC02&gt;&lt;/span&gt; { &lt;span class="Statement"&gt;symbols&lt;/span&gt;[Group2] = [scaron, Scaron, plus, plus] };
&lt;span class="lnr"&gt;15 &lt;/span&gt;  &lt;span class="Statement"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;AC05&gt;&lt;/span&gt; { &lt;span class="Statement"&gt;symbols&lt;/span&gt;[Group2] = [gcedilla, Gcedilla, underscore, underscore] };
&lt;span class="lnr"&gt;16 &lt;/span&gt;  &lt;span class="Statement"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;AC08&gt;&lt;/span&gt; { &lt;span class="Statement"&gt;symbols&lt;/span&gt;[Group2] = [kcedilla, Kcedilla, ampersand, ampersand] };
&lt;span class="lnr"&gt;17 &lt;/span&gt;  &lt;span class="Statement"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;AC09&gt;&lt;/span&gt; { &lt;span class="Statement"&gt;symbols&lt;/span&gt;[Group2] = [lcedilla, Lcedilla, exclam, exclam] };
&lt;span class="lnr"&gt;18 &lt;/span&gt;  &lt;span class="Statement"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;AB01&gt;&lt;/span&gt; { &lt;span class="Statement"&gt;symbols&lt;/span&gt;[Group2] = [zcaron, Zcaron, sterling, sterling] };
&lt;span class="lnr"&gt;19 &lt;/span&gt;  &lt;span class="Statement"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;AB03&gt;&lt;/span&gt; { &lt;span class="Statement"&gt;symbols&lt;/span&gt;[Group2] = [ccaron, Ccaron, EuroSign, EuroSign] };
&lt;span class="lnr"&gt;20 &lt;/span&gt;  &lt;span class="Statement"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;AB06&gt;&lt;/span&gt; { &lt;span class="Statement"&gt;symbols&lt;/span&gt;[Group2] = [ncedilla, Ncedilla, quotedbl, quotedbl] };
&lt;span class="lnr"&gt;21 &lt;/span&gt;
&lt;span class="lnr"&gt;22 &lt;/span&gt;  &lt;span class="Statement"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;AB08&gt;&lt;/span&gt; { [ISO_Group_Latch, semicolon, equal, equal], [comma, semicolon, equal, equal] };
&lt;span class="lnr"&gt;23 &lt;/span&gt;  &lt;span class="Statement"&gt;key&lt;/span&gt; &lt;span class="Identifier"&gt;&lt;SPCE&gt;&lt;/span&gt; { &lt;span class="Statement"&gt;symbols&lt;/span&gt;[Group2] = [comma, space, at, at] };
&lt;span class="lnr"&gt;24 &lt;/span&gt;
&lt;span class="lnr"&gt;25 &lt;/span&gt;};
&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;What this does is adds another group to keys and sets &lt;code&gt;,&lt;/code&gt; key to “latch” onto it. Here’s how it works - every key works like normal, except &lt;code&gt;,&lt;/code&gt;, it sets key group to two, so that when you press the next key, that has a second group defined, a symbol from group two will be used, instead of the default first group. Works really well, I’m happy with this setup, only thing that could make it better, would be a dedicated &lt;code&gt;Chr&lt;/code&gt; key, like some other Nokia phones have.&lt;/p&gt;

&lt;p&gt;Another interesting possibility is to define keys with eight levels and set first group type to &lt;code&gt;EIGHT_LEVEL_SEMIALPHABETIC&lt;/code&gt;, then you can switch between first four and last four levels with &lt;code&gt;Ctrl + Space&lt;/code&gt;. Perfect for languages that don’t have Latin letters.&lt;/p&gt;

&lt;p&gt;Resources: &lt;a href="http://www.charvolant.org/~doug/xkb/html/xkb.html"&gt;An Unreliable Guide to XKB Configuration&lt;/a&gt;, &lt;a href="http://pascal.tsu.ru/en/xkb/"&gt;X Keyboard Extension - Иван Паскаль&lt;/a&gt;, &lt;a href="http://cgit.freedesktop.org/xkeyboard-config/tree/symbols"&gt;example configurations&lt;/a&gt;. &lt;/p&gt;</description><link>http://blog.crt.lv/post/365704128</link><guid>http://blog.crt.lv/post/365704128</guid><pubDate>Tue, 02 Feb 2010 00:13:00 +0200</pubDate><category>XKB</category><category>Maemo</category><category>N900</category></item><item><title>Computing MD5/SHA256/SHA512 Checksum</title><description>&lt;p&gt;&lt;code&gt;&lt;pre&gt;
&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="Statement"&gt;using&lt;/span&gt; System;
&lt;span class="lnr"&gt; 2 &lt;/span&gt;&lt;span class="Statement"&gt;using&lt;/span&gt; System.Security.Cryptography;
&lt;span class="lnr"&gt; 3 &lt;/span&gt;&lt;span class="Statement"&gt;using&lt;/span&gt; System.Text;
&lt;span class="lnr"&gt; 4 &lt;/span&gt;
&lt;span class="lnr"&gt; 5 &lt;/span&gt;&lt;span class="Type"&gt;class&lt;/span&gt; Test {
&lt;span class="lnr"&gt; 6 &lt;/span&gt;
&lt;span class="lnr"&gt; 7 &lt;/span&gt;  &lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;static&lt;/span&gt; &lt;span class="Type"&gt;int&lt;/span&gt; Main(String[] args) {
&lt;span class="lnr"&gt; 8 &lt;/span&gt;    &lt;span class="Statement"&gt;if&lt;/span&gt; (args.Length != &lt;span class="Constant"&gt;2&lt;/span&gt;) {
&lt;span class="lnr"&gt; 9 &lt;/span&gt;      &lt;span class="Statement"&gt;return&lt;/span&gt; &lt;span class="Constant"&gt;1&lt;/span&gt;;
&lt;span class="lnr"&gt;10 &lt;/span&gt;    } &lt;span class="Statement"&gt;else&lt;/span&gt; {
&lt;span class="lnr"&gt;11 &lt;/span&gt;      HashAlgorithm algo;
&lt;span class="lnr"&gt;12 &lt;/span&gt;      &lt;span class="Statement"&gt;switch&lt;/span&gt; (args[&lt;span class="Constant"&gt;0&lt;/span&gt;].ToUpper()) {
&lt;span class="lnr"&gt;13 &lt;/span&gt;        &lt;span class="Statement"&gt;case&lt;/span&gt; &lt;span class="Constant"&gt;"MD5"&lt;/span&gt;:
&lt;span class="lnr"&gt;14 &lt;/span&gt;          algo = &lt;span class="Statement"&gt;new&lt;/span&gt; MD5CryptoServiceProvider();
&lt;span class="lnr"&gt;15 &lt;/span&gt;          &lt;span class="Statement"&gt;break&lt;/span&gt;;
&lt;span class="lnr"&gt;16 &lt;/span&gt;        &lt;span class="Statement"&gt;case&lt;/span&gt; &lt;span class="Constant"&gt;"SHA256"&lt;/span&gt;:
&lt;span class="lnr"&gt;17 &lt;/span&gt;          algo = &lt;span class="Statement"&gt;new&lt;/span&gt; SHA256CryptoServiceProvider();
&lt;span class="lnr"&gt;18 &lt;/span&gt;          &lt;span class="Statement"&gt;break&lt;/span&gt;;
&lt;span class="lnr"&gt;19 &lt;/span&gt;        &lt;span class="Statement"&gt;case&lt;/span&gt; &lt;span class="Constant"&gt;"SHA512"&lt;/span&gt;:
&lt;span class="lnr"&gt;20 &lt;/span&gt;          algo = &lt;span class="Statement"&gt;new&lt;/span&gt; SHA512CryptoServiceProvider();
&lt;span class="lnr"&gt;21 &lt;/span&gt;          &lt;span class="Statement"&gt;break&lt;/span&gt;;
&lt;span class="lnr"&gt;22 &lt;/span&gt;        &lt;span class="Statement"&gt;default&lt;/span&gt;:
&lt;span class="lnr"&gt;23 &lt;/span&gt;          &lt;span class="Statement"&gt;return&lt;/span&gt; &lt;span class="Constant"&gt;2&lt;/span&gt;;
&lt;span class="lnr"&gt;24 &lt;/span&gt;      }
&lt;span class="lnr"&gt;25 &lt;/span&gt;      Console.WriteLine(ComputeChecksum(algo, args[&lt;span class="Constant"&gt;1&lt;/span&gt;]));
&lt;span class="lnr"&gt;26 &lt;/span&gt;      &lt;span class="Statement"&gt;return&lt;/span&gt; &lt;span class="Constant"&gt;0&lt;/span&gt;;
&lt;span class="lnr"&gt;27 &lt;/span&gt;    }
&lt;span class="lnr"&gt;28 &lt;/span&gt;  }
&lt;span class="lnr"&gt;29 &lt;/span&gt;
&lt;span class="lnr"&gt;30 &lt;/span&gt;  &lt;span class="Type"&gt;static&lt;/span&gt; &lt;span class="Type"&gt;public&lt;/span&gt; String ComputeChecksum(HashAlgorithm algo, String message) {
&lt;span class="lnr"&gt;31 &lt;/span&gt;    var bytes = Encoding.UTF8.GetBytes(message);
&lt;span class="lnr"&gt;32 &lt;/span&gt;    var digest = algo.ComputeHash(bytes);
&lt;span class="lnr"&gt;33 &lt;/span&gt;    var checksum = &lt;span class="Statement"&gt;new&lt;/span&gt; StringBuilder();
&lt;span class="lnr"&gt;34 &lt;/span&gt;    &lt;span class="Statement"&gt;foreach&lt;/span&gt; (Byte b &lt;span class="Statement"&gt;in&lt;/span&gt; digest) {
&lt;span class="lnr"&gt;35 &lt;/span&gt;      checksum.Append(b.ToString(&lt;span class="Constant"&gt;"x2"&lt;/span&gt;));
&lt;span class="lnr"&gt;36 &lt;/span&gt;    }
&lt;span class="lnr"&gt;37 &lt;/span&gt;    &lt;span class="Statement"&gt;return&lt;/span&gt; checksum.ToString();
&lt;span class="lnr"&gt;38 &lt;/span&gt;  }
&lt;span class="lnr"&gt;39 &lt;/span&gt;
&lt;span class="lnr"&gt;40 &lt;/span&gt;}
&lt;/pre&gt;&lt;/code&gt;&lt;/p&gt;</description><link>http://blog.crt.lv/post/351237943</link><guid>http://blog.crt.lv/post/351237943</guid><pubDate>Sun, 24 Jan 2010 22:24:06 +0200</pubDate><category>.NET</category><category>Mono</category><category>C Sharp</category></item><item><title>sp_lock Replacement</title><description>&lt;p&gt;Here’s what I’ve been using instead of &lt;code&gt;sp_lock&lt;/code&gt;:&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;
&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="Statement"&gt;SELECT&lt;/span&gt;
&lt;span class="lnr"&gt; 2 &lt;/span&gt;  l.request_session_id &lt;span class="Statement"&gt;AS&lt;/span&gt; sid,
&lt;span class="lnr"&gt; 3 &lt;/span&gt;  r.status,
&lt;span class="lnr"&gt; 4 &lt;/span&gt;  d.name &lt;span class="Statement"&gt;AS&lt;/span&gt; [database],
&lt;span class="lnr"&gt; 5 &lt;/span&gt;  o.name &lt;span class="Statement"&gt;AS&lt;/span&gt; object,
&lt;span class="lnr"&gt; 6 &lt;/span&gt;  l.request_mode,
&lt;span class="lnr"&gt; 7 &lt;/span&gt;  l.request_status,
&lt;span class="lnr"&gt; 8 &lt;/span&gt;  r.blocking_session_id &lt;span class="Statement"&gt;AS&lt;/span&gt; blocking_sid,
&lt;span class="lnr"&gt; 9 &lt;/span&gt;  r.wait_type,
&lt;span class="lnr"&gt;10 &lt;/span&gt;  r.wait_time,
&lt;span class="lnr"&gt;11 &lt;/span&gt;  r.total_elapsed_time,
&lt;span class="lnr"&gt;12 &lt;/span&gt;  r.percent_complete,
&lt;span class="lnr"&gt;13 &lt;/span&gt;  p.cpu,
&lt;span class="lnr"&gt;14 &lt;/span&gt;  p.physical_io,
&lt;span class="lnr"&gt;15 &lt;/span&gt;  p.memusage,
&lt;span class="lnr"&gt;16 &lt;/span&gt;  p.loginame,
&lt;span class="lnr"&gt;17 &lt;/span&gt;  p.hostname,
&lt;span class="lnr"&gt;18 &lt;/span&gt;  p.program_name,
&lt;span class="lnr"&gt;19 &lt;/span&gt;  t.text
&lt;span class="lnr"&gt;20 &lt;/span&gt;&lt;span class="Statement"&gt;FROM&lt;/span&gt; sys.dm_tran_locks &lt;span class="Statement"&gt;AS&lt;/span&gt; l
&lt;span class="lnr"&gt;21 &lt;/span&gt;&lt;span class="Statement"&gt;INNER&lt;/span&gt; &lt;span class="Statement"&gt;JOIN&lt;/span&gt; sys.databases &lt;span class="Statement"&gt;AS&lt;/span&gt; d &lt;span class="Statement"&gt;ON&lt;/span&gt; d.database_id = l.resource_database_id
&lt;span class="lnr"&gt;22 &lt;/span&gt;&lt;span class="Statement"&gt;INNER&lt;/span&gt; &lt;span class="Statement"&gt;JOIN&lt;/span&gt; sys.objects &lt;span class="Statement"&gt;AS&lt;/span&gt; o &lt;span class="Statement"&gt;ON&lt;/span&gt; o.object_id = l.resource_associated_entity_id
&lt;span class="lnr"&gt;23 &lt;/span&gt;&lt;span class="Statement"&gt;LEFT&lt;/span&gt; &lt;span class="Statement"&gt;JOIN&lt;/span&gt; sys.dm_exec_requests &lt;span class="Statement"&gt;AS&lt;/span&gt; r &lt;span class="Statement"&gt;ON&lt;/span&gt; r.session_id = l.request_session_id
&lt;span class="lnr"&gt;24 &lt;/span&gt;&lt;span class="Statement"&gt;LEFT&lt;/span&gt; &lt;span class="Statement"&gt;JOIN&lt;/span&gt; sys.sysprocesses &lt;span class="Statement"&gt;AS&lt;/span&gt; p &lt;span class="Statement"&gt;ON&lt;/span&gt; p.spid = l.request_session_id
&lt;span class="lnr"&gt;25 &lt;/span&gt;&lt;span class="Statement"&gt;CROSS&lt;/span&gt; &lt;span class="Statement"&gt;APPLY&lt;/span&gt; sys.dm_exec_sql_text(r.sql_handle) &lt;span class="Statement"&gt;AS&lt;/span&gt; t
&lt;span class="lnr"&gt;26 &lt;/span&gt;&lt;span class="Statement"&gt;WHERE&lt;/span&gt;
&lt;span class="lnr"&gt;27 &lt;/span&gt;  d.database_id = DB_ID() &lt;span class="Statement"&gt;AND&lt;/span&gt;
&lt;span class="lnr"&gt;28 &lt;/span&gt;  l.resource_type = &lt;span class="Constant"&gt;'OBJECT'&lt;/span&gt; &lt;span class="Statement"&gt;AND&lt;/span&gt;
&lt;span class="lnr"&gt;29 &lt;/span&gt;  r.session_id != &lt;span class="Identifier"&gt;@@SPID&lt;/span&gt;
&lt;span class="lnr"&gt;30 &lt;/span&gt;&lt;span class="Statement"&gt;ORDER&lt;/span&gt; &lt;span class="Statement"&gt;BY&lt;/span&gt;
&lt;span class="lnr"&gt;31 &lt;/span&gt;  d.name,
&lt;span class="lnr"&gt;32 &lt;/span&gt;  l.request_session_id,
&lt;span class="lnr"&gt;33 &lt;/span&gt;  o.name
&lt;/pre&gt;&lt;/code&gt;</description><link>http://blog.crt.lv/post/338323215</link><guid>http://blog.crt.lv/post/338323215</guid><pubDate>Sun, 17 Jan 2010 04:21:00 +0200</pubDate><category>SQL</category><category>SQL Server</category></item><item><title>URL Mapping</title><description>&lt;p&gt;Here’s full, working and as simple as possible example on how to get pretty URLs with .NET/Mono.&lt;/p&gt;

&lt;p&gt;First, here’s all the code:&lt;/p&gt;
&lt;code&gt;&lt;pre&gt;
&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="Statement"&gt;using&lt;/span&gt; System;
&lt;span class="lnr"&gt; 2 &lt;/span&gt;&lt;span class="Statement"&gt;using&lt;/span&gt; System.Web;
&lt;span class="lnr"&gt; 3 &lt;/span&gt;&lt;span class="Statement"&gt;using&lt;/span&gt; System.Web.Routing;
&lt;span class="lnr"&gt; 4 &lt;/span&gt;
&lt;span class="lnr"&gt; 5 &lt;/span&gt;
&lt;span class="lnr"&gt; 6 &lt;/span&gt;&lt;span class="Type"&gt;class&lt;/span&gt; RouteHandler : IRouteHandler {
&lt;span class="lnr"&gt; 7 &lt;/span&gt;
&lt;span class="lnr"&gt; 8 &lt;/span&gt;  Type PageType;
&lt;span class="lnr"&gt; 9 &lt;/span&gt;
&lt;span class="lnr"&gt;10 &lt;/span&gt;  &lt;span class="Type"&gt;public&lt;/span&gt; RouteHandler(Type pageType) {
&lt;span class="lnr"&gt;11 &lt;/span&gt;    PageType = pageType;
&lt;span class="lnr"&gt;12 &lt;/span&gt;  }
&lt;span class="lnr"&gt;13 &lt;/span&gt;
&lt;span class="lnr"&gt;14 &lt;/span&gt;  &lt;span class="Type"&gt;public&lt;/span&gt; IHttpHandler GetHttpHandler(RequestContext requestContext) {
&lt;span class="lnr"&gt;15 &lt;/span&gt;    var routeData = requestContext.RouteData.Values.Values;
&lt;span class="lnr"&gt;16 &lt;/span&gt;    &lt;span class="Type"&gt;string&lt;/span&gt;[] args = &lt;span class="Statement"&gt;new&lt;/span&gt; &lt;span class="Type"&gt;string&lt;/span&gt;[routeData.Count];
&lt;span class="lnr"&gt;17 &lt;/span&gt;    routeData.CopyTo(args, &lt;span class="Constant"&gt;0&lt;/span&gt;);
&lt;span class="lnr"&gt;18 &lt;/span&gt;    Page page = (Page)Activator.CreateInstance(PageType, args);
&lt;span class="lnr"&gt;19 &lt;/span&gt;    &lt;span class="Statement"&gt;return&lt;/span&gt; page;
&lt;span class="lnr"&gt;20 &lt;/span&gt;  }
&lt;span class="lnr"&gt;21 &lt;/span&gt;
&lt;span class="lnr"&gt;22 &lt;/span&gt;}
&lt;span class="lnr"&gt;23 &lt;/span&gt;
&lt;span class="lnr"&gt;24 &lt;/span&gt;
&lt;span class="lnr"&gt;25 &lt;/span&gt;&lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;class&lt;/span&gt; Global : HttpApplication {
&lt;span class="lnr"&gt;26 &lt;/span&gt;
&lt;span class="lnr"&gt;27 &lt;/span&gt;  &lt;span class="Type"&gt;protected&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; Application_Start() {
&lt;span class="lnr"&gt;28 &lt;/span&gt;    RouteCollection r = RouteTable.Routes;
&lt;span class="lnr"&gt;29 &lt;/span&gt;    r.Add(&lt;span class="Statement"&gt;new&lt;/span&gt; Route(&lt;span class="Constant"&gt;"foo"&lt;/span&gt;, &lt;span class="Statement"&gt;new&lt;/span&gt; RouteHandler(&lt;span class="Statement"&gt;typeof&lt;/span&gt;(Foo))));
&lt;span class="lnr"&gt;30 &lt;/span&gt;    r.Add(&lt;span class="Statement"&gt;new&lt;/span&gt; Route(&lt;span class="Constant"&gt;"bar/{id}"&lt;/span&gt;, &lt;span class="Statement"&gt;new&lt;/span&gt; RouteHandler(&lt;span class="Statement"&gt;typeof&lt;/span&gt;(Bar))));
&lt;span class="lnr"&gt;31 &lt;/span&gt;  }
&lt;span class="lnr"&gt;32 &lt;/span&gt;
&lt;span class="lnr"&gt;33 &lt;/span&gt;}
&lt;span class="lnr"&gt;34 &lt;/span&gt;
&lt;span class="lnr"&gt;35 &lt;/span&gt;
&lt;span class="lnr"&gt;36 &lt;/span&gt;&lt;span class="Type"&gt;class&lt;/span&gt; Page : System.Web.UI.Page {
&lt;span class="lnr"&gt;37 &lt;/span&gt;
&lt;span class="lnr"&gt;38 &lt;/span&gt;  &lt;span class="Type"&gt;override&lt;/span&gt; &lt;span class="Type"&gt;protected&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; OnLoadComplete(EventArgs e) {
&lt;span class="lnr"&gt;39 &lt;/span&gt;    &lt;span class="Statement"&gt;if&lt;/span&gt; (Request.HttpMethod == &lt;span class="Constant"&gt;"POST"&lt;/span&gt;) {
&lt;span class="lnr"&gt;40 &lt;/span&gt;      Post();
&lt;span class="lnr"&gt;41 &lt;/span&gt;    } &lt;span class="Statement"&gt;else&lt;/span&gt; {
&lt;span class="lnr"&gt;42 &lt;/span&gt;      Get();
&lt;span class="lnr"&gt;43 &lt;/span&gt;    }
&lt;span class="lnr"&gt;44 &lt;/span&gt;  }
&lt;span class="lnr"&gt;45 &lt;/span&gt;
&lt;span class="lnr"&gt;46 &lt;/span&gt;  &lt;span class="Type"&gt;virtual&lt;/span&gt; &lt;span class="Type"&gt;protected&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; Get() {
&lt;span class="lnr"&gt;47 &lt;/span&gt;    &lt;span class="Statement"&gt;throw&lt;/span&gt; &lt;span class="Statement"&gt;new&lt;/span&gt; NotImplementedException();
&lt;span class="lnr"&gt;48 &lt;/span&gt;  }
&lt;span class="lnr"&gt;49 &lt;/span&gt;
&lt;span class="lnr"&gt;50 &lt;/span&gt;  &lt;span class="Type"&gt;virtual&lt;/span&gt; &lt;span class="Type"&gt;protected&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; Post() {
&lt;span class="lnr"&gt;51 &lt;/span&gt;    &lt;span class="Statement"&gt;throw&lt;/span&gt; &lt;span class="Statement"&gt;new&lt;/span&gt; NotImplementedException();
&lt;span class="lnr"&gt;52 &lt;/span&gt;  }
&lt;span class="lnr"&gt;53 &lt;/span&gt;
&lt;span class="lnr"&gt;54 &lt;/span&gt;}
&lt;span class="lnr"&gt;55 &lt;/span&gt;
&lt;span class="lnr"&gt;56 &lt;/span&gt;
&lt;span class="lnr"&gt;57 &lt;/span&gt;&lt;span class="Type"&gt;class&lt;/span&gt; Foo : Page {
&lt;span class="lnr"&gt;58 &lt;/span&gt;
&lt;span class="lnr"&gt;59 &lt;/span&gt;  &lt;span class="Type"&gt;override&lt;/span&gt; &lt;span class="Type"&gt;protected&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; Get() {
&lt;span class="lnr"&gt;60 &lt;/span&gt;    Response.Write(&lt;span class="Constant"&gt;"FOO!"&lt;/span&gt;);
&lt;span class="lnr"&gt;61 &lt;/span&gt;  }
&lt;span class="lnr"&gt;62 &lt;/span&gt;
&lt;span class="lnr"&gt;63 &lt;/span&gt;}
&lt;span class="lnr"&gt;64 &lt;/span&gt;
&lt;span class="lnr"&gt;65 &lt;/span&gt;
&lt;span class="lnr"&gt;66 &lt;/span&gt;&lt;span class="Type"&gt;class&lt;/span&gt; Bar : Page {
&lt;span class="lnr"&gt;67 &lt;/span&gt;
&lt;span class="lnr"&gt;68 &lt;/span&gt;  &lt;span class="Type"&gt;string&lt;/span&gt; Id;
&lt;span class="lnr"&gt;69 &lt;/span&gt;
&lt;span class="lnr"&gt;70 &lt;/span&gt;  &lt;span class="Type"&gt;public&lt;/span&gt; Bar(&lt;span class="Type"&gt;string&lt;/span&gt; id) {
&lt;span class="lnr"&gt;71 &lt;/span&gt;    Id = id;
&lt;span class="lnr"&gt;72 &lt;/span&gt;  }
&lt;span class="lnr"&gt;73 &lt;/span&gt;
&lt;span class="lnr"&gt;74 &lt;/span&gt;  &lt;span class="Type"&gt;override&lt;/span&gt; &lt;span class="Type"&gt;protected&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; Get() {
&lt;span class="lnr"&gt;75 &lt;/span&gt;    Response.Write(&lt;span class="Constant"&gt;"BAR"&lt;/span&gt; + Id + &lt;span class="Constant"&gt;"!"&lt;/span&gt;);
&lt;span class="lnr"&gt;76 &lt;/span&gt;  }
&lt;span class="lnr"&gt;77 &lt;/span&gt;
&lt;span class="lnr"&gt;78 &lt;/span&gt;}
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;Save that as global.cs and compile it with this, if you’re using Mono:&lt;/p&gt;
&lt;code&gt;&lt;pre&gt;
&lt;span class="lnr"&gt;1 &lt;/span&gt;gmcs &lt;span class="Special"&gt;-debug&lt;/span&gt;+ &lt;span class="Special"&gt;-r&lt;/span&gt;:System.Web,System.Web.Routing &lt;span class="Special"&gt;-t&lt;/span&gt;:library global.cs
&lt;/pre&gt;&lt;/code&gt;
&lt;p&gt;Or this, if you’re using .NET:&lt;/p&gt;
&lt;code&gt;&lt;pre&gt;
&lt;span class="lnr"&gt;1 &lt;/span&gt;csc &lt;span class="Special"&gt;/debug&lt;/span&gt;+ &lt;span class="Special"&gt;/r&lt;/span&gt;:System.Web.Routing.dll &lt;span class="Special"&gt;/t&lt;/span&gt;:library global.cs
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;Drop the resulting &lt;code&gt;global.dll&lt;/code&gt; in &lt;code&gt;Bin&lt;/code&gt; directory on the web server. And to wire it up, you’ll need this &lt;code&gt;global.asax&lt;/code&gt;:&lt;/p&gt;
&lt;code&gt;&lt;pre&gt;
&lt;span class="lnr"&gt;1 &lt;/span&gt;&lt;span class="Special"&gt;&lt;%&lt;/span&gt;@ &lt;span class="Identifier"&gt;Inherits&lt;/span&gt;=&lt;span class="Constant"&gt;"&lt;/span&gt;&lt;span class="Constant"&gt;Global&lt;/span&gt;&lt;span class="Constant"&gt;"&lt;/span&gt; &lt;span class="Special"&gt;%&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;Also, your &lt;code&gt;web.config&lt;/code&gt; should look something like this:&lt;/p&gt;
&lt;code&gt;&lt;pre&gt;
&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="Comment"&gt;&lt;?&lt;/span&gt;&lt;span class="Type"&gt;xml&lt;/span&gt;&lt;span class="Type"&gt; &lt;/span&gt;&lt;span class="Type"&gt;version&lt;/span&gt;=&lt;span class="Constant"&gt;"1.0"&lt;/span&gt;&lt;span class="Comment"&gt;?&gt;&lt;/span&gt;
&lt;span class="lnr"&gt; 2 &lt;/span&gt;&lt;configuration&gt;
&lt;span class="lnr"&gt; 3 &lt;/span&gt;  &lt;system.web&gt;
&lt;span class="lnr"&gt; 4 &lt;/span&gt;    &lt;customErrors &lt;span class="Type"&gt;mode&lt;/span&gt;=&lt;span class="Constant"&gt;"Off"&lt;/span&gt; /&gt;
&lt;span class="lnr"&gt; 5 &lt;/span&gt;    &lt;httpModules&gt;
&lt;span class="lnr"&gt; 6 &lt;/span&gt;      &lt;clear /&gt;
&lt;span class="lnr"&gt; 7 &lt;/span&gt;      &lt;add &lt;span class="Type"&gt;name&lt;/span&gt;=&lt;span class="Constant"&gt;"UrlRoutingModule"&lt;/span&gt;&lt;span class="Function"&gt; &lt;/span&gt;&lt;span class="Type"&gt;type&lt;/span&gt;=&lt;span class="Constant"&gt;"System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"&lt;/span&gt; /&gt;
&lt;span class="lnr"&gt; 8 &lt;/span&gt;    &lt;/httpModules&gt;
&lt;span class="lnr"&gt; 9 &lt;/span&gt;  &lt;/system.web&gt;
&lt;span class="lnr"&gt;10 &lt;/span&gt;&lt;/configuration&gt;
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;And that should be it! Try visiting &lt;code&gt;/foo&lt;/code&gt; and &lt;code&gt;/bar/123&lt;/code&gt; on the web server. I successfully tested this with xsp2, lighttpd and IIS 6.0, just remember that, for this to work, web server needs to send all requests to CGI/ISAPI module, xsp2 always does this, in lighttpd, simply send all requests to &lt;code&gt;fastcgi-mono-server&lt;/code&gt;, in IIS, send everything to &lt;code&gt;aspnet_isapi.dll&lt;/code&gt; using “wildcard application maps” setting.&lt;/p&gt;</description><link>http://blog.crt.lv/post/327553063</link><guid>http://blog.crt.lv/post/327553063</guid><pubDate>Mon, 11 Jan 2010 00:13:00 +0200</pubDate><category>.NET</category><category>C Sharp</category><category>Mono</category><category>ASP.NET</category></item><item><title>Type-Safe Collection of Diverse Types</title><description>&lt;p&gt;So you have a couple of different objects (say, &lt;code&gt;Foo&lt;/code&gt; and &lt;code&gt;Bar&lt;/code&gt;), and would like to store them all in some sort of collection (&lt;code&gt;Col&lt;/code&gt;), but in a type-safe way.&lt;/p&gt;
&lt;p&gt;Here’s two solutions:&lt;/p&gt;
&lt;code&gt;&lt;pre&gt;
&lt;span class="lnr"&gt;  1 &lt;/span&gt;&lt;span class="Statement"&gt;using&lt;/span&gt; System;
&lt;span class="lnr"&gt;  2 &lt;/span&gt;&lt;span class="Statement"&gt;using&lt;/span&gt; System.Collections;
&lt;span class="lnr"&gt;  3 &lt;/span&gt;&lt;span class="Statement"&gt;using&lt;/span&gt; System.Collections.Generic;
&lt;span class="lnr"&gt;  4 &lt;/span&gt;
&lt;span class="lnr"&gt;  5 &lt;/span&gt;
&lt;span class="lnr"&gt;  6 &lt;/span&gt;&lt;span class="Comment"&gt;// required only for Col2&lt;/span&gt;
&lt;span class="lnr"&gt;  7 &lt;/span&gt;&lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;interface&lt;/span&gt; IItem {
&lt;span class="lnr"&gt;  8 &lt;/span&gt;
&lt;span class="lnr"&gt;  9 &lt;/span&gt;  &lt;span class="Type"&gt;void&lt;/span&gt; Print();
&lt;span class="lnr"&gt; 10 &lt;/span&gt;
&lt;span class="lnr"&gt; 11 &lt;/span&gt;}
&lt;span class="lnr"&gt; 12 &lt;/span&gt;
&lt;span class="lnr"&gt; 13 &lt;/span&gt;
&lt;span class="lnr"&gt; 14 &lt;/span&gt;&lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;class&lt;/span&gt; Foo : IItem {
&lt;span class="lnr"&gt; 15 &lt;/span&gt;
&lt;span class="lnr"&gt; 16 &lt;/span&gt;  &lt;span class="Type"&gt;public&lt;/span&gt; String Text;
&lt;span class="lnr"&gt; 17 &lt;/span&gt;
&lt;span class="lnr"&gt; 18 &lt;/span&gt;  &lt;span class="Type"&gt;public&lt;/span&gt; Foo(String text) {
&lt;span class="lnr"&gt; 19 &lt;/span&gt;    Text = text;
&lt;span class="lnr"&gt; 20 &lt;/span&gt;    Print();
&lt;span class="lnr"&gt; 21 &lt;/span&gt;  }
&lt;span class="lnr"&gt; 22 &lt;/span&gt;
&lt;span class="lnr"&gt; 23 &lt;/span&gt;  &lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; Print() {
&lt;span class="lnr"&gt; 24 &lt;/span&gt;    Console.Write(&lt;span class="Constant"&gt;"Foo:"&lt;/span&gt; + Text + &lt;span class="Constant"&gt;"; "&lt;/span&gt;);
&lt;span class="lnr"&gt; 25 &lt;/span&gt;  }
&lt;span class="lnr"&gt; 26 &lt;/span&gt;
&lt;span class="lnr"&gt; 27 &lt;/span&gt;}
&lt;span class="lnr"&gt; 28 &lt;/span&gt;
&lt;span class="lnr"&gt; 29 &lt;/span&gt;
&lt;span class="lnr"&gt; 30 &lt;/span&gt;&lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;class&lt;/span&gt; Bar : IItem {
&lt;span class="lnr"&gt; 31 &lt;/span&gt;
&lt;span class="lnr"&gt; 32 &lt;/span&gt;  &lt;span class="Type"&gt;public&lt;/span&gt; List&lt;String&gt; List;
&lt;span class="lnr"&gt; 33 &lt;/span&gt;
&lt;span class="lnr"&gt; 34 &lt;/span&gt;  &lt;span class="Type"&gt;public&lt;/span&gt; Bar(List&lt;String&gt; list) {
&lt;span class="lnr"&gt; 35 &lt;/span&gt;    List = list;
&lt;span class="lnr"&gt; 36 &lt;/span&gt;    Print();
&lt;span class="lnr"&gt; 37 &lt;/span&gt;  }
&lt;span class="lnr"&gt; 38 &lt;/span&gt;
&lt;span class="lnr"&gt; 39 &lt;/span&gt;  &lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; Print() {
&lt;span class="lnr"&gt; 40 &lt;/span&gt;    Console.Write(&lt;span class="Constant"&gt;"Bar:"&lt;/span&gt;);
&lt;span class="lnr"&gt; 41 &lt;/span&gt;    &lt;span class="Statement"&gt;foreach&lt;/span&gt; (String item &lt;span class="Statement"&gt;in&lt;/span&gt; List) {
&lt;span class="lnr"&gt; 42 &lt;/span&gt;      Console.Write(item + &lt;span class="Constant"&gt;";"&lt;/span&gt;);
&lt;span class="lnr"&gt; 43 &lt;/span&gt;    }
&lt;span class="lnr"&gt; 44 &lt;/span&gt;    Console.Write(&lt;span class="Constant"&gt;" "&lt;/span&gt;);
&lt;span class="lnr"&gt; 45 &lt;/span&gt;  }
&lt;span class="lnr"&gt; 46 &lt;/span&gt;
&lt;span class="lnr"&gt; 47 &lt;/span&gt;}
&lt;span class="lnr"&gt; 48 &lt;/span&gt;
&lt;span class="lnr"&gt; 49 &lt;/span&gt;
&lt;span class="lnr"&gt; 50 &lt;/span&gt;&lt;span class="Comment"&gt;// stores objects as they are, without casting&lt;/span&gt;
&lt;span class="lnr"&gt; 51 &lt;/span&gt;&lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;class&lt;/span&gt; Col1 {
&lt;span class="lnr"&gt; 52 &lt;/span&gt;
&lt;span class="lnr"&gt; 53 &lt;/span&gt;  &lt;span class="Type"&gt;private&lt;/span&gt; List&lt;Foo&gt; fooList = &lt;span class="Statement"&gt;new&lt;/span&gt; List&lt;Foo&gt;();
&lt;span class="lnr"&gt; 54 &lt;/span&gt;
&lt;span class="lnr"&gt; 55 &lt;/span&gt;  &lt;span class="Type"&gt;private&lt;/span&gt; List&lt;Bar&gt; barList = &lt;span class="Statement"&gt;new&lt;/span&gt; List&lt;Bar&gt;();
&lt;span class="lnr"&gt; 56 &lt;/span&gt;
&lt;span class="lnr"&gt; 57 &lt;/span&gt;  &lt;span class="Type"&gt;private&lt;/span&gt; List&lt;Char&gt; order = &lt;span class="Statement"&gt;new&lt;/span&gt; List&lt;Char&gt;();
&lt;span class="lnr"&gt; 58 &lt;/span&gt;
&lt;span class="lnr"&gt; 59 &lt;/span&gt;  &lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; Add(Foo item) {
&lt;span class="lnr"&gt; 60 &lt;/span&gt;    fooList.Add(item);
&lt;span class="lnr"&gt; 61 &lt;/span&gt;    order.Add(&lt;span class="Constant"&gt;'f'&lt;/span&gt;);
&lt;span class="lnr"&gt; 62 &lt;/span&gt;  }
&lt;span class="lnr"&gt; 63 &lt;/span&gt;
&lt;span class="lnr"&gt; 64 &lt;/span&gt;  &lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; Add(Bar item) {
&lt;span class="lnr"&gt; 65 &lt;/span&gt;    barList.Add(item);
&lt;span class="lnr"&gt; 66 &lt;/span&gt;    order.Add(&lt;span class="Constant"&gt;'b'&lt;/span&gt;);
&lt;span class="lnr"&gt; 67 &lt;/span&gt;  }
&lt;span class="lnr"&gt; 68 &lt;/span&gt;
&lt;span class="lnr"&gt; 69 &lt;/span&gt;  &lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; Print() {
&lt;span class="lnr"&gt; 70 &lt;/span&gt;    var fooEnu = fooList.GetEnumerator();
&lt;span class="lnr"&gt; 71 &lt;/span&gt;    var barEnu = barList.GetEnumerator();
&lt;span class="lnr"&gt; 72 &lt;/span&gt;    &lt;span class="Statement"&gt;foreach&lt;/span&gt; (Char list &lt;span class="Statement"&gt;in&lt;/span&gt; order) {
&lt;span class="lnr"&gt; 73 &lt;/span&gt;      &lt;span class="Statement"&gt;switch&lt;/span&gt; (list) {
&lt;span class="lnr"&gt; 74 &lt;/span&gt;        &lt;span class="Statement"&gt;case&lt;/span&gt; &lt;span class="Constant"&gt;'f'&lt;/span&gt;:
&lt;span class="lnr"&gt; 75 &lt;/span&gt;          fooEnu.MoveNext();
&lt;span class="lnr"&gt; 76 &lt;/span&gt;          fooEnu.Current.Print();
&lt;span class="lnr"&gt; 77 &lt;/span&gt;          &lt;span class="Statement"&gt;break&lt;/span&gt;;
&lt;span class="lnr"&gt; 78 &lt;/span&gt;        &lt;span class="Statement"&gt;case&lt;/span&gt; &lt;span class="Constant"&gt;'b'&lt;/span&gt;:
&lt;span class="lnr"&gt; 79 &lt;/span&gt;          barEnu.MoveNext();
&lt;span class="lnr"&gt; 80 &lt;/span&gt;          barEnu.Current.Print();
&lt;span class="lnr"&gt; 81 &lt;/span&gt;          &lt;span class="Statement"&gt;break&lt;/span&gt;;
&lt;span class="lnr"&gt; 82 &lt;/span&gt;        &lt;span class="Statement"&gt;default&lt;/span&gt;:
&lt;span class="lnr"&gt; 83 &lt;/span&gt;          &lt;span class="Statement"&gt;throw&lt;/span&gt; &lt;span class="Statement"&gt;new&lt;/span&gt; Exception();
&lt;span class="lnr"&gt; 84 &lt;/span&gt;      }
&lt;span class="lnr"&gt; 85 &lt;/span&gt;    }
&lt;span class="lnr"&gt; 86 &lt;/span&gt;  }
&lt;span class="lnr"&gt; 87 &lt;/span&gt;
&lt;span class="lnr"&gt; 88 &lt;/span&gt;}
&lt;span class="lnr"&gt; 89 &lt;/span&gt;
&lt;span class="lnr"&gt; 90 &lt;/span&gt;
&lt;span class="lnr"&gt; 91 &lt;/span&gt;&lt;span class="Comment"&gt;// stores objects cast to interface&lt;/span&gt;
&lt;span class="lnr"&gt; 92 &lt;/span&gt;&lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;class&lt;/span&gt; Col2 {
&lt;span class="lnr"&gt; 93 &lt;/span&gt;
&lt;span class="lnr"&gt; 94 &lt;/span&gt;  &lt;span class="Type"&gt;private&lt;/span&gt; List&lt;IItem&gt; list = &lt;span class="Statement"&gt;new&lt;/span&gt; List&lt;IItem&gt;();
&lt;span class="lnr"&gt; 95 &lt;/span&gt;
&lt;span class="lnr"&gt; 96 &lt;/span&gt;  &lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; Add(IItem item) {
&lt;span class="lnr"&gt; 97 &lt;/span&gt;    list.Add(item);
&lt;span class="lnr"&gt; 98 &lt;/span&gt;  }
&lt;span class="lnr"&gt; 99 &lt;/span&gt;
&lt;span class="lnr"&gt;100 &lt;/span&gt;  &lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; Print() {
&lt;span class="lnr"&gt;101 &lt;/span&gt;    &lt;span class="Statement"&gt;foreach&lt;/span&gt; (IItem item &lt;span class="Statement"&gt;in&lt;/span&gt; list) {
&lt;span class="lnr"&gt;102 &lt;/span&gt;      item.Print();
&lt;span class="lnr"&gt;103 &lt;/span&gt;    }
&lt;span class="lnr"&gt;104 &lt;/span&gt;  }
&lt;span class="lnr"&gt;105 &lt;/span&gt;
&lt;span class="lnr"&gt;106 &lt;/span&gt;}
&lt;span class="lnr"&gt;107 &lt;/span&gt;
&lt;span class="lnr"&gt;108 &lt;/span&gt;
&lt;span class="lnr"&gt;109 &lt;/span&gt;&lt;span class="Comment"&gt;// test collection with random data&lt;/span&gt;
&lt;span class="lnr"&gt;110 &lt;/span&gt;&lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;class&lt;/span&gt; Test {
&lt;span class="lnr"&gt;111 &lt;/span&gt;
&lt;span class="lnr"&gt;112 &lt;/span&gt;  &lt;span class="Type"&gt;public&lt;/span&gt; &lt;span class="Type"&gt;static&lt;/span&gt; &lt;span class="Type"&gt;void&lt;/span&gt; Main() {
&lt;span class="lnr"&gt;113 &lt;/span&gt;    Col1 col = &lt;span class="Statement"&gt;new&lt;/span&gt; Col1();
&lt;span class="lnr"&gt;114 &lt;/span&gt;    &lt;span class="Comment"&gt;//Col2 col = new Col2();&lt;/span&gt;
&lt;span class="lnr"&gt;115 &lt;/span&gt;    Random rng = &lt;span class="Statement"&gt;new&lt;/span&gt; Random();
&lt;span class="lnr"&gt;116 &lt;/span&gt;    &lt;span class="Statement"&gt;for&lt;/span&gt; (Int16 i = &lt;span class="Constant"&gt;0&lt;/span&gt;; i &lt; rng.Next(&lt;span class="Constant"&gt;3&lt;/span&gt;, &lt;span class="Constant"&gt;10&lt;/span&gt;); i++) {
&lt;span class="lnr"&gt;117 &lt;/span&gt;      &lt;span class="Statement"&gt;if&lt;/span&gt; (rng.Next(&lt;span class="Constant"&gt;2&lt;/span&gt;) == &lt;span class="Constant"&gt;0&lt;/span&gt;) {
&lt;span class="lnr"&gt;118 &lt;/span&gt;        col.Add(&lt;span class="Statement"&gt;new&lt;/span&gt; Foo(i.ToString()));
&lt;span class="lnr"&gt;119 &lt;/span&gt;      } &lt;span class="Statement"&gt;else&lt;/span&gt; {
&lt;span class="lnr"&gt;120 &lt;/span&gt;        List&lt;String&gt; list = &lt;span class="Statement"&gt;new&lt;/span&gt; List&lt;String&gt;();
&lt;span class="lnr"&gt;121 &lt;/span&gt;        &lt;span class="Statement"&gt;for&lt;/span&gt; (Int16 i2 = &lt;span class="Constant"&gt;0&lt;/span&gt;; i2 &lt; rng.Next(&lt;span class="Constant"&gt;1&lt;/span&gt;, &lt;span class="Constant"&gt;4&lt;/span&gt;); i2++) {
&lt;span class="lnr"&gt;122 &lt;/span&gt;          list.Add(i.ToString() + i2.ToString());
&lt;span class="lnr"&gt;123 &lt;/span&gt;        }
&lt;span class="lnr"&gt;124 &lt;/span&gt;        col.Add(&lt;span class="Statement"&gt;new&lt;/span&gt; Bar(list));
&lt;span class="lnr"&gt;125 &lt;/span&gt;      }
&lt;span class="lnr"&gt;126 &lt;/span&gt;    }
&lt;span class="lnr"&gt;127 &lt;/span&gt;    Console.WriteLine();
&lt;span class="lnr"&gt;128 &lt;/span&gt;    col.Print();
&lt;span class="lnr"&gt;129 &lt;/span&gt;    Console.WriteLine();
&lt;span class="lnr"&gt;130 &lt;/span&gt;  }
&lt;span class="lnr"&gt;131 &lt;/span&gt;
&lt;span class="lnr"&gt;132 &lt;/span&gt;}
&lt;/pre&gt;&lt;/code&gt;</description><link>http://blog.crt.lv/post/313608065</link><guid>http://blog.crt.lv/post/313608065</guid><pubDate>Sun, 03 Jan 2010 01:50:00 +0200</pubDate><category>.NET</category><category>Mono</category><category>C Sharp</category></item><item><title>Restore Cursor Position</title><description>&lt;p&gt;Add the fallowing line to your &lt;code&gt;.vimrc&lt;/code&gt; and when a file is opened, the cursor will be positioned to the same line it was left on, when this file previously was closed.&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;
&lt;span class="lnr"&gt;1 &lt;/span&gt;&lt;span class="Statement"&gt;autocmd&lt;/span&gt; &lt;span class="Type"&gt;BufReadPost&lt;/span&gt; * &lt;span class="Statement"&gt;if&lt;/span&gt; &lt;span class="Function"&gt;line&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="String"&gt;"'\""&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt; &lt;span class="Operator"&gt;&gt;&lt;/span&gt; &lt;span class="Number"&gt;0&lt;/span&gt;|&lt;span class="Statement"&gt;if&lt;/span&gt; &lt;span class="Function"&gt;line&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="String"&gt;"'\""&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt; &lt;span class="Operator"&gt;&lt;=&lt;/span&gt; &lt;span class="Function"&gt;line&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="String"&gt;"$"&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;|&lt;span class="Normal"&gt;exe&lt;/span&gt;&lt;span class="Operator"&gt;(&lt;/span&gt;&lt;span class="String"&gt;"norm '\""&lt;/span&gt;&lt;span class="Operator"&gt;)&lt;/span&gt;|&lt;span class="Statement"&gt;else&lt;/span&gt;|&lt;span class="Statement"&gt;exe&lt;/span&gt; &lt;span class="String"&gt;"norm $"&lt;/span&gt;&lt;span class="Statement"&gt;|endif&lt;/span&gt;|&lt;span class="Statement"&gt;endif&lt;/span&gt;
&lt;/pre&gt;&lt;/code&gt;</description><link>http://blog.crt.lv/post/302961127</link><guid>http://blog.crt.lv/post/302961127</guid><pubDate>Sun, 27 Dec 2009 19:28:00 +0200</pubDate><category>Vim</category></item><item><title>String Aggregation</title><description>&lt;p&gt;Say you have the following data and you want to concatenate all queries for each year.&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;
&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="Statement"&gt;CREATE TABLE&lt;/span&gt; years (&lt;span class="Statement"&gt;year&lt;/span&gt; &lt;span class="Type"&gt;smallint&lt;/span&gt;);
&lt;span class="lnr"&gt; 2 &lt;/span&gt;&lt;span class="Statement"&gt;INSERT&lt;/span&gt; &lt;span class="Statement"&gt;INTO&lt;/span&gt; years &lt;span class="Statement"&gt;VALUES&lt;/span&gt;
&lt;span class="lnr"&gt; 3 &lt;/span&gt;  (&lt;span class="Number"&gt;2008&lt;/span&gt;),
&lt;span class="lnr"&gt; 4 &lt;/span&gt;  (&lt;span class="Number"&gt;2007&lt;/span&gt;),
&lt;span class="lnr"&gt; 5 &lt;/span&gt;  (&lt;span class="Number"&gt;2009&lt;/span&gt;);
&lt;span class="lnr"&gt; 6 &lt;/span&gt;
&lt;span class="lnr"&gt; 7 &lt;/span&gt;&lt;span class="Statement"&gt;CREATE TABLE&lt;/span&gt; top_queries (&lt;span class="Statement"&gt;year&lt;/span&gt; &lt;span class="Type"&gt;smallint&lt;/span&gt;, place &lt;span class="Type"&gt;smallint&lt;/span&gt;, query &lt;span class="Type"&gt;varchar&lt;/span&gt;(&lt;span class="Number"&gt;50&lt;/span&gt;));
&lt;span class="lnr"&gt; 8 &lt;/span&gt;&lt;span class="Statement"&gt;INSERT&lt;/span&gt; &lt;span class="Statement"&gt;INTO&lt;/span&gt; top_queries &lt;span class="Statement"&gt;VALUES&lt;/span&gt;
&lt;span class="lnr"&gt; 9 &lt;/span&gt;  (&lt;span class="Number"&gt;2009&lt;/span&gt;,  &lt;span class="Number"&gt;4&lt;/span&gt;, &lt;span class="String"&gt;'twitter'&lt;/span&gt;),
&lt;span class="lnr"&gt;10 &lt;/span&gt;  (&lt;span class="Number"&gt;2008&lt;/span&gt;,  &lt;span class="Number"&gt;2&lt;/span&gt;, &lt;span class="String"&gt;'beijing 2008'&lt;/span&gt;),
&lt;span class="lnr"&gt;11 &lt;/span&gt;  (&lt;span class="Number"&gt;2008&lt;/span&gt;,  &lt;span class="Number"&gt;9&lt;/span&gt;, &lt;span class="String"&gt;'euro 2008'&lt;/span&gt;),
&lt;span class="lnr"&gt;12 &lt;/span&gt;  (&lt;span class="Number"&gt;2007&lt;/span&gt;,  &lt;span class="Number"&gt;8&lt;/span&gt;, &lt;span class="String"&gt;'second life'&lt;/span&gt;),
&lt;span class="lnr"&gt;13 &lt;/span&gt;  (&lt;span class="Number"&gt;2008&lt;/span&gt;,  &lt;span class="Number"&gt;8&lt;/span&gt;, &lt;span class="String"&gt;'wer kennt wen'&lt;/span&gt;),
&lt;span class="lnr"&gt;14 &lt;/span&gt;  (&lt;span class="Number"&gt;2009&lt;/span&gt;,  &lt;span class="Number"&gt;6&lt;/span&gt;, &lt;span class="String"&gt;'new moon'&lt;/span&gt;),
&lt;span class="lnr"&gt;15 &lt;/span&gt;  (&lt;span class="Number"&gt;2007&lt;/span&gt;,  &lt;span class="Number"&gt;3&lt;/span&gt;, &lt;span class="String"&gt;'facebook'&lt;/span&gt;),
&lt;span class="lnr"&gt;16 &lt;/span&gt;  (&lt;span class="Number"&gt;2007&lt;/span&gt;,  &lt;span class="Number"&gt;4&lt;/span&gt;, &lt;span class="String"&gt;'dailymotion'&lt;/span&gt;),
&lt;span class="lnr"&gt;17 &lt;/span&gt;  (&lt;span class="Number"&gt;2009&lt;/span&gt;,  &lt;span class="Number"&gt;8&lt;/span&gt;, &lt;span class="String"&gt;'windows 7'&lt;/span&gt;),
&lt;span class="lnr"&gt;18 &lt;/span&gt;  (&lt;span class="Number"&gt;2007&lt;/span&gt;,  &lt;span class="Number"&gt;7&lt;/span&gt;, &lt;span class="String"&gt;'ebuddy'&lt;/span&gt;),
&lt;span class="lnr"&gt;19 &lt;/span&gt;  (&lt;span class="Number"&gt;2009&lt;/span&gt;,  &lt;span class="Number"&gt;9&lt;/span&gt;, &lt;span class="String"&gt;'dantri.com.vn'&lt;/span&gt;),
&lt;span class="lnr"&gt;20 &lt;/span&gt;  (&lt;span class="Number"&gt;2009&lt;/span&gt;, &lt;span class="Number"&gt;10&lt;/span&gt;, &lt;span class="String"&gt;'torpedo gratis'&lt;/span&gt;),
&lt;span class="lnr"&gt;21 &lt;/span&gt;  (&lt;span class="Number"&gt;2009&lt;/span&gt;,  &lt;span class="Number"&gt;3&lt;/span&gt;, &lt;span class="String"&gt;'tuenti'&lt;/span&gt;),
&lt;span class="lnr"&gt;22 &lt;/span&gt;  (&lt;span class="Number"&gt;2008&lt;/span&gt;,  &lt;span class="Number"&gt;1&lt;/span&gt;, &lt;span class="String"&gt;'sarah palin'&lt;/span&gt;),
&lt;span class="lnr"&gt;23 &lt;/span&gt;  (&lt;span class="Number"&gt;2008&lt;/span&gt;,  &lt;span class="Number"&gt;6&lt;/span&gt;, &lt;span class="String"&gt;'obama'&lt;/span&gt;),
&lt;span class="lnr"&gt;24 &lt;/span&gt;  (&lt;span class="Number"&gt;2009&lt;/span&gt;,  &lt;span class="Number"&gt;1&lt;/span&gt;, &lt;span class="String"&gt;'michael jackson'&lt;/span&gt;),
&lt;span class="lnr"&gt;25 &lt;/span&gt;  (&lt;span class="Number"&gt;2007&lt;/span&gt;,  &lt;span class="Number"&gt;1&lt;/span&gt;, &lt;span class="String"&gt;'iphone'&lt;/span&gt;),
&lt;span class="lnr"&gt;26 &lt;/span&gt;  (&lt;span class="Number"&gt;2009&lt;/span&gt;,  &lt;span class="Number"&gt;5&lt;/span&gt;, &lt;span class="String"&gt;'sanalika'&lt;/span&gt;),
&lt;span class="lnr"&gt;27 &lt;/span&gt;  (&lt;span class="Number"&gt;2007&lt;/span&gt;, &lt;span class="Number"&gt;10&lt;/span&gt;, &lt;span class="String"&gt;'club penguin'&lt;/span&gt;),
&lt;span class="lnr"&gt;28 &lt;/span&gt;  (&lt;span class="Number"&gt;2007&lt;/span&gt;,  &lt;span class="Number"&gt;9&lt;/span&gt;, &lt;span class="String"&gt;'hi5'&lt;/span&gt;),
&lt;span class="lnr"&gt;29 &lt;/span&gt;  (&lt;span class="Number"&gt;2009&lt;/span&gt;,  &lt;span class="Number"&gt;2&lt;/span&gt;, &lt;span class="String"&gt;'facebook'&lt;/span&gt;),
&lt;span class="lnr"&gt;30 &lt;/span&gt;  (&lt;span class="Number"&gt;2008&lt;/span&gt;,  &lt;span class="Number"&gt;4&lt;/span&gt;, &lt;span class="String"&gt;'tuenti'&lt;/span&gt;),
&lt;span class="lnr"&gt;31 &lt;/span&gt;  (&lt;span class="Number"&gt;2007&lt;/span&gt;,  &lt;span class="Number"&gt;6&lt;/span&gt;, &lt;span class="String"&gt;'youtube'&lt;/span&gt;),
&lt;span class="lnr"&gt;32 &lt;/span&gt;  (&lt;span class="Number"&gt;2008&lt;/span&gt;,  &lt;span class="Number"&gt;7&lt;/span&gt;, &lt;span class="String"&gt;'nasza klasa'&lt;/span&gt;),
&lt;span class="lnr"&gt;33 &lt;/span&gt;  (&lt;span class="Number"&gt;2008&lt;/span&gt;,  &lt;span class="Number"&gt;3&lt;/span&gt;, &lt;span class="String"&gt;'facebook login'&lt;/span&gt;),
&lt;span class="lnr"&gt;34 &lt;/span&gt;  (&lt;span class="Number"&gt;2009&lt;/span&gt;,  &lt;span class="Number"&gt;7&lt;/span&gt;, &lt;span class="String"&gt;'lady gaga'&lt;/span&gt;),
&lt;span class="lnr"&gt;35 &lt;/span&gt;  (&lt;span class="Number"&gt;2007&lt;/span&gt;,  &lt;span class="Number"&gt;5&lt;/span&gt;, &lt;span class="String"&gt;'webkinz'&lt;/span&gt;),
&lt;span class="lnr"&gt;36 &lt;/span&gt;  (&lt;span class="Number"&gt;2007&lt;/span&gt;,  &lt;span class="Number"&gt;2&lt;/span&gt;, &lt;span class="String"&gt;'badoo'&lt;/span&gt;),
&lt;span class="lnr"&gt;37 &lt;/span&gt;  (&lt;span class="Number"&gt;2008&lt;/span&gt;,  &lt;span class="Number"&gt;5&lt;/span&gt;, &lt;span class="String"&gt;'heath ledger'&lt;/span&gt;),
&lt;span class="lnr"&gt;38 &lt;/span&gt;  (&lt;span class="Number"&gt;2008&lt;/span&gt;, &lt;span class="Number"&gt;10&lt;/span&gt;, &lt;span class="String"&gt;'jonas brothers'&lt;/span&gt;);
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;For SQL Server, a recursive &lt;abbr title="Common Table Expressions"&gt;CTE&lt;/abbr&gt; is good option:&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;
&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="Statement"&gt;WITH&lt;/span&gt;
&lt;span class="lnr"&gt; 2 &lt;/span&gt;  q &lt;span class="Statement"&gt;AS&lt;/span&gt; (
&lt;span class="lnr"&gt; 3 &lt;/span&gt;    &lt;span class="Statement"&gt;SELECT&lt;/span&gt;
&lt;span class="lnr"&gt; 4 &lt;/span&gt;      &lt;span class="Function"&gt;ROW_NUMBER&lt;/span&gt;() &lt;span class="Statement"&gt;OVER&lt;/span&gt;(&lt;span class="Statement"&gt;PARTITION&lt;/span&gt; &lt;span class="Statement"&gt;BY&lt;/span&gt; year &lt;span class="Statement"&gt;ORDER&lt;/span&gt; &lt;span class="Statement"&gt;BY&lt;/span&gt; place) &lt;span class="Statement"&gt;AS&lt;/span&gt; nr,
&lt;span class="lnr"&gt; 5 &lt;/span&gt;      year,
&lt;span class="lnr"&gt; 6 &lt;/span&gt;      query
&lt;span class="lnr"&gt; 7 &lt;/span&gt;    &lt;span class="Statement"&gt;FROM&lt;/span&gt; top_queries
&lt;span class="lnr"&gt; 8 &lt;/span&gt;  ),
&lt;span class="lnr"&gt; 9 &lt;/span&gt;  t &lt;span class="Statement"&gt;AS&lt;/span&gt; (
&lt;span class="lnr"&gt;10 &lt;/span&gt;    &lt;span class="Statement"&gt;SELECT&lt;/span&gt;
&lt;span class="lnr"&gt;11 &lt;/span&gt;      year,
&lt;span class="lnr"&gt;12 &lt;/span&gt;      &lt;span class="Number"&gt;1&lt;/span&gt; &lt;span class="Statement"&gt;AS&lt;/span&gt; query_nr,
&lt;span class="lnr"&gt;13 &lt;/span&gt;      &lt;span class="Function"&gt;CONVERT&lt;/span&gt;(&lt;span class="Type"&gt;varchar&lt;/span&gt;(&lt;span class="Number"&gt;8000&lt;/span&gt;), &lt;span class="String"&gt;''&lt;/span&gt;) &lt;span class="Statement"&gt;AS&lt;/span&gt; queries
&lt;span class="lnr"&gt;14 &lt;/span&gt;    &lt;span class="Statement"&gt;FROM&lt;/span&gt; years
&lt;span class="lnr"&gt;15 &lt;/span&gt;    &lt;span class="Statement"&gt;UNION&lt;/span&gt; &lt;span class="Statement"&gt;ALL&lt;/span&gt;
&lt;span class="lnr"&gt;16 &lt;/span&gt;    &lt;span class="Statement"&gt;SELECT&lt;/span&gt;
&lt;span class="lnr"&gt;17 &lt;/span&gt;      t.year,
&lt;span class="lnr"&gt;18 &lt;/span&gt;      t.query_nr + &lt;span class="Number"&gt;1&lt;/span&gt;,
&lt;span class="lnr"&gt;19 &lt;/span&gt;      &lt;span class="Function"&gt;CONVERT&lt;/span&gt;(&lt;span class="Type"&gt;varchar&lt;/span&gt;(&lt;span class="Number"&gt;8000&lt;/span&gt;),
&lt;span class="lnr"&gt;20 &lt;/span&gt;        t.queries +
&lt;span class="lnr"&gt;21 &lt;/span&gt;        &lt;span class="Statement"&gt;CASE&lt;/span&gt; &lt;span class="Statement"&gt;WHEN&lt;/span&gt; &lt;span class="Function"&gt;LEN&lt;/span&gt;(t.queries) &gt; &lt;span class="Number"&gt;0&lt;/span&gt; &lt;span class="Statement"&gt;THEN&lt;/span&gt; &lt;span class="String"&gt;', '&lt;/span&gt; &lt;span class="Statement"&gt;ELSE&lt;/span&gt; &lt;span class="String"&gt;''&lt;/span&gt; &lt;span class="Statement"&gt;END&lt;/span&gt; +
&lt;span class="lnr"&gt;22 &lt;/span&gt;        q.query
&lt;span class="lnr"&gt;23 &lt;/span&gt;      )
&lt;span class="lnr"&gt;24 &lt;/span&gt;    &lt;span class="Statement"&gt;FROM&lt;/span&gt; t
&lt;span class="lnr"&gt;25 &lt;/span&gt;    &lt;span class="Statement"&gt;INNER&lt;/span&gt; &lt;span class="Statement"&gt;JOIN&lt;/span&gt; q &lt;span class="Statement"&gt;ON&lt;/span&gt;
&lt;span class="lnr"&gt;26 &lt;/span&gt;      q.year = t.year &lt;span class="Statement"&gt;AND&lt;/span&gt;
&lt;span class="lnr"&gt;27 &lt;/span&gt;      q.nr = t.query_nr
&lt;span class="lnr"&gt;28 &lt;/span&gt;  )
&lt;span class="lnr"&gt;29 &lt;/span&gt;&lt;span class="Statement"&gt;SELECT&lt;/span&gt;
&lt;span class="lnr"&gt;30 &lt;/span&gt;  year,
&lt;span class="lnr"&gt;31 &lt;/span&gt;  queries
&lt;span class="lnr"&gt;32 &lt;/span&gt;&lt;span class="Statement"&gt;FROM&lt;/span&gt; t
&lt;span class="lnr"&gt;33 &lt;/span&gt;&lt;span class="Statement"&gt;WHERE&lt;/span&gt;
&lt;span class="lnr"&gt;34 &lt;/span&gt;  query_nr &lt;span class="Statement"&gt;IN&lt;/span&gt; (
&lt;span class="lnr"&gt;35 &lt;/span&gt;    &lt;span class="Statement"&gt;SELECT&lt;/span&gt; &lt;span class="Function"&gt;MAX&lt;/span&gt;(nr) + &lt;span class="Number"&gt;1&lt;/span&gt; &lt;span class="Statement"&gt;FROM&lt;/span&gt; q &lt;span class="Statement"&gt;GROUP&lt;/span&gt; &lt;span class="Statement"&gt;BY&lt;/span&gt; year
&lt;span class="lnr"&gt;36 &lt;/span&gt;  )
&lt;span class="lnr"&gt;37 &lt;/span&gt;&lt;span class="Statement"&gt;ORDER&lt;/span&gt; &lt;span class="Statement"&gt;BY&lt;/span&gt; year;
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;Or maybe, although I never understood how exactly this works, &lt;a href="http://msdn.microsoft.com/en-us/library/ms190922(lightweight).aspx" title="MSDN: Basic Syntax of the FOR XML Clause"&gt;&lt;code&gt;FOR XML&lt;/code&gt; clause&lt;/a&gt;:&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;
&lt;span class="lnr"&gt; 1 &lt;/span&gt;&lt;span class="Statement"&gt;SELECT&lt;/span&gt;
&lt;span class="lnr"&gt; 2 &lt;/span&gt;  year,
&lt;span class="lnr"&gt; 3 &lt;/span&gt;  &lt;span class="Function"&gt;LEFT&lt;/span&gt;(queries, &lt;span class="Function"&gt;LEN&lt;/span&gt;(queries) - &lt;span class="Number"&gt;2&lt;/span&gt;) &lt;span class="Statement"&gt;AS&lt;/span&gt; queries
&lt;span class="lnr"&gt; 4 &lt;/span&gt;&lt;span class="Statement"&gt;FROM&lt;/span&gt; (
&lt;span class="lnr"&gt; 5 &lt;/span&gt;  &lt;span class="Statement"&gt;SELECT&lt;/span&gt;
&lt;span class="lnr"&gt; 6 &lt;/span&gt;    year,
&lt;span class="lnr"&gt; 7 &lt;/span&gt;    (
&lt;span class="lnr"&gt; 8 &lt;/span&gt;      &lt;span class="Statement"&gt;SELECT&lt;/span&gt; q.query + &lt;span class="String"&gt;', '&lt;/span&gt; &lt;span class="Statement"&gt;AS&lt;/span&gt; [&lt;span class="Type"&gt;text&lt;/span&gt;()]
&lt;span class="lnr"&gt; 9 &lt;/span&gt;      &lt;span class="Statement"&gt;FROM&lt;/span&gt; top_queries &lt;span class="Statement"&gt;AS&lt;/span&gt; q
&lt;span class="lnr"&gt;10 &lt;/span&gt;      &lt;span class="Statement"&gt;WHERE&lt;/span&gt; q.year = y.year
&lt;span class="lnr"&gt;11 &lt;/span&gt;      &lt;span class="Statement"&gt;ORDER&lt;/span&gt; &lt;span class="Statement"&gt;BY&lt;/span&gt; q.place
&lt;span class="lnr"&gt;12 &lt;/span&gt;      &lt;span class="Statement"&gt;FOR&lt;/span&gt; &lt;span class="Type"&gt;XML&lt;/span&gt; &lt;span class="Statement"&gt;PATH&lt;/span&gt;(&lt;span class="String"&gt;''&lt;/span&gt;)
&lt;span class="lnr"&gt;13 &lt;/span&gt;    ) &lt;span class="Statement"&gt;AS&lt;/span&gt; queries
&lt;span class="lnr"&gt;14 &lt;/span&gt;  &lt;span class="Statement"&gt;FROM&lt;/span&gt; years &lt;span class="Statement"&gt;AS&lt;/span&gt; y
&lt;span class="lnr"&gt;15 &lt;/span&gt;  &lt;span class="Statement"&gt;GROUP&lt;/span&gt; &lt;span class="Statement"&gt;BY&lt;/span&gt; year
&lt;span class="lnr"&gt;16 &lt;/span&gt;) &lt;span class="Statement"&gt;AS&lt;/span&gt; t
&lt;span class="lnr"&gt;17 &lt;/span&gt;&lt;span class="Statement"&gt;ORDER&lt;/span&gt; &lt;span class="Statement"&gt;BY&lt;/span&gt; year;
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;In PostgreSQL, pretty much the same CTE query would work, but you’re better off with &lt;a href="http://www.postgresql.org/docs/8.4/static/functions-aggregate.html" title="PostgreSQL 8.4: Aggregate Functions"&gt;&lt;code&gt;array_agg&lt;/code&gt;&lt;/a&gt; function:&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;
&lt;span class="lnr"&gt;1 &lt;/span&gt;&lt;span class="Statement"&gt;SELECT&lt;/span&gt;
&lt;span class="lnr"&gt;2 &lt;/span&gt;  y.year,
&lt;span class="lnr"&gt;3 &lt;/span&gt;  &lt;span class="Function"&gt;array_to_string&lt;/span&gt;(&lt;span class="Function"&gt;array_agg&lt;/span&gt;(query), &lt;span class="String"&gt;', '&lt;/span&gt;) &lt;span class="Statement"&gt;AS&lt;/span&gt; queries
&lt;span class="lnr"&gt;4 &lt;/span&gt;&lt;span class="Statement"&gt;FROM&lt;/span&gt; (
&lt;span class="lnr"&gt;5 &lt;/span&gt;  &lt;span class="Statement"&gt;SELECT&lt;/span&gt; * &lt;span class="Statement"&gt;FROM&lt;/span&gt; top_queries &lt;span class="Statement"&gt;ORDER&lt;/span&gt; &lt;span class="Statement"&gt;BY&lt;/span&gt; place &lt;span class="Statement"&gt;DESC&lt;/span&gt;
&lt;span class="lnr"&gt;6 &lt;/span&gt;) &lt;span class="Statement"&gt;AS&lt;/span&gt; q
&lt;span class="lnr"&gt;7 &lt;/span&gt;&lt;span class="Statement"&gt;INNER&lt;/span&gt; &lt;span class="Statement"&gt;JOIN&lt;/span&gt; years &lt;span class="Statement"&gt;AS&lt;/span&gt; y &lt;span class="Statement"&gt;ON&lt;/span&gt; y.year = q.year
&lt;span class="lnr"&gt;8 &lt;/span&gt;&lt;span class="Statement"&gt;GROUP&lt;/span&gt; &lt;span class="Statement"&gt;BY&lt;/span&gt; y.year
&lt;span class="lnr"&gt;9 &lt;/span&gt;&lt;span class="Statement"&gt;ORDER&lt;/span&gt; &lt;span class="Statement"&gt;BY&lt;/span&gt; y.year;
&lt;/pre&gt;&lt;/code&gt;</description><link>http://blog.crt.lv/post/292349654</link><guid>http://blog.crt.lv/post/292349654</guid><pubDate>Mon, 21 Dec 2009 01:01:00 +0200</pubDate><category>SQL</category><category>SQL Server</category><category>PostgreSQL</category></item><item><title>Autocompletion</title><description>&lt;p&gt;Vim has quite a few &lt;a href="http://vimdoc.sourceforge.net/htmldoc/insert.html#ins-completion" title="Vim documentation: Insert mode completion"&gt;features&lt;/a&gt; for automatic text completion. The most basic is &lt;a href="http://vimdoc.sourceforge.net/htmldoc/insert.html#i_CTRL-X_CTRL-N" title="Vim documentation: Completing keywords in current file"&gt;keyword completion&lt;/a&gt; - 1) open a file, 2) write first few characters of any word you see in the file, 3) hit &lt;code&gt;CTRL&lt;/code&gt;+&lt;code&gt;N&lt;/code&gt; to automatically complete the word. Simple, easy to use and very useful.&lt;/p&gt;

&lt;p&gt;To make this feature more intuitive, consider mapping &lt;code&gt;CTRL+Space&lt;/code&gt; to &lt;code&gt;CTRL+N&lt;/code&gt;:&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;
&lt;span class="lnr"&gt;1 &lt;/span&gt;&lt;span class="Statement"&gt;inoremap&lt;/span&gt; &lt;span class="Special"&gt;&lt;&lt;/span&gt;&lt;span class="Special"&gt;C-Space&lt;/span&gt;&lt;span class="Special"&gt;&gt;&lt;/span&gt; &lt;span class="Special"&gt;&lt;&lt;/span&gt;&lt;span class="Special"&gt;C-n&lt;/span&gt;&lt;span class="Special"&gt;&gt;&lt;/span&gt;
&lt;span class="lnr"&gt;2 &lt;/span&gt;&lt;span class="Statement"&gt;inoremap&lt;/span&gt; &lt;span class="Special"&gt;&lt;&lt;/span&gt;&lt;span class="Special"&gt;C-S-Space&lt;/span&gt;&lt;span class="Special"&gt;&gt;&lt;/span&gt; &lt;span class="Special"&gt;&lt;&lt;/span&gt;&lt;span class="Special"&gt;C-p&lt;/span&gt;&lt;span class="Special"&gt;&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/code&gt;</description><link>http://blog.crt.lv/post/282006407</link><guid>http://blog.crt.lv/post/282006407</guid><pubDate>Sun, 13 Dec 2009 21:30:00 +0200</pubDate><category>Vim</category></item><item><title>Generating a Range of Values</title><description>&lt;p&gt;For example, lets generate a set of months, from 2010-01-01 to 2011-01-01.&lt;/p&gt;

&lt;p&gt;In SQL Server:&lt;/p&gt;
&lt;code&gt;&lt;pre&gt;
&lt;span class="lnr"&gt;1 &lt;/span&gt;&lt;span class="Statement"&gt;WITH&lt;/span&gt; t &lt;span class="Statement"&gt;AS&lt;/span&gt; (
&lt;span class="lnr"&gt;2 &lt;/span&gt;  &lt;span class="Statement"&gt;SELECT&lt;/span&gt; &lt;span class="Function"&gt;CONVERT&lt;/span&gt;(&lt;span class="Type"&gt;date&lt;/span&gt;, &lt;span class="Constant"&gt;'2010-01-01'&lt;/span&gt;) &lt;span class="Statement"&gt;AS&lt;/span&gt; d
&lt;span class="lnr"&gt;3 &lt;/span&gt;  &lt;span class="Statement"&gt;UNION&lt;/span&gt; &lt;span class="Statement"&gt;ALL&lt;/span&gt;
&lt;span class="lnr"&gt;4 &lt;/span&gt;  &lt;span class="Statement"&gt;SELECT&lt;/span&gt; &lt;span class="Function"&gt;DATEADD&lt;/span&gt;(&lt;span class="Statement"&gt;MONTH&lt;/span&gt;, &lt;span class="Constant"&gt;1&lt;/span&gt;, d) &lt;span class="Statement"&gt;FROM&lt;/span&gt; t &lt;span class="Statement"&gt;WHERE&lt;/span&gt; d &lt; &lt;span class="Constant"&gt;'2010-12-01'&lt;/span&gt;
&lt;span class="lnr"&gt;5 &lt;/span&gt;)
&lt;span class="lnr"&gt;6 &lt;/span&gt;&lt;span class="Statement"&gt;SELECT&lt;/span&gt; * &lt;span class="Statement"&gt;FROM&lt;/span&gt; t &lt;span class="Statement"&gt;ORDER&lt;/span&gt; &lt;span class="Statement"&gt;BY&lt;/span&gt; d;
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;Same in PostgreSQL:&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;
&lt;span class="lnr"&gt;1 &lt;/span&gt;&lt;span class="Statement"&gt;WITH&lt;/span&gt; &lt;span class="Statement"&gt;RECURSIVE&lt;/span&gt; t &lt;span class="Statement"&gt;AS&lt;/span&gt; (
&lt;span class="lnr"&gt;2 &lt;/span&gt;  &lt;span class="Statement"&gt;SELECT&lt;/span&gt; &lt;span class="Constant"&gt;'2010-01-01'&lt;/span&gt;::&lt;span class="Type"&gt;timestamp&lt;/span&gt; &lt;span class="Statement"&gt;AS&lt;/span&gt; d
&lt;span class="lnr"&gt;3 &lt;/span&gt;  &lt;span class="Statement"&gt;UNION&lt;/span&gt; &lt;span class="Statement"&gt;ALL&lt;/span&gt;
&lt;span class="lnr"&gt;4 &lt;/span&gt;  &lt;span class="Statement"&gt;SELECT&lt;/span&gt; d + &lt;span class="Constant"&gt;'1 months'&lt;/span&gt; &lt;span class="Statement"&gt;FROM&lt;/span&gt; t &lt;span class="Statement"&gt;WHERE&lt;/span&gt; d &lt; &lt;span class="Constant"&gt;'2010-12-01'&lt;/span&gt;
&lt;span class="lnr"&gt;5 &lt;/span&gt;)
&lt;span class="lnr"&gt;6 &lt;/span&gt;&lt;span class="Statement"&gt;SELECT&lt;/span&gt; * &lt;span class="Statement"&gt;FROM&lt;/span&gt; t &lt;span class="Statement"&gt;ORDER&lt;/span&gt; &lt;span class="Statement"&gt;BY&lt;/span&gt; d
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;In PostgreSQL, you can also use &lt;a href="http://www.postgresql.org/docs/8.4/interactive/functions-srf.html" title="PostgreSQL 8.4: Set Returning Functions"&gt;&lt;code&gt;generate_series()&lt;/code&gt;&lt;/a&gt; function, but it’s useful only in these basic cases:&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;
&lt;span class="lnr"&gt;1 &lt;/span&gt;&lt;span class="Statement"&gt;SELECT&lt;/span&gt; * &lt;span class="Statement"&gt;FROM&lt;/span&gt; &lt;span class="Function"&gt;generate_series&lt;/span&gt;(&lt;span class="Constant"&gt;'2010-01-01'&lt;/span&gt;::&lt;span class="Type"&gt;timestamp&lt;/span&gt;, &lt;span class="Constant"&gt;'2010-12-01'&lt;/span&gt;, &lt;span class="Constant"&gt;'1 months'&lt;/span&gt;);
&lt;/pre&gt;&lt;/code&gt;</description><link>http://blog.crt.lv/post/270694768</link><guid>http://blog.crt.lv/post/270694768</guid><pubDate>Sat, 05 Dec 2009 22:31:00 +0200</pubDate><category>SQL</category><category>SQL Server</category><category>PostgreSQL</category></item></channel></rss>

