<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>Technology Bits and Bytes</title>
	<atom:link href="http://blogs.circlesource.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blogs.circlesource.com</link>
	<description>CircleSource Technical Talent ShowCase</description>
	<pubDate>Mon, 22 Sep 2008 18:04:38 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
	<language>en</language>
			<item>
		<title>Trac hack to control email notification to the Reporter</title>
		<link>http://blogs.circlesource.com/2008/09/12/trac-hack-to-control-email-notification-to-the-reporter/</link>
		<comments>http://blogs.circlesource.com/2008/09/12/trac-hack-to-control-email-notification-to-the-reporter/#comments</comments>
		<pubDate>Fri, 12 Sep 2008 11:26:13 +0000</pubDate>
		<dc:creator>satyam</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blogs.circlesource.com/?p=18</guid>
		<description><![CDATA[We implemented Trac with a customized workflow. In our implementation a ticket has many additional states.
Thus during its lifecycle a ticket has to go through several stages. Most of these stages are irrelevant to the reporter of the ticket. He doesnt want to be overwhelemed by email notifications for each and every change to the [...]]]></description>
			<content:encoded><![CDATA[<p>We implemented Trac with a customized workflow. In our implementation a ticket has many additional states.</p>
<p>Thus during its lifecycle a ticket has to go through several stages. Most of these stages are irrelevant to the reporter of the ticket. He doesnt want to be overwhelemed by email notifications for each and every change to the ticket. Our managers used to get complains from clients who were ticket reporters about these notifications. We needed a solution.</p>
<p>One option was to turn off the the reporter notification completely other option was to modify trac&#8217;s default behaviour. The first option was not a good one as the reporters needed some kind of notification when a ticket was created, closed or reopened.</p>
<p>I searched Trac-hacks plugin list to find out something suitable. I couldnot find anything therefore i decided to tweak the Trac myself. It was not at all difficult as Trac has a plugin architecture and I found an api which could solve my problem. I just needed to add and modify few lines.That was it our problem was solved.I named it &#8220;<strong>FlexibleReporterNotification</strong>&#8221; plugin.</p>
<p>I have posted the solution at trac-hacks site so that someone needing similar solution may find it useful. It works on Trac 0.11.</p>
<p>Plugin url :- <a class="alignleft" href="http://trac-hacks.org/wiki/FlexibleReporterNotificationPlugin" target="_blank">http://trac-hacks.org/wiki/FlexibleReporterNotificationPlugin</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.circlesource.com/2008/09/12/trac-hack-to-control-email-notification-to-the-reporter/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Email2trac configuration on windows 2003.</title>
		<link>http://blogs.circlesource.com/2008/08/04/email2trac-configuration-on-windows-2003/</link>
		<comments>http://blogs.circlesource.com/2008/08/04/email2trac-configuration-on-windows-2003/#comments</comments>
		<pubDate>Mon, 04 Aug 2008 15:16:46 +0000</pubDate>
		<dc:creator>satyam</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blogs.circlesource.com/?p=16</guid>
		<description><![CDATA[This post shares our experience of configuring email2trac plugin. ]]></description>
			<content:encoded><![CDATA[<p class="MsoNormal">Trac version 0.11b1</p>
<p class="MsoNormal">OS:-Windows 2003</p>
<p class="MsoNormal">Email client: - Fetchmail</p>
<p class="MsoNormal">Email2trac version: - 0.30</p>
<p class="MsoNormal">Others: - cygwin</p>
<p class="MsoNormal">
<p class="MsoNormal">Through this blog I intend to share our experience of configuring email2trac plugin on windows 2003. We had to make few changes in the original email2trac.py file in order to get it working.</p>
<p class="MsoNormal">
<p class="MsoNormal">We configured this plugin one eventful night a couple of months back. A normal trac plugin takes around 30-40 minutes at max to configure, but this one plugin took one whole night (around 6-7 hrs.).<span> </span>We started off with downloading the plugin and following the install instructions. After completing the instruction set we tried to test the plugin, the test failed we could not create tickets from email. We revisited the instructions to figure out if we had missed out something. We had followed the instructions quite well.</p>
<p class="MsoNormal">
<p class="MsoNormal">After playing around with the configuration files and revisiting the entire setup it was time to look at the code itself (email2trac.py). It took us a couple of hours to understand the code and its flow. Few things in the code did not make sense to us therefore we commented out those added few lines of ours and email2trac was working for us. <span> </span>Following are the things we commented out from email2trac.py</p>
<p class="MsoNormal">
<p class="MsoNormal" style="-0.25in;"><!--[if !supportLists]--><span>1)<span style="normal;"> </span></span><!--[endif]-->Blacklisting section.</p>
<p class="MsoNormal" style="-0.25in;"><!--[if !supportLists]--><span>2)<span style="normal;"> </span></span><!--[endif]-->Attachment Encoding.</p>
<p class="MsoNormal" style="-0.25in;"><!--[if !supportLists]--><span>3)<span style="normal;"> </span></span><!--[endif]-->Check for syslog.</p>
<p class="MsoNormal" style="-0.25in;"><!--[if !supportLists]--><span>4)<span style="normal;"> </span></span><!--[endif]-->Normalization of the file name for the attachment.</p>
<p class="MsoNormal" style="0.25in;">
<p class="MsoNormal">
<p class="MsoNormal">Due to the commenting of the above mentioned sections attachment path was not being generated correctly. To overcome this problem we added the following lines at the end of attachments definition after fd.close (line number 1073.)</p>
<p class="MsoNormal">
<p class="MsoNormal">
<p class="MsoNormal"><span> </span><strong><span>attachmentPath = self.PROJECTPATH + &#8220;/attachments/ticket/&#8221; + str(ticket['id']) + &#8220;/&#8221; + url_filename</span></strong></p>
<p class="MsoNormal"><strong><span> </span></strong></p>
<p class="MsoNormal"><strong><span><span> </span></span></strong></p>
<p class="MsoNormal"><strong><span><span> </span>shutil.copy2 (temppath, attachmentPath)</span></strong></p>
<p class="MsoNormal">
<p class="MsoNormal">
<p class="MsoNormal"><span> </span></p>
<p class="MsoNormal">
<p class="MsoNormal"><span> </span></p>
<p class="MsoNormal" style="0.5in;">Although this fix made the email2trac functional on our trac system, we are still struggling with attachments. We are able to send in zipped files in but the MS office documents get clobbered. We are still working on this and hopefully will resolve it soon at that point I will post another blog here.</p>
<p class="MsoNormal" style="0.5in;">
<p class="MsoNormal" style="0.5in;">In my view if any one wants to implement email2trac on windows they should be willing to make their hands dirty. There is not enough documentation available for this plugin. It is still a UNIX based program which can be made to work on windows with some hacks. <strong><em>Just as in our case we broke away from the program flow to make it work for us.</em></strong></p>
<p class="MsoNormal">
<p class="MsoNormal">
<p class="MsoNormal">
<p class="MsoNormal">Following links are helpful in setting up this plugin on windows.</p>
<p class="MsoNormal">
<p class="MsoNormal"><a href="https://subtrac.sara.nl/oss/email2trac/wiki/Email2tracInstallation/Windows">https://subtrac.sara.nl/oss/email2trac/wiki/Email2tracInstallation/Windows</a></p>
<p class="MsoNormal">
<p class="MsoNormal"><a href="http://functionalelegant.blogspot.com/search/label/Trac">http://functionalelegant.blogspot.com/search/label/Trac</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.circlesource.com/2008/08/04/email2trac-configuration-on-windows-2003/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Be a Miser&#8230;&#8230;&#8230;.</title>
		<link>http://blogs.circlesource.com/2008/07/30/be-a-miser/</link>
		<comments>http://blogs.circlesource.com/2008/07/30/be-a-miser/#comments</comments>
		<pubDate>Wed, 30 Jul 2008 12:52:32 +0000</pubDate>
		<dc:creator>sandeverma</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blogs.circlesource.com/?p=15</guid>
		<description><![CDATA[If a loaf can full your appetite then why to order for two loafs and waste the other one. But to this people call them stereotype of miser that is wealthy and greedy, a man who lives intelligently in order to save and increase his treasure. Same thing I have seen while creating a table [...]]]></description>
			<content:encoded><![CDATA[<p class="MsoNormal" style="normal;"><span>If a loaf can full your appetite then why to order for two loafs and waste the other one. But to this people call them stereotype of miser that is wealthy and greedy, a man who lives intelligently in order to save and increase his treasure. Same thing I have seen while creating a table and columns and assigning the data-types and their sizes, if we can full fill the requirement of the data by providing the accurate or approximate size then it will not only increase the treasure(or in technical terms we used to call performance) but also we can reduce the risk which prevails in any application. If we can use tiny int and get our work done then why to use small int or simple int and burden the database and decrease the performance. Use the best data-type matching your requirement, if it is varchar don&#8217;t just define varchar, but if you know the size define it like varchar(20) or something else. Below are few data-types and the values they accommodate. I know this is the basic of but sometimes these basic things make a major difference. So when ever creating the tables <strong>BE MISER&#8230;</strong> and don&#8217;t <strong>BE SPENDTHRIFT</strong></span></p>
<table class="MsoNormalTable" style="592.5pt;" border="0" cellspacing="0" cellpadding="0" width="790">
<tbody>
<tr>
<td style="82.7pt;" width="110" valign="bottom">
<p class="MsoNormal" style="normal;"><span> </span></p>
<p class="MsoNormal" style="normal;"><strong><span>bigint</span></strong></p>
</td>
<td style="509.8pt;" width="680" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>Integer data from -2^63 through   2^63-1</span></strong></p>
</td>
</tr>
<tr>
<td style="82.7pt;" width="110" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>int</span></strong></p>
</td>
<td style="509.8pt;" width="680" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>Integer data from -2^31 through   2^31 - 1</span></strong></p>
</td>
</tr>
<tr>
<td style="82.7pt;" width="110" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>smallint</span></strong></p>
</td>
<td style="509.8pt;" width="680" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>Integer data from -2^15 through   2^15 - 1</span></strong></p>
</td>
</tr>
<tr>
<td style="82.7pt;" width="110" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>tinyint</span></strong></p>
</td>
<td style="509.8pt;" width="680" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>Integer data from 0 through 255</span></strong></p>
</td>
</tr>
<tr>
<td style="82.7pt;" width="110" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>bit</span></strong></p>
</td>
<td style="509.8pt;" width="680" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>Integer data with either a 1 or 0   value</span></strong></p>
</td>
</tr>
<tr>
<td style="82.7pt;" width="110" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>decimal</span></strong></p>
</td>
<td style="509.8pt;" width="680" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>Fixed precision and scale numeric   data from -10^38 +1 through 10^38 -1</span></strong></p>
</td>
</tr>
<tr>
<td style="82.7pt;" width="110" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>numeric</span></strong></p>
</td>
<td style="509.8pt;" width="680" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>Fixed precision and scale numeric   data from -10^38 +1 through 10^38 -1</span></strong></p>
</td>
</tr>
<tr>
<td style="82.7pt;" width="110" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>money</span></strong></p>
</td>
<td style="509.8pt;" width="680" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>Monetary data values from -2^63   through 2^63 - 1</span></strong></p>
</td>
</tr>
<tr>
<td style="82.7pt;" width="110" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>smallmoney</span></strong></p>
</td>
<td style="509.8pt;" width="680" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>Monetary data values from   -214,748.3648 through +214,748.3647</span></strong></p>
</td>
</tr>
<tr>
<td style="82.7pt;" width="110" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>float</span></strong></p>
</td>
<td style="509.8pt;" width="680" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>Floating precision number data   from -1.79E + 308 through 1.79E + 308</span></strong></p>
</td>
</tr>
<tr>
<td style="82.7pt;" width="110" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>real</span></strong></p>
</td>
<td style="509.8pt;" width="680" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>Floating precision number data   from -3.40E + 38 through 3.40E + 38</span></strong></p>
</td>
</tr>
<tr>
<td style="82.7pt;" width="110" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>datetime</span></strong></p>
</td>
<td style="509.8pt;" width="680" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>Date and time data from January 1,   1753, through December 31, 9999,with an accuracy of 3.33 milliseconds</span></strong></p>
</td>
</tr>
<tr>
<td style="82.7pt;" width="110" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>smalldatetime</span></strong></p>
</td>
<td style="509.8pt;" width="680" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>Date and time data from January 1,   1900, through June 6, 2079,with an accuracy of one minute</span></strong></p>
</td>
</tr>
<tr>
<td style="82.7pt;" width="110" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>char</span></strong></p>
</td>
<td style="509.8pt;" width="680" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>Fixed-length character data with a   maximum length of 8,000 characters</span></strong></p>
</td>
</tr>
<tr>
<td style="82.7pt;" width="110" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>varchar</span></strong></p>
</td>
<td style="509.8pt;" width="680" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>Variable-length data with a   maximum of 8,000 characters</span></strong></p>
</td>
</tr>
<tr>
<td style="82.7pt;" width="110" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>text</span></strong></p>
</td>
<td style="509.8pt;" width="680" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>Variable-length data with a   maximum length of 2^31 - 1 characters</span></strong></p>
</td>
</tr>
<tr>
<td style="82.7pt;" width="110" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>nchar</span></strong></p>
</td>
<td style="509.8pt;" width="680" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>Fixed-length Unicode data with a   maximum length of 4,000 characters</span></strong></p>
</td>
</tr>
<tr>
<td style="82.7pt;" width="110" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>nvarchar</span></strong></p>
</td>
<td style="509.8pt;" width="680" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>Variable-length Unicode data with   a maximum length of 4,000 characters</span></strong></p>
</td>
</tr>
<tr>
<td style="82.7pt;" width="110" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>ntext</span></strong></p>
</td>
<td style="509.8pt;" width="680" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>Variable-length Unicode data with   a maximum length of 2^30 - 1 characters</span></strong></p>
</td>
</tr>
<tr>
<td style="82.7pt;" width="110" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>binary</span></strong></p>
</td>
<td style="509.8pt;" width="680" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>Fixed-length binary data with a   maximum length of 8,000 bytes</span></strong></p>
</td>
</tr>
<tr>
<td style="82.7pt;" width="110" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>varbinary</span></strong></p>
</td>
<td style="509.8pt;" width="680" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>Variable-length binary data with a   maximum length of 8,000 bytes</span></strong></p>
</td>
</tr>
<tr>
<td style="82.7pt;" width="110" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>image</span></strong></p>
</td>
<td style="509.8pt;" width="680" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>Variable-length binary data with a   maximum length of 2^31 - 1 bytes</span></strong></p>
</td>
</tr>
<tr>
<td style="82.7pt;" width="110" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>timestamp</span></strong></p>
</td>
<td style="509.8pt;" width="680" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>A database-wide unique number that   gets updated every time a row gets updated</span></strong></p>
</td>
</tr>
<tr>
<td style="82.7pt;" width="110" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>uniqueidentifier</span></strong></p>
</td>
<td style="509.8pt;" width="680" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>A globally unique identifier</span></strong></p>
</td>
</tr>
<tr>
<td style="82.7pt;" width="110" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>sql_variant</span></strong></p>
</td>
<td style="509.8pt;" width="680" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span>A data type that stores values of   various data types,except text, ntext, timestamp, and sql_variant</span></strong></p>
</td>
</tr>
<tr>
<td style="82.7pt;" width="110" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span> varchar(max)</span></strong></p>
</td>
<td style="509.8pt;" width="680" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span> Maximum 1,073,741,824 characters </span></strong></p>
</td>
</tr>
<tr>
<td style="82.7pt;" width="110" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span> text </span></strong></p>
</td>
<td style="509.8pt;" width="680" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span> Maximum 2GB of text data </span></strong></p>
</td>
</tr>
<tr>
<td style="82.7pt;" width="110" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span> nvarchar(max) </span></strong></p>
</td>
<td style="509.8pt;" width="680" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span> Maximum 536,870,912 characters </span></strong></p>
</td>
</tr>
<tr>
<td style="82.7pt;" width="110" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span> ntext</span></strong></p>
</td>
<td style="509.8pt;" width="680" valign="bottom">
<p class="MsoNormal" style="normal;"><strong><span> Unicode data. Maximum 2GB of text data</span></strong></p>
</td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://blogs.circlesource.com/2008/07/30/be-a-miser/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Step-By-Step setup slicehost server (fedora) for rails application.</title>
		<link>http://blogs.circlesource.com/2008/07/29/step-by-step-setup-slicehost-server-fedora-for-rails-application/</link>
		<comments>http://blogs.circlesource.com/2008/07/29/step-by-step-setup-slicehost-server-fedora-for-rails-application/#comments</comments>
		<pubDate>Tue, 29 Jul 2008 04:08:11 +0000</pubDate>
		<dc:creator>Bhushan Ahire</dc:creator>
		
		<category><![CDATA[Ruby On Rails]]></category>

		<category><![CDATA[Rails]]></category>

		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[server setup]]></category>

		<category><![CDATA[slicehost]]></category>

		<guid isPermaLink="false">http://blogs.circlesource.com/?p=14</guid>
		<description><![CDATA[Hi all as I worked on setting up 4 to 5 servers, I thought its better to document the stuff so that I/developers can refer it, So I am documenting the step-by-step process for setting up the slicehost server for rails application work with nginx as a web server and mongrel as a rails application [...]]]></description>
			<content:encoded><![CDATA[<div>Hi all as I worked on setting up 4 to 5 servers, I thought its better to document the stuff so that I/developers can refer it, So I am documenting the step-by-step process for setting up the slicehost server for rails application work with <strong>nginx</strong> as a web server and <strong>mongrel</strong> as a rails application server.</p>
</div>
<div>
<h2>Update</h2>
<div class="level2">
<p>
 To update your system:
</p>
<blockquote><p>yum update</p></blockquote>
</div>
<h2>MySQL</h2>
<div class="level2">
<p>
 to install mysql client and server apps </p>
<blockquote><p>yum install mysql-server</p></blockquote>
<p>
 The client package “mysql” will automatically be installed as a dependency.
</p>
</div>
<h2>Apache</h2>
<div class="level2">
<blockquote><p>yum install httpd</p></blockquote>
</div>
<h2>PHP5</h2>
<div class="level2">
<p>
 To install php with soap, xml and mysql plugins:
</p>
<blockquote><p>yum install php php-soap php-xml php-mysql </p></blockquote>
<p>
 some other php plugin utilities that are common:
</p>
<blockquote><p>yum install php-mbstring php-gd </p></blockquote>
</div>
<h2>Ruby</h2>
<div class="level2">
<blockquote><p>yum install ruby</p></blockquote>
</div>
<h2>Utilities</h2>
<div class="level2">
<p>
 other useful utilities:
</p>
<blockquote><p>yum install nano wget elinks subversion vi</p></blockquote>
</div>
</div>
<div>
</div>
<div>
<h2>Nginx</h2>
<div class="level2">
<p>
 install nginx web server:
</p>
<blockquote><p>yum install nginx</p></blockquote>
</div>
<h2>Mongrel Cluster</h2>
<div class="level2">
<p>
 install mongrel_cluster:
</p>
<blockquote><p>gem install mongrel_cluster &#8211;include-dependencies</p></blockquote>
</div>
<p>Setup your nginx configuration for your rails application and mongrel_cluster (proxy).</p>
<p>Below you found sample config file for nginx.conf (normally located in &#8220;/etc/nginx/conf/nginx.conf&#8221;)</p>
<blockquote>
<pre>
user  deploy;
worker_processes  1;
error_log   logs/error.log debug;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;
#pid        logs/nginx.pid;
events {
    worker_connections  1024;
}
http {
  include        conf/mime.types;
  default_type   application/octet-stream;
  sendfile        on;
  #tcp_nopush     on;
  keepalive_timeout  65;
  tcp_nodelay        on;
  gzip  on;
  gzip_min_length  1100;
  gzip_buffers     4 8k;
  gzip_types       text/plain;
  upstream mongrel {
    server 127.0.0.1:8000;
    server 127.0.0.1:8001;
  }
  server {
    listen       80;
    server_name  example.com;
    root /var/www/apps/example/current/public;
    index  index.html index.htm;
    location / {
      proxy_set_header  X-Real-IP  $remote_addr;
      proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_redirect false;
      if (-f $request_filename/index.html) {
        rewrite (.*) $1/index.html break;
      }
      if (-f $request_filename.html) {
        rewrite (.*) $1.html break;
      }
      if (!-f $request_filename) {
        proxy_pass http://mongrel;
        break;
      }
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }
  }
}
</pre>
</blockquote>
</div>
<p>Restart the nginx server:</p>
<blockquote><p>/etc/init.d/nginx restart</p></blockquote>
<div>
<h2>Mongrel Configuration:</h2>
<p>Now Go to the application directory and create a configuration for Mongrel:</p>
<blockquote><p>
mongrel_rails cluster::configure -e production -p 8000 -a 127.0.0.1 -N 2 -c /home/APP/production/APP/current
</p></blockquote>
<p>it will create the config/mongrel_cluster.yml file; basically you do not need to edit it.</p>
<p>You can test cluster with</p>
<p>To Start:</p>
<blockquote><p>mongrel_rails cluster::start</p></blockquote>
<p>To Stop:</p>
<blockquote><p>mongrel_rails cluster::stop</p></blockquote>
<p>To Restart:</p>
<blockquote><p>mongrel_rails cluster::restart</p></blockquote>
</div>
<div>
<h2>Capistrano Configuration:</h2>
<p>Then create a configuration for Capistrano:</p>
<blockquote><p>cap –apply-to . </p></blockquote>
<p>we need to modify the generated file config/deploy.rb:</p>
<blockquote><pre>
require 'mongrel_cluster/recipes'

#you set the APP name with the cap command
set :application, "APP"
#a path to your repository
set :repository, "svn+ssh://USERNAME@SVN_SERVER/projects/#{application}/trunk"

role :web, "SERVER"
role :app, "SERVER"
role :db, "SERVER", :primary =&gt; true

#where to deploy (copy the files) on the server; I created a special user APP for the application (if you do not like it, replace the /home/#{application} part with your path
set :deploy_to, "/home/#{application}/production/#{application}"
set :mongrel_conf, "#{current_path}/config/mongrel_cluster.yml"
#if the server login name is different to the development computer login name; in my case the user name is the APP name
set :user, "APP"
</pre>
</blockquote>
<p>Make necessary changes to the config/database.yml file.</p>
</div>
<div>
<h2>Capistrano Deployment:</h2>
<p>Create the basic structure on the server:</p>
<blockquote><p>cap deploy:setup </p></blockquote>
<p>For the first deployment you can use cold deploy:</p>
<blockquote><p>cap cold_deploy</p></blockquote>
<p>After that for next deployments you have to use:</p>
<blockquote><p>cap deploy</p></blockquote>
<p>You can also run migration from capistrano with:</p>
<blockquote><p>cap deploy:migrate<sup>*</sup></p></blockquote>
<p><sup>*</sup> Note: It wont work for me, it migrating to the previous release available in the releses folder, So I suggest you manually run migration on server.</p>
</div>
<div>
<p>That&#8217;s it, your server is ready to run.<br />
      Hope this documentation will be helpful to you, Enjoy ;-).</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blogs.circlesource.com/2008/07/29/step-by-step-setup-slicehost-server-fedora-for-rails-application/feed/</wfw:commentRss>
		</item>
		<item>
		<title>How to use Google Apps mail configuration with rails application.</title>
		<link>http://blogs.circlesource.com/2008/07/28/how-to-use-google-apps-mail-configuration-with-rails-application/</link>
		<comments>http://blogs.circlesource.com/2008/07/28/how-to-use-google-apps-mail-configuration-with-rails-application/#comments</comments>
		<pubDate>Mon, 28 Jul 2008 04:06:52 +0000</pubDate>
		<dc:creator>Bhushan Ahire</dc:creator>
		
		<category><![CDATA[Ruby On Rails]]></category>

		<category><![CDATA[google apps]]></category>

		<category><![CDATA[mail conf]]></category>

		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://blogs.circlesource.com/?p=13</guid>
		<description><![CDATA[I am using google apps for my domain www.bhushangahire.com
For one of my rails application I am using this domain mail account setup for sending mails.
But I am not able to send the mail with the default smtp setings we use for sending mail.
So I search on net and I found the Goggle Apps consider its [...]]]></description>
			<content:encoded><![CDATA[<p>I am using google apps for my domain <strong>www.bhushangahire.com</strong></p>
<p>For one of my rails application I am using this domain mail account setup for sending mails.<br />
But I am not able to send the mail with the default smtp setings we use for sending mail.</p>
<p>So I search on net and I found the Goggle Apps consider its in different way. Which is TLS ans SSH service, which is not by default comes with the Action mailler.</p>
<p class="vspace"><span class="wikiword">ActionMailer</span> can&#8217;t send emails using <span class="wikiword">GMail</span> out of the box. To add this functionality do the following configuration in your rails application:</p>
<ol>
<li>Create the file <strong><code>lib/smtp_tls.rb</code></strong>
<div class="code">
<pre>require "openssl"
require "net/smtp"

Net::SMTP.class_eval do
private
def do_start(helodomain, user, secret, authtype)
raise IOError, 'SMTP session already started' if @started
check_auth_args user, secret, authtype if user or secret

sock = timeout(@open_timeout) { TCPSocket.open(@address, @port) }
@socket = Net::InternetMessageIO.new(sock)
@socket.read_timeout = 60 #@read_timeout

check_response(critical { recv_response() })
do_helo(helodomain)

raise 'openssl library not installed' unless defined?(OpenSSL)
starttls
ssl = OpenSSL::SSL::SSLSocket.new(sock)
ssl.sync_close = true
ssl.connect
@socket = Net::InternetMessageIO.new(ssl)
@socket.read_timeout = 60 #@read_timeout
do_helo(helodomain)

authenticate user, secret, authtype if user
@started = true
ensure
unless @started
# authentication failed, cancel connection.
@socket.close if not @started and @socket and not @socket.closed?
@socket = nil
end
end

def do_helo(helodomain)
begin
if @esmtp
ehlo helodomain
else
helo helodomain
end
rescue Net::ProtocolError
if @esmtp
@esmtp = false
@error_occured = false
retry
end
raise
end
end

def starttls
getok('STARTTLS')
end

def quit
begin
getok('QUIT')
rescue EOFError
rescue OpenSSL::SSL::SSLError
end
end
end</pre>
</div>
</li>
<li>Add the following lines to <strong><code>config/environment.rb</code></strong> and replace the values with the appropriate username and password:
<div class="code">
<pre>require 'smtp_tls'
ActionMailer::Base.perform_deliveries = true
ActionMailer::Base.raise_delivery_errors = true
ActionMailer::Base.server_settings = {
:address =&gt; "smtp.gmail.com",
:port =&gt; 587,
:domain =&gt; "mydomain.com",
:authentication =&gt; :plain,
:user_name =&gt; "username@mydomain.com",
:password =&gt; "password"
}</pre>
</div>
<p><strong><sup>*</sup>Note:</strong>To work your domain with <strong>&#8220;mydomain.com&#8221;</strong> you have to configure your <strong>MX records</strong> to work Gmail mail sending functionality out of box.</p>
<p>Else you can use a temporary address <strong>@mydomain.com.test-google-a.com</strong>, I have not tested with this as I have already configure my <strong>MX records</strong>.</p>
<p>You can get more information on changing <strong><a href="http://www.google.com/support/a/bin/answer.py?answer=33352">http://www.google.com/support/a/bin/answer.py?answer=33352</a></strong>.</p>
<p>Hope this information is useful to you. <img src='http://blogs.circlesource.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://blogs.circlesource.com/2008/07/28/how-to-use-google-apps-mail-configuration-with-rails-application/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Thickbox, Rails and SSL</title>
		<link>http://blogs.circlesource.com/2008/07/23/thickbox-rails-and-ssl/</link>
		<comments>http://blogs.circlesource.com/2008/07/23/thickbox-rails-and-ssl/#comments</comments>
		<pubDate>Wed, 23 Jul 2008 15:53:06 +0000</pubDate>
		<dc:creator>Aditya</dc:creator>
		
		<category><![CDATA[Ruby On Rails]]></category>

		<category><![CDATA[Rails]]></category>

		<category><![CDATA[SSL]]></category>

		<category><![CDATA[Thickbox]]></category>

		<guid isPermaLink="false">http://blogs.circlesource.com/?p=11</guid>
		<description><![CDATA[Couple of months back, one of our clients requested an enhancement - To show some parts of the application in pop ups. I told him it would be pretty easy. I gave him the link of Redbox and said we have done this many times, it should be easy. His reply was… “Scroll up and [...]]]></description>
			<content:encoded><![CDATA[<p>Couple of months back, one of our clients requested an enhancement - To show some parts of the application in pop ups. I told him it would be pretty easy. I gave him the link of <a href="http://www.craigambrose.com/redbox_demo">Redbox</a> and said we have done this many times, it should be easy. His reply was… “Scroll up and down the pages, the pop up doesn’t seem to be moving with the page” . I said “Yes, it doesn’t”. He said he wants that to happen.</p>
<p>After looking around for next couple of hours, I came across <a href="http://jquery.com/demo/thickbox/">Thickbox</a>. Now how could I miss this at the first place. It was what I exactly wanted for sometime now. And it had support for iframe also. So I went ahead and downloaded the required files namely jquery-latest.js, thickbox.js and thickbox.css. For those who don’t know about <a href="http://jquery.com/">jquery</a> – Jquery is a Javascript library to handle browser events, add AJAX features to your application etc. In next 15 minutes I was ready with the sample code to check if things really work and to my disappointment it didn’t work and moreover my existing AJAX features broke.  When I opened the jquery library I found that it also uses ‘$’ like prototype.js, hence a conflict.</p>
<p>The solution for this problem is described <a href="http://docs.jquery.com/Using_jQuery_with_Other_Libraries">here</a>.</p>
<p>After making the required changes it worked. I was happy, client was happy until one fine day SSL came into picture. I use nginx as my web server and had done SSL setup before. I could setup the SSL but when I clicked one of the links which use thickbox to open up the popup, it just opened the content of the popup on a new page. After playing with the code from sometime I found that the j-query file gets truncated because its too big and also the page takes lot of time to download.</p>
<p>Jquery provides a compact version of its library. Using this file solved my problem.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.circlesource.com/2008/07/23/thickbox-rails-and-ssl/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Hosting Rails Web Application on Amazon EC2</title>
		<link>http://blogs.circlesource.com/2008/07/23/hosting-web-application-on-amazon-ec2/</link>
		<comments>http://blogs.circlesource.com/2008/07/23/hosting-web-application-on-amazon-ec2/#comments</comments>
		<pubDate>Wed, 23 Jul 2008 11:21:16 +0000</pubDate>
		<dc:creator>relton</dc:creator>
		
		<category><![CDATA[Ruby On Rails]]></category>

		<category><![CDATA[EC2]]></category>

		<category><![CDATA[EC2 and Rails]]></category>

		<category><![CDATA[Hosting Web Application]]></category>

		<guid isPermaLink="false">http://blogs.circlesource.com/?p=9</guid>
		<description><![CDATA[I have my Ruby on Rails application running on EC2.
EC2 is a web service that helps in elastic computation across the web. It is elastic because the computation is very resizable. When compared with Plain Hosting it provides the following advantages:

 Unlike traditional hosting services EC2 provides resources that can be used unlimitedly,
 EC2 provides [...]]]></description>
			<content:encoded><![CDATA[<p>I have my Ruby on Rails application running on EC2.</p>
<p style="0cm;">EC2 is a web service that helps in elastic computation across the web. It is elastic because the computation is very resizable. When compared with Plain Hosting it provides the following advantages:</p>
<ul>
<li> Unlike traditional hosting services EC2 provides resources that can be used unlimitedly,</li>
<li> EC2 provides full control on the resource where in the entire resource configurations can be manipulated according to the users requirement and</li>
<li> EC2’s service doesn’t require users to pay a fixed, up-front fee irrespective of their actual computing power used but instead the pay is very dynamic and the computed based on the usage of the resource.</li>
</ul>
<p style="0cm;">The usage of the EC2 image becomes easier if ruby on rails application is to be hosted. As rails provide gems for additional utilities, it provides a gem called as “ec2onrails” that makes the hosting even simpler.</p>
<p style="0cm;">The following are the steps in using the EC2 image:</p>
<ul>
<li>
<p style="0cm;">Install the gem – gem install 	ec2onrails</p>
</li>
</ul>
<ul>
<li>
<p style="0cm;">Add the configuration files to the 	rails application – There are 3 files that is essential in order 	to use the image:</p>
<ul>
<li>
<p style="0cm;">Capfile – The Capistrano file 		that includes the line, require &#8216;ec2onrails/recipes&#8217; in addition to 		the existing config details. This makes the ec2onrails libraries 		available during deployment.</p>
</li>
<li>
<p style="0cm;">S3.yml – Instance stores appear to an instance as a local disk. 		They just survive intentional and unintentional reboots of the 		instance unless the instance terminates or the underlying drive 		fails. Hence the backup or replication of important data is very 		essential and it happens in Amazon S3. This happens using the 		configurations in this S3.yml file. The details comprises of 		aws_access_key, aws_secret_access_key and bucket_base_name.<span style="Courier New,monospace;"><span style="x-small;"> </span></span>aws_access_key and aws_secret_access_key are the keys 		received at the time of creating an account with Amazon EC2 and 		bucket_base_name is the name of the bucket into which the data 		needs to be stored.</p>
</li>
<li>
<p style="0cm;">deploy.rb – This is the 		deployment file containing the Capistrano configurations for 		ec2onrails.</p>
</li>
</ul>
</li>
</ul>
<ul>
<li>
<p style="0cm;">Start the instance of the image – 	The instance can be started as follows:</p>
<ul>
<li>
<p style="0cm;">Signup for Amazon EC2 and S3 to 		acquire the necessary authentication credentials – The necessary 		authentication credentials are the privacy encoded mail security 		X509 certificate, privacy encoded mail security private key file 		and the account ID.</p>
</li>
<li>
<p style="0cm;">Installing the EC2 Tools – This 		basically involves no installation as such because all what is 		required is to get the tools downloaded from the EC2 site, unzip it 		into a folder. The unzipped files are the pre-installed files, 		hence to make the tools visible, an environment variable – 		EC2_HOME is set with the path to the EC2 tools folder. Apart from 		this we need to tell the tools for whom it is going to be used for 		by setting two more environment variables such as EC2_PRIVATE_KEY 		and EC2_CERT containing the paths of the private key file and X509 		certificate.</p>
</li>
<li>
<p style="0cm;">Start running the instance – 		All what we are left now is with running the instance. In order to 		run the instance we need to do the following:</p>
<ul>
<li>
<p style="0cm;">Find a suitable AMI(Amazon 			Machine Image) – This happens to be the crucial step. Why I say 			that this is a crucial one is because on executing the command: 			ec2-describe-images –o self –o amazon, it will list all the 			available images. We need to pick the most stable image that will 			suffice our purpose. This is where I initially went wrong. What I 			did was, I chose an image without reading the name of the image 			file, which happened to be a very unstable one and hence had to 			install all the required software manually which had dependencies 			issue and as a result of this I had to spend several additional 			hours in the setup process. But realized pretty early that I was 			in the wrong track and then chose the right one. So how do we 			choose the right image? In the listing we need to look for 			developer-image which is public and available and make a note of 			the ami ID(something like ami-xxxxxxxx).</p>
</li>
<li>
<p style="0cm;">Generating the key pair – The 			privacy enhanced mail security files is used for all the 			interactions with the image but each and every time we interact we 			need to use then in our command with various options. This can be 			avoided by generating key pair out of the two security files and 			use this key pair for all the usage. In order to generate the key 			pair execute the command: ec2-add-keypair &lt;name&gt;. The name 			can be anything and this list a key pair which needs to be stored 			in a file with the name of our choice.</p>
</li>
<li>
<p style="0cm;">Run the instance – On 			executing: “ec2-run-instance ami-xxxxxxxx key_pair_filename”, 			the instance starts running. But it takes long time to start. This 			is because Amazon EC2 moves the images around the network before 			they can be launched. For big images and/or congested networks, 			this takes several minutes. To improve performance, images can be 			cached. As you launch your images more frequently, it becomes less 			noticeable.</p>
</li>
<li>
<p style="0cm;">Authorize Network Access o the 			instance – The instance uses port 80 and 22 which can be 			authorized by executing: “<span>ec2-authorize 			default -p 22”</span> and “<span>ec2-authorize 			default -p 80”. If your application requires nay other port for 			access, it can be done the same way.</span></p>
</li>
</ul>
</li>
</ul>
</li>
<li>
<p style="0cm;">Fetch the Public key – The 	Capistrano deployment requires the public key of the server which 	can be fetched by executing: “<span>cap 	ec2onrails:get_public_key_from_server”</span></p>
</li>
<li>
<p style="0cm;">Finally deploy the application 	with Capistrano – Firstly setup the ec2onrails Capistrano 	deployment by saying, <span>cap ec2onrails:setup</span> and then the first deployment can be done by executing, <span>cap 	deploy:cold</span> and for the later successive deployments just 	use, cap deploy. Apart from this the Capistrano with ec2onrails 	provides <span>cap ec2onrails:db:archive</span> and <span>cap 	ec2onrails:db:restore</span>. They can be explicitly executed for 	archiving and restoring the data for the database. But on the cold 	deploy execution the ec2 instance starts the incremental archiving 	of the data using the predefined cron jobs.</p>
</li>
</ul>
<p><strong><em>We now have our application hosted on EC2. Yes, it is that easy.</em><br />
</strong></p>
<p>The only question that one would have in his/her mind now is, what will happen if my instance or the ec2 server terminates? Once the server terminates, the instance is lost and can never be got back. This is one feature that ec2 lacks. But it provides a solution to handle such situation.</p>
<p style="0cm;">There is something called as bundling of the image. On bundling the image, the instance configuration and the application is uploaded to the S3 which can then be register to another instance and the application can be in form again. This can be achieved as follows:</p>
<p style="0cm;">Prepare for bundling – The server requires the two privacy enhanced mail security files. This can be got by using scp command.</p>
<p><em>Example - <span>scp pk-xxyyzz.pem cert-xxyyzz.pem root@ec2-xx-xxx-xx-xxx.compute-1.amazonaws.com:/mnt -i keypair_file_name</span></em></p>
<p style="0cm;">Bundle the current image – From the ec2 instance bundle the image.</p>
<p><em>Example - <span>ec2-bundle-vol -d /mnt -k /mnt/pk-xxyyzz.pem -c /mnt/cert-xxyyzz.pem -u account_number -r i386</span></em></p>
<p style="0cm;">Upload the AMI – The AMI is then uploaded to S3.</p>
<p><em><span>Example - ec2-upload-bundle -b bucket_name -m /mnt/image.manifest.xml -a access_key_id -s secret_access_key</span></em></p>
<p style="0cm;">Register the Uploaded image – The image needs to be register from the local system and can be done as:<span> ec2-register bucket</span><span>_name/image.manifest.xml</span></p>
<p style="0cm;">This gives an ami ID with which the instance can be run.</p>
<p style="0cm;"><strong><em>EC2 - a quick and cost effective way of hosting Web Applications.</em></strong></p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.circlesource.com/2008/07/23/hosting-web-application-on-amazon-ec2/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Generating random Date/Time between 2 different Dates/TimeStamps in Java</title>
		<link>http://blogs.circlesource.com/2008/07/17/generating-random-datetime-between-2-different-datestimestamps-in-java/</link>
		<comments>http://blogs.circlesource.com/2008/07/17/generating-random-datetime-between-2-different-datestimestamps-in-java/#comments</comments>
		<pubDate>Thu, 17 Jul 2008 13:34:10 +0000</pubDate>
		<dc:creator>Nivasini</dc:creator>
		
		<category><![CDATA[Java]]></category>

		<category><![CDATA[Random dates]]></category>

		<guid isPermaLink="false">http://blogs.circlesource.com/?p=8</guid>
		<description><![CDATA[It is common to find a random number between 2 given numbers&#8230; In our java application that we are working on, We had a need to find a random time between two given timestamp.. We felt it little challenging in the beginning&#8230; But later figured out a simple solution for the same&#8230; The steps for [...]]]></description>
			<content:encoded><![CDATA[<p>It is common to find a random number between 2 given numbers&#8230; In our java application that we are working on, We had a need to find a random time between two given timestamp.. We felt it little challenging in the beginning&#8230; But later figured out a simple solution for the same&#8230; The steps for generating a random time between 2 timestamps really turned out to be very simple &amp; this article is about how we achieved that&#8230;</p>
<p>If min and max are the 2 variables that are holding minimum and maximum values, &amp; random is the random number that is to be generated, in java the random number is calculated in this way&#8230;<br />
<strong><code><br />
random = (Math.random() * (max - min) ) + min<br />
</code></strong></p>
<p>Here <strong>Math.random()</strong> is a function in java that generates any random value between 0 &amp; 1&#8230; We multiply that with the difference between max &amp; min values and finally add the obtained result with the min value to get a random number between 2 given numbers.. This idea was set as the basement for our requirement too&#8230; Wondering how?? This is how it goes&#8230;</p>
<p>We use <strong>Calendar</strong> object which defaults to current date and time. We then set Hour, minute &amp; second in the same object(If required we can set the year, month &amp; date too).. Now we have the Calendar object with the date what we set or current date and time. Calendar class has a method named <strong>getTimeInMillis</strong> which will convert this timeStamp to a long value. This long value serves as the first min variable as in the example where we generate a random number between 2 different numbers.</p>
<p>Now in the same way we get the long value of the second timestamp too which is the max variable value. Using a similar calculation as above we get a random long number between 2 different long numbers which are the long time. Finally we construct the date object with the long value that we obtained.. This date object&#8217;s value is the random time stamp between 2 different Calendar objects and hence the we can generate random date/time between two different Calendar objects!!!!   <img src='http://blogs.circlesource.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Here goes the code for that..<br />
<strong><code><br />
//code to generate random timestamp between morning 6 to evening 8 pm<br />
public static void main(String args[]){<br />
Calendar cdr = Calendar.getInstance();<br />
cdr.set(Calendar.HOUR_OF_DAY, 6);<br />
cdr.set(Calendar.MINUTE, 0);<br />
cdr.set(Calendar.SECOND, 0);<br />
long val1=cdr.getTimeInMillis();<br />
</code></p>
<p><code><br />
cdr.set(Calendar.HOUR_OF_DAY, 20);<br />
cdr.set(Calendar.MINUTE, 0);<br />
cdr.set(Calendar.SECOND, 0);<br />
long val2=cdr.getTimeInMillis();<br />
</code></p>
<p><code><br />
Random r=new Random();<br />
long randomTS=(long)(r.nextDouble()*(val2-val1))+val1;<br />
Date d=new Date(randomTS);<br />
System.out.println(d.toString());<br />
}<br />
</code></strong><br />
<strong>PS: This will work even for generating random date between two different dates which can be a month/year gap.</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.circlesource.com/2008/07/17/generating-random-datetime-between-2-different-datestimestamps-in-java/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Complex SQL queries with Hibernate</title>
		<link>http://blogs.circlesource.com/2008/07/11/complex-sql-queries-with-hibernate/</link>
		<comments>http://blogs.circlesource.com/2008/07/11/complex-sql-queries-with-hibernate/#comments</comments>
		<pubDate>Fri, 11 Jul 2008 07:58:19 +0000</pubDate>
		<dc:creator>Samanth</dc:creator>
		
		<category><![CDATA[Java]]></category>

		<category><![CDATA[Hibernate]]></category>

		<guid isPermaLink="false">http://blogs.circlesource.com/?p=7</guid>
		<description><![CDATA[The topic of discussion in this would not be to explain what Hibernate is or its architecture or performance issues. The reader should have a minimum knowledge of how an ORM works and Java.
One of the main reasons to move to Hibernate is to improve performance of the entire application. Traditional JDBC application is expensive [...]]]></description>
			<content:encoded><![CDATA[<p><strong>The topic of discussion in this would not be to explain what Hibernate is or its architecture or performance issues. The reader should have a minimum knowledge of how an ORM works and Java.</strong></p>
<p>One of the main reasons to move to Hibernate is to improve performance of the entire application. Traditional JDBC application is expensive and a complex job for any developer (if no DBA is available) to write the SQL queries. The developer first has to get a connection to the Database, create a Statement/PreparedStatement, ResultSets and iterate the ResultSet and embed the values into the ValueObjects (VO). Once done, the developer must ensure to close all the resources that were open during this process.</p>
<p>How does Hibernate eliminate all these? Hibernate requires only a DataSource to be specified and all the work of opening a connection, creating statements and executing these queries are the dirty job done by Hibernate. This shall be point of discussion in the later posts.</p>
<p>Let&#8217;s take a complex SQL query and convert them to Hibernate and see its advantages.</p>
<p>SQL Query:<br />
<code><br />
select modality_type,<br />
count(case when scheduled_ts &gt;= DATE(NOW()) and scheduled_ts &lt; DATE(NOW() + INTERVAL 1 DAY )<br />
and hospital_id= 'BS' then scheduled_ts else NULL END ) as scheduled,<br />
count(case when completed_ts != '0000-00-00 00:00:00'<br />
and scheduled_ts &gt;= DATE(NOW()) and scheduled_ts &lt; DATE(NOW() + INTERVAL 1 DAY )<br />
and hospital_id= 'BS' then completed_ts else NULL END) as completed<br />
from order_status where modality_type in ('CT','DX','NM','US','IR','MR','PX','VA')<br />
group by modality_type<br />
</code></p>
<p>This query is a typical Cross-tab/Pivot query. The query results in showing three columns - Modality Type, Count of Exams Scheduled for today and Count of Exams completed for the day which is grouped by Modality Type.</p>
<p>Let&#8217;s see how this is done with Hibernate.</p>
<p>1. Create a value object/java bean<br />
Lets call our VO as CompletedAgainstScheduled</p>
<p><strong>Note: For easier understanding I&#8217;ll show only a few snippets</strong></p>
<p><code><br />
/**<br />
* @hibernate.class table="order_status" lazy="false"<br />
*/<br />
public class CompletedAgainstScheduled implements Serializable {<br />
private Long id;<br />
private String hospitalId;<br />
private String modalityType;<br />
private String completedTimestamp;<br />
private String scheduledTimestamp;<br />
private int completed;<br />
private int scheduled;<br />
private int interpretedBy;<br />
</code></p>
<p><code><br />
/**<br />
* @return<br />
*<br />
* @hibernate.meta attribute="id" value="ID"<br />
* @hibernate.id type="long" column="id" generator-class="native"<br />
*/<br />
public Long getId() {<br />
return id;<br />
}<br />
public void setId(Long id) {<br />
this.id = id;<br />
}<br />
<code><br />
/** other setter and getters with hibernate mapping */<br />
</code><br />
&#8230;..<br />
<code><br />
/**<br />
* get and set completed orders<br />
*<br />
* @return<br />
*<br />
* @hibernate.meta attribute="completedTimestamp" value="Completed Timestamp"<br />
* @hibernate.property column="completed_ts" formula="case when completed_ts != '0000-00-00 00:00:00' then completed_ts else null end"<br />
*/<br />
public String getCompletedTimestamp() {<br />
return completedTimestamp;<br />
}<br />
public void setCompletedTimestamp(String completedTimestamp) {<br />
this.completedTimestamp = completedTimestamp;<br />
}<br />
}<br />
</code></p>
<p>For better understanding I&#8217;ve used XDoclet for Hibernate mapping.</p>
<p>When this class is compiled (using maven and xdoclet-plugin), it creates the Hibernate mapping file automatically.</p>
<p>So what is this class doing?<code> @hibernate.class table="order_status"</code> says that this VO is mapped to the table order_status in our database.</p>
<p><code>@hibernate.meta attribute="completedTimestamp" value="Completed Timestamp"<br />
@hibernate.property column="completed_ts" formula="case when completed_ts != '0000-00-00 00:00:00' then completed_ts else null end"</code></p>
<p>The <code>@hibernate.meta</code> is basically for API Documentation and <code>@hibernate.property column="completed_ts"</code> is mapped to the attribute <code>completedTimestamp</code> in the Value Object.</p>
<p>Here is a very interesting concept: <code>formula="case when completed_ts != '0000-00-00 00:00:00' then completed_ts else null end"</code><br />
Why do this at all? Value Objects are <strong>ALWAYS</strong> mapped to a table and its attributes to columns. In the above Cross-tab query, we are deriving columns that are not in the table. Hence the formula on what should be done. We are counting number of rows for completed_ts that is not equal to &#8220;0000-00-00 00:00:00&#8243;. This formula will be embedded within the count() function.</p>
<p><strong>NOTE: The case when.. is compatible only with MySQL and Oracle.</strong></p>
<p>2. Hibernate Query<br />
This section covers how the query is built in the DAO layer</p>
<p><code> Criteria criteria = getSession().createCriteria(CompletedAgainstScheduled.class)<br />
.setProjection(<br />
Projections.projectionList()<br />
.add(Projections.groupProperty("modalityType").as("modalityType"))<br />
.add(Projections.count("scheduledTimestamp").as("scheduled"))<br />
.add(Projections.count("completedTimestamp").as("completed"))<br />
)//.add(Restrictions.in("modalityType", modArr))<br />
.add(Expression.ge("scheduledTimestamp", sdf.format(c.getTime())))<br />
.add(Expression.lt("scheduledTimestamp", sdf.format(cd.getTime())))<br />
.add(Expression.eq("hospitalId", hospitalId));</code><br />
<code><br />
List csList = null;<br />
if (criteria != null) {<br />
csList = criteria.setResultTransformer(new AliasToBeanResultTransformer(CompletedAgainstScheduled.class)).list();<br />
}<br />
</code><br />
We have a ProjectionList that has modalityType (the column on which the resultSet should be grouped), scheduledTimestamp and completedTimestamp (the column that should be counted). Note that the attributes we are providing in the criteria. These are the attributes from the VO not the actual column names. This is what we call as HQL (Hibernate Query Language). When Hibernate complies this criteria, it generates a SQL dynamically and executes this at the database and returns a list of Objects which is of type CompletedAgainstScheduled.</p>
<p>Now, let&#8217;s do a little bit of post-mortem on how this Hibernate and SQL Query:</p>
<p><code>.add(Projections.groupProperty("modalityType").as("modalityType"))<br />
.add(Projections.count("scheduledTimestamp").as("scheduled"))<br />
.add(Projections.count("completedTimestamp").as("completed"))</code></p>
<p>is equivalent to</p>
<p><code>select modality_type,<br />
count(scheduled_ts) as scheduled, count(completed_ts) as completed</code></p>
<p>We know that completedTimestamp is mapped to completed_ts in the table and returns an integer. But the column completed_ts itself is a datetime column. So, what happens to the integer? Well, the Projection says that count(completedTimestamp) which is mapped to completed_ts based on the formula we have specified in the VO and store the result in the completed attribute of the VO. Simple?</p>
<p>We can add as many expression as possible using the Expression class.</p>
<p>Once the query is executed, it returns a list of Objects which we have stored in csList. How does Hibernate know what and how to map? The ResultTransformer class does this job. It uses a sub-class called AliasToBeanResultTransformer class which is called for every row in the ResultSet and maps them to our VO.</p>
<p>That&#8217;s it. Very simple and intelligent.</p>
<p>If you have any doubts, do not hesitate to ask your questions.</p>
<p>In the next few series we&#8217;ll explore, Why Hibernate, XDoclets, Associations  and other Hibernate related challenges.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.circlesource.com/2008/07/11/complex-sql-queries-with-hibernate/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
