<?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"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>2Paths &#187; Utilities</title>
	<atom:link href="http://www.2paths.com/category/blog/tech/utilities/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.2paths.com</link>
	<description>Custom Software Technical Architecture, Design and Development in Vancouver, BC, Canada</description>
	<lastBuildDate>Mon, 27 Sep 2010 01:15:46 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>memcached and Grails</title>
		<link>http://www.2paths.com/2009/07/16/memcached-and-grails/</link>
		<comments>http://www.2paths.com/2009/07/16/memcached-and-grails/#comments</comments>
		<pubDate>Fri, 17 Jul 2009 01:16:30 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Under the hood]]></category>
		<category><![CDATA[Utilities]]></category>
		<category><![CDATA[continuous integration]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[memcached]]></category>
		<category><![CDATA[scalability]]></category>

		<guid isPermaLink="false">http://www.2paths.com/?p=1122</guid>
		<description><![CDATA[I put together a Grails app to try out memcached. Like a lot of things in Grails, it was quite simple to integrate memcached once I found the right magic words. hibernate-memcached works nicely and has clear setup instructions.
Install memcached, which is simple if you use a Mac and have MacPorts installed.
$ sudo port install [...]]]></description>
			<content:encoded><![CDATA[<p>I put together a <a href="http://www.grails.org/">Grails</a> app to try out <a href="http://www.danga.com/memcached/">memcached</a>. Like a lot of things in Grails, it was quite simple to integrate memcached once I found the right magic words. <a href="http://code.google.com/p/hibernate-memcached/">hibernate-memcached</a> works nicely and has clear setup instructions.</p>
<p>Install memcached, which is simple if you use a Mac and have <a href="http://www.macports.org/">MacPorts</a> installed.</p>
<pre>$ sudo port install memcached</pre>
<p>Get the <a href="http://spymemcached.googlecode.com/files/memcached-2.3.1.jar">memcached jar</a> , the <a href="http://code.google.com/p/hibernate-memcached/downloads/list">hibernate-memcached jar</a> and the <a href="http://jdbc.postgresql.org/">PostgreSQL JDBC driver jar</a>, then  add them to the project.</p>
<pre>$ cp memcached-2.3.1.jar hibernate-memcached-1.2.jar postgresql-8.4-701.jdbc3.jar &lt;project_dir&gt;/lib/</pre>
<p>Configure memcached as the second-level cache by adding something like this to your DataSource.groovy.</p>
<pre><span class="pln">hibernate </span><span class="pun">{</span><span class="pln">
    cache</span><span class="pun">.</span><span class="pln">use_second_level_cache </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">true</span><span class="pln">
    cache</span><span class="pun">.</span><span class="pln">use_query_cache </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">true</span><span class="pln">
    cache</span><span class="pun">.</span><span class="pln">provider_class </span><span class="pun">=</span><span class="pln"> </span><span class="str">'com.googlecode.hibernate.memcached.MemcachedCacheProvider'</span><span class="pln">
    memcached </span><span class="pun">{</span><span class="pln">
        servers </span><span class="pun">=</span><span class="pln"> </span><span class="str">"localhost:11211"</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>
<p>I wrote a simple test to generate a whole bunch of domain objects and shove them in the database, then go back and fetch them all again. I set the test to run the insert/load loops in batches of 1, 10, 100, 1,000, 2,000, 4,000, 7,000, and 10,000 objects. I expected that inserting the objects would take a little longer because of the memcached overhead but that loading the objects would be faster because they could be loaded from memcached instead of going out to the database.</p>
<p>I tested three persistence backend configurations.</p>
<ul>
<li><a href="http://en.wikipedia.org/wiki/HSQLDB">HSQLDB</a>, the default for new Grails projects and when running unit/integration tests. This is an in-memory database only, so data aren&#8217;t persisted permanently.</li>
<li><a href="http://en.wikipedia.org/wiki/PostgreSQL"> PostgreSQL</a> for a full-blown RDBMS setup. I set dbCreate to &#8220;create-drop&#8221; in <a href="http://docs.codehaus.org/display/GRAILS/Quick+Start">DataSource.groovy</a> so that each test started with an empty database.</li>
<li>PostgreSQL with memcached enabled. I should point out that in this test I had both PostgreSQL and memcached running on the same machine (my laptop) as the application, so it&#8217;s really not taking advantage of memcached&#8217;s parallelism strengths.</li>
</ul>
<p>My expectations held true for the inserts. The memcached case is a little slower but not that much.</p>
<div id="attachment_1123" class="wp-caption alignnone" style="width: 806px"><img class="size-full wp-image-1123 " title="db-compare-inserts" src="http://www.2paths.com/wp-content/uploads/2009/07/db-compare-inserts.png" alt="db-compare-inserts" width="796" height="516" /><p class="wp-caption-text">Comparison of object insert times using HSQL, PostgreSQL, and memcached+PostgreSQL for persistence backend</p></div>
<p>When I tested the load times, I was surprised. It looked like memcached wasn&#8217;t speeding things up at all. I was also surprised to see that it took less time to load 10,000 objects from the data store than 7,000 objects. I ran the test a few times to rule out the possibility of a load spike from something else running at the same time, but I got similar results every time.</p>
<div id="attachment_1124" class="wp-caption alignnone" style="width: 806px"><img class="size-full wp-image-1124 " title="db-compare-loads" src="http://www.2paths.com/wp-content/uploads/2009/07/db-compare-loads.png" alt="Comparison object load times using HSQL, PostgreSQL, and memcached+PostgreSQL for persistence backend" width="796" height="516" /><p class="wp-caption-text">Comparison of object load times using HSQL, PostgreSQL, and memcached+PostgreSQL for persistence backend</p></div>
<p>I then tried to improve my test setup by running memcached on a second machine (my desktop, connected by gigabit ethernet to the laptop). Using the PostgreSQL + memcached configuration for each test this time, I looked at three more scenarios.</p>
<ul>
<li>PostgreSQL running locally on the laptop, memcached running locally on the laptop.</li>
<li>PostgreSQL running locally on the laptop, memcached running remotely on the desktop.</li>
<li>PostgreSQL running locally on the laptop, memcached running on both the laptop and the desktop.</li>
</ul>
<p>There&#8217;s some overhead in going out to the network to retrieve data instead of fetching it from a process running locally, so I expected the memcached local instance to be faster than the memcached remote instance. I expected the third test, with two instances of memcached running in parallel, to be fastest because it splits the load between the two instances and frees up some CPU time on the laptop. Things didn&#8217;t play out that way, though.</p>
<div id="attachment_1125" class="wp-caption alignnone" style="width: 806px"><img class="size-full wp-image-1125" title="local-remote-inserts" src="http://www.2paths.com/wp-content/uploads/2009/07/local-remote-inserts.png" alt="Comparison of object insert times for various memcache setups" width="796" height="516" /><p class="wp-caption-text">Comparison of object insert times for various memcache setups</p></div>
<div id="attachment_1126" class="wp-caption alignnone" style="width: 806px"><img class="size-full wp-image-1126" title="local-remote-loads" src="http://www.2paths.com/wp-content/uploads/2009/07/local-remote-loads.png" alt="Comparison of object load times for various memcache setups" width="796" height="516" /><p class="wp-caption-text">Comparison of object load times for various memcache setups</p></div>
<p>I have to be honest that these were not great tests. For one, I should really have run those insert/load loops in parallel instead of sequentially. I&#8217;m guessing that the test spent a lot of time stalled waiting for data when it could have been sending out more requests. I would also like to test with a large group of memcached servers and a remote database, perhaps even a cluster of app servers with a load balancer to try the full meal deal. The <a href="http://code.google.com/p/memcached/wiki/FAQ#Memcached_is_not_faster_than_my_database._Why?">memcached FAQ</a> explains that running everything on one machine will not show off memcached&#8217;s scalability.</p>
<p>However, this gave me the opportunity to get my hands dirty with memcached and learn a few things.</p>
<ul>
<li>Integrating memcached is so simple and the performance penalty of just running it locally during development is so small that there&#8217;s no reason not to enable it.</li>
<li>It&#8217;s dead simple to install and set up. We could , for example, easily  install it on a bunch of test servers and run multiple instances on different ports &#8211; one for each developer (to prevent us from clobbering each other&#8217;s data).</li>
<li>Measuring performance and scalability realistically is tricky. It&#8217;s one thing to hand wave and say that running multiple instances of a database or a cache will speed things up, but it takes some work to set up a realistic simulation of high traffic application performance.</li>
<li>Adding memcached doesn&#8217;t automatically turn performance up to <a href="http://www.youtube.com/watch?v=EbVKWCpNFhY">11</a>. I need to learn more about what&#8217;s going on under the hood with my domain objects and how they&#8217;re being persisted through memcached.</li>
</ul>
<p>I look forward to using memcached more in the future and learning how to really take advantage of it.</p>
<p><strong>Update (2009-07-24)</strong>: Ray pointed out in the <a href="#comment-8792">comments</a> that I should have enabled <a href="http://www.grails.org/GORM+-+Mapping+DSL">caching</a> in my domain objects under test. I added &#8220;static mapping = { cache true }&#8221; to my domain class definition and re-ran the tests to compare the effect under 4 scenarios.</p>
<ul>
<li>no domain object caching (as before)</li>
<li>domain object caching with memcached running locally</li>
<li>domain object caching with memcached running remotely</li>
<li>domain object caching with memcached running both locally and remotely</li>
</ul>
<p>Not much difference with the inserts.</p>
<div id="attachment_1145" class="wp-caption alignnone" style="width: 806px"><img class="size-full wp-image-1145" title="cache-true-inserts" src="http://www.2paths.com/wp-content/uploads/2009/07/cache-true-inserts.png" alt="Comparison of object insert times with domain object caching enabled and disabled" width="796" height="516" /><p class="wp-caption-text">Comparison of object insert times with domain object caching enabled and disabled</p></div>
<p>However, the load times are slightly better with memcached enabled during heavy activity! The advantage disappears when I add the overhead of traversing the network, but it&#8217;s a start. Thanks for the pointer, Ray!</p>
<div id="attachment_1146" class="wp-caption alignnone" style="width: 806px"><img class="size-full wp-image-1146" title="cache-true-loads" src="http://www.2paths.com/wp-content/uploads/2009/07/cache-true-loads.png" alt="Comparison of object load times with domain object caching enabled and disabled" width="796" height="516" /><p class="wp-caption-text">Comparison of object load times with domain object caching enabled and disabled</p></div>
]]></content:encoded>
			<wfw:commentRss>http://www.2paths.com/2009/07/16/memcached-and-grails/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>AWS and large data sets</title>
		<link>http://www.2paths.com/2009/05/21/aws-and-large-data-sets/</link>
		<comments>http://www.2paths.com/2009/05/21/aws-and-large-data-sets/#comments</comments>
		<pubDate>Thu, 21 May 2009 16:59:44 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Utilities]]></category>
		<category><![CDATA[aws]]></category>
		<category><![CDATA[cloud computing]]></category>

		<guid isPermaLink="false">http://www.2paths.com/?p=984</guid>
		<description><![CDATA[We&#8217;ve held back on going fully AWS as trying to get terabytes of data over to them would have been a colossal waste of time/money over a network connection.  Today, Amazon web services announced they can receive USB 2/esata devices up to 8U high if you want to load up large data sets into [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve held back on going fully AWS as trying to get terabytes of data over to them would have been a colossal waste of time/money over a network connection.  Today, Amazon web services announced they can receive USB 2/esata devices up to 8U high if you want to load up large data sets into their S3 service:</p>
<p><a href="http://aws.amazon.com/importexport/">AWS Import/Export</a></p>
<p>We haven&#8217;t analyzed the pricing but it is one more nail into the &#8220;let&#8217;s shut the dev cage down and go all cloud&#8221; debate.  </p>
]]></content:encoded>
			<wfw:commentRss>http://www.2paths.com/2009/05/21/aws-and-large-data-sets/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Unix shell grab bag</title>
		<link>http://www.2paths.com/2009/03/06/unix-shell-grab-bag/</link>
		<comments>http://www.2paths.com/2009/03/06/unix-shell-grab-bag/#comments</comments>
		<pubDate>Fri, 06 Mar 2009 23:09:39 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Utilities]]></category>
		<category><![CDATA[osx]]></category>

		<guid isPermaLink="false">http://www.2paths.com/?p=818</guid>
		<description><![CDATA[
Largely for my own reference, here are some Unix shell tricks that have come up lately. If you&#8217;re using Linux, Mac OS X, or other Unix-like systems, these might be handy.
Redirecting output
When a process starts, it opens three file descriptors: file descriptor 0 for standard input (STDIN), file descriptor 1 for standard output (STDOUT), and [...]]]></description>
			<content:encoded><![CDATA[<p><!-- Note to self: this really messes up with all the ampersands. Be sure to check the output if I ever change anything. --></p>
<p>Largely for my own reference, here are some Unix shell tricks that have come up lately. If you&#8217;re using Linux, Mac OS X, or other Unix-like systems, these might be handy.</p>
<h3>Redirecting output</h3>
<p>When a process starts, it opens three file descriptors: file descriptor 0 for standard input (STDIN), file descriptor 1 for standard output (STDOUT), and file descriptor 2 for standard error (STDERR). By default, the standard output and error just print to the terminal (so you see them on the screen), but you can redirect them to a file (e.g. for logging or just to cut down on gibberish that you&#8217;re not going to read anyway) by using &#8220;&gt;&#8221; to create/overwrite the file or &#8220;&gt;&gt;&#8221; to create/append the file.</p>
<p>I&#8217;ve used &#8220;find /&#8221; as the command in these examples because it takes a while to run and tends to produce plenty of output on STDOUT and STDERR.</p>
<p><code><br />
# Redirect STDOUT to a file, but leave STDERR to print on screen.<br />
# If the file exists, overwrite it.<br />
$ find / > /some/file.txt<br />
# Redirect STDOUT to a file, but leave STDERR to print on screen.<br />
# If the file exists, append to the end of it. If it doesn't exist, create it.<br />
$ find / >> /some/file.txt<br />
# Redirect STDOUT to the null device, which is a special file that silently discards everything.<br />
# Use this if you want to ignore STDOUT but keep an eye on STDERR.<br />
$ find / > /dev/null<br />
# Redirect both STDOUT and STDERR to the same file.<br />
$ find / > /some/file.txt 2>&#038;1<br />
# Redirect STDOUT and STDERR to different files.<br />
# The numbers refer to the file descriptors mentioned above.<br />
$ find / > /path/to/log.out 2>/path/to/log.err<br />
# ... or, more explicitly:<br />
$ find / 1>/path/to/log.out 2>/path/to/log.err<br />
</code></p>
<h3>Background processes</h3>
<p>Often you&#8217;ll want to start something running and keep working on something else. This is frequently done by redirecting the output to a file (or the <a href="http://en.wikipedia.org/wiki/Data_sink">null device</a>) by starting it in the background with the &#8220;&amp;&#8221; keyword.</p>
<p><code><br />
# Start a process in the background.<br />
$ find / &#038;<br />
# Start a process in the background and ignore all output.<br />
$ find / > /dev/null 2>&#038;1<br />
</code></p>
<p>To bring a background process back to the foreground, for example to stop it with ctrl+c or to provide input if it asks a question, use the &#8220;fg&#8221; command.</p>
<p>If you start several background processes, use the &#8220;jobs&#8221; command to list them. That will print the job number (different from the process ID) that you can use to bring a specific one back to the foreground with e.g. &#8220;fg 3&#8243; to bring back job 3.</p>
<p><code><br />
$ find / > /dev/null 2>&#038;1 &#038;<br />
$ cp file.dat /mnt/other_drive &#038;<br />
$ sleep 600 &#038;<br />
$ jobs<br />
[1]   Running             find / > /dev/null 2>&#038;1 &#038;<br />
[2]-  Running             cp file.dat /mnt/other_drive &#038;<br />
[3]+  Running             sleep 600 &#038;<br />
$ fg 3<br />
sleep 600<br />
</code></p>
<h3>Capturing process ID for simple start/stop scripts</h3>
<p>Putting those together, here&#8217;s a simple start/stop script that starts a command in the background and stores all output in a log file. It also uses the &#8220;$!&#8221; variable to record the process ID so it can kill the process later. Call the file &#8220;startstop.sh&#8221; and just run &#8220;startstop.sh start&#8221; to start it and &#8220;startstop.sh stop&#8221; to stop it.</p>
<p><code><br />
#!/bin/sh<br />
PID_FILE="test.pid"<br />
LOG_FILE="test.log"<br />
CMD="find /"<br />
if [ "$1" == "start" ]; then<br />
    echo "starting!"<br />
    $CMD > $LOG_FILE 2>&#038;1 &#038;<br />
    echo $! > $PID_FILE;<br />
fi<br />
if [ "$1" == "stop" ]; then<br />
    echo "stopping!"<br />
    kill `cat $PID_FILE`;<br />
    rm $PID_FILE;<br />
fi<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.2paths.com/2009/03/06/unix-shell-grab-bag/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building GRAILS app on Debian using Maven GRAILS Plugin</title>
		<link>http://www.2paths.com/2008/12/23/building-grails-app-on-debian-using-maven-grails-plugin/</link>
		<comments>http://www.2paths.com/2008/12/23/building-grails-app-on-debian-using-maven-grails-plugin/#comments</comments>
		<pubDate>Tue, 23 Dec 2008 23:07:54 +0000</pubDate>
		<dc:creator>Lorill</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Under the hood]]></category>
		<category><![CDATA[Utilities]]></category>
		<category><![CDATA[debian]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[Grails ended with a non null return code]]></category>
		<category><![CDATA[grails maven plugin]]></category>
		<category><![CDATA[hudson]]></category>

		<guid isPermaLink="false">http://www.2paths.com/?p=432</guid>
		<description><![CDATA[We&#8217;re now using GRAILS in one of our Maven-ized projects, and have it building using the Maven GRAILS plugin. We needed to roll this integration out to Husdon, our CI server which is running on a Debian box. We ran into a couple of snags.  
We had downloaded and installed the debian package grails_1.0.4-1_all.deb [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;re now using GRAILS in one of our Maven-ized projects, and have it building using the <a href="http://forge.octo.com/maven/sites/mtg/grails-maven-plugin/">Maven GRAILS plugin</a>. We needed to roll this integration out to Husdon, our CI server which is running on a Debian box. We ran into a couple of snags.  </p>
<p>We had downloaded and installed the debian package <code>grails_1.0.4-1_all.deb</code> from the <a href="http://grails.org/Download">GRAILS site</a>, configured the GRAILS_HOME environment variable for our build target, and attempted to  build it. We got this error:<br />
<code>Grails ended with a non null return code: 127</code><br />
After some digging, it turns out that the debian package installs GRAILS but puts the actual executable in /usr/bin instead of just a symlink from the GRAILS_HOME.  The Maven GRAILS plugin appears to be calling grails using the GRAILS_HOME path. Making a symlink to the grails executable in the bin dir of the GRAILS_HOME fixed this problem (although the symlink really more correctly belongs in the /usr/bin dir).</p>
<p>Trying to build again we came across a different problem, where the GRAILS version was showing up as null, causing build errors. After some googling I found <a href="http://code.google.com/p/ant-deb-task/issues/detail?id=19#c1">this useful post</a>, and re-installed GRAILS with the updated <a href="http://code.google.com/p/ant-deb-task/downloads/detail?name=grails_1.0.4-2_all.deb&amp;can=2&amp;q=">grails_1.0.4-2_all.deb</a> package, repeating the steps for the GRAILS executable.  Now we&#8217;re all up and running in Hudson!  I hope this might alleviate some pain for anyone trying to troubleshoot this problem.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.2paths.com/2008/12/23/building-grails-app-on-debian-using-maven-grails-plugin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>LiquiBase-ifying your Grails Application</title>
		<link>http://www.2paths.com/2008/12/23/liquibase-ifying-your-grails-application/</link>
		<comments>http://www.2paths.com/2008/12/23/liquibase-ifying-your-grails-application/#comments</comments>
		<pubDate>Tue, 23 Dec 2008 21:46:27 +0000</pubDate>
		<dc:creator>Lorill</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Under the hood]]></category>
		<category><![CDATA[Utilities]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[LiquiBase]]></category>

		<guid isPermaLink="false">http://www.2paths.com/?p=401</guid>
		<description><![CDATA[At 2Paths we&#8217;ve got some pretty good processes in place: we practice agile software development and scrum, have all our projects set up in Continuous Integration. We try to do test-driven development where at all possible. One area that has slipped through the cracks though is database change management. What company hasn&#8217;t run into the [...]]]></description>
			<content:encoded><![CDATA[<p>At 2Paths we&#8217;ve got some pretty good processes in place: we practice agile software development and scrum, have all our projects set up in Continuous Integration. We try to do test-driven development where at all possible. One area that has slipped through the cracks though is database change management. What company hasn&#8217;t run into the problem of ensuring all database environments in a project (dev, staging, production, test) are in sync and in source control? Without this, it becomes an onerous if not impossible task to rollback a set of databases to a known state, or to recreate one from scratch to a known state.</p>
<p>Enter <a href="http://liquibase.org">LiquiBase</a>, an open source database-agnostic tool for tracking, managing and applying database changes. We recently worked on a small Grails project and decided to give this tool a try and I was duly impressed.</p>
<p>LiquiBase functionality is built around a main changelog.xml file containing changesets representing incremental database changes to be applied to a database. LiquiBase manages which changesets have been run through a DATABASECHANGELOG table it creates in each database. </p>
<p>We used the <a href="http://www.liquibase.org/manual/grails">grails plugin</a> which gave us most of the full LiquiBase functionality, albeit a little less than mature.  There were a couple of gotchas and bugs with the plugin, but nothing we couldn&#8217;t work around.</p>
<p>LiquiBase buys us the ability to store database change in source control, easily sync databases in multi-environments in an automated and controlled fashion, tag database states upon iteration-end releases, auto-generate rollback sql to tagged states, diff databases, and much more.</p>
<h2>LiquiBase-ifying Your Application</h2>
<p>With your database in a known state, you can use the grails plugin to create your changelog.xml. First you need to install the grails LiquiBase plugin:<br />
<code>grails install-plugin liquibase</code><br />
Once installed simply run this from the root of your grails app:<br />
<code>grails generate-changelog grails-app/changelog.xml</code></p>
<p>This will generate the changelog.xml from your development database (specified in DataSource.groovy) and write it to the path specified in the command.  <code>grails-app/changelog.xml</code> is the default path where the grails plugin will be expecting the changelog to be. If you need to read from a different database environment like staging for example, just add the -Dgrails.env=staging option to the command.</p>
<p>To propagate this changelog to other databases (say, test), run<br />
<code>grails -Dgrails.env=test migrate</code>. This runs all the sql necessary to upate the database to match the changelog. Any new changes from here on will be appended as new changesets, and can be migrated with the same command as above.  You can also use the migrate-sql command instead if want to generate the sql and run it yourself.  Most LiquiBase commands come in tuples: one to generate the sql for you and one to just run the sql directly against your database.</p>
<p>If you&#8217;re integrating LiquiBase mid-project and already have all your databases set up, you&#8217;ll need to run sql against them to update the LiquiBase DATABASECHANGELOG table to show all the changes as run.  First, make sure that the databases are all in sync. To do this, you can use the handy LiquiBase diff tool. Unfortunately, the grails plugin for this diff tool is not very robust and will only diff your development database against your test database &#8211; the plugin has those two environments hard-coded. You can either mess with your DataSource.groovy db environments to do the diff setting the two dbs in question to dev and test temporarily, or <a href="http://www.liquibase.org/download">install LiquiBase</a> itself and run the <a href="http://www.liquibase.org/manual/diff">diff</a> passing the db parameters to the diff command. Using the grails plugin you would run:<br />
<code>grails db-diff</code> which will spit to the screen any differences as changesets to be applied. Strangely, there is no documentation for this command in the <a href="http://www.liquibase.org/manual/grails">LiquiBase Grails plugin page</a>.</p>
<p>Once your database are in sync, run<br />
<code>grails changelog-sync-sql</code> with the appropriate <code>-Dgrails.env</code> switch to generate the sql to update the DATABASECHANGELOG table, then run the sql in your database.</p>
<h2>LiquiBase and Continuous Integration</h2>
<p>We use Hudson at 2Paths for our CI, and have added the simple <code>grails -Dgrails.env=test migrate</code> command as part of our build process to migrate the test database upon every checkin. This ensures that the test db is always the most up-to-date.</p>
<h2>Rolling LiquiBase into our Dev Process</h2>
<p>We&#8217;ve adopted on a trial basis the following process for database change management as part of our agile software development, taking into consideration Grails development (which uses hibernate) which can auto-generates schemas based on domain objects:</p>
<ol>
<li>Generate changelog from initial schema and commit to svn</li>
<li>Rollout schema to other databases by migrating from changelog</li>
<ol>
<li>if the schema already exists and it needs &#8220;LiquiBase-ifying&#8221;, generate changelog-sync-sql and run it</li>
</ol>
<li>Add every schema change via new changeset from hereon in by generating changelogs via grails <a href="http://www.liquibase.org/manual/diff">db-diff</a></li>
<ol>
<li>add / change domain objects in project</li>
<li>set hiberante ddl mode to update</li>
<li>start app and grails will automatically update the db</li>
<li>generate new changelogs using db-diff (against the test db)</li>
<li>append changelogs to changelog.xml</li>
<li>run <code>grails changelog-sync-sql</code> to generate the sql that will mark all these new changes as ran on your db, then run the sql</li>
<li>checkin changes. this will be applied to test</li>
</ol>
<li>provide explicit rollback sql for any custom sql</li>
<li>tag each iteration end with a &#8220;tagDatabase&#8221; changelog in the changelog.xml</li>
</ol>
<h2>Gotchas</h2>
<p>We ran into some gotchas with LiquiBase. One of the first things we started doing before fully understanding how LiquiBase worked was to update existing changesets when changing the schema. LiquiBase generates checksums for each changeset to ensure they don&#8217;t change, and altering existing changelogs will cause future migrations to fail. Even though LiquiBase gives you some tools to get around this, it&#8217;s generally a better practice to just add a new changeset for every database change. There is a good blog on the LiquiBase site explaining  <a href="http://blog.liquibase.org/2008/10/dealing-with-changing-changesets.html">how to deal with changing changesets</a>.</p>
<p>Another gotcha is that the rollback-sql command won&#8217;t magically generate rollback scripts for hand-coded sql (obviously!) You must to generate your own rollback sql for these custom sql tags, otherwise not only will you not get rollback sql for those particular changesets, but the rollback functionality won&#8217;t spit out sql for any other changeset either until you do.</p>
<p>Tagging was a little fussy as well. The command line <code>grails tag</code> can only tag a given state once &#8211; future tags will overwrite the earlier ones unless you&#8217;re at a different changeset. I found it better to add a tag changeset explicitly in the changelog.xml. The Grails plugin for tagging also seems to be problematic with spaces in the tag name. We decided to just use underscores as a convention.</p>
<p>We also ran across some broken functionality:</p>
<ul>
<li>The <code>grails generate-changelog</code> command generates some extraneous information that breaks sql for data type numeric(19,0) if that type has auto-increment on.  It generates this in the changelog:<br />
&lt;column autoIncrement=&#8221;true&#8221; name=&#8221;id&#8221; type=&#8221;numeric()(19,0)&#8221;&gt; (notice the extra empty brackets).  We needed to manually remove these to get it to work.</li>
<li>The <code>grails rollback-to-date-sql</code> command writes to a file with the datestamp instead of to console like the other rollbacks do, even though the docs say it writes to STDOUT (<code>rollback-count-sql</code> also has issues, but <code>rollback-sql</code> for tags works just fine). The code for these plugin commands doesn&#8217;t seem to do the right thing with the args. Time permitting, we may provide a patch for this.</li>
<li>db-doc generation doesn&#8217;t work with large amount of columns in a table because it uses the table description including column names for the html file name.  Too many db columns make the file names too long.</li>
</ul>
<h2>Moving Forward</h2>
<p>Although there&#8217;s a bit of grumbling amongst the developers here that using LiquiBase with the above process is a little onerous, it buys us a lot more certainty for knowing what state our databases are in, making sure changes are in source control, and knowing what updates have or haven&#8217;t been run. It&#8217;s a whole lot easier than hand-coding a bunch of sql, and easily accommodates the possibility of migrating to other DBMS&#8217;s in the future without having to re-write DBMS-specific sql. There&#8217;s even talk of trying to go a step or two further to automate even more of the process so a developer doesn&#8217;t have to think about generating changesets upon changing of a grails domain model. We&#8217;ll see how that goes.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.2paths.com/2008/12/23/liquibase-ifying-your-grails-application/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Eclipse update, fix for home and end keys</title>
		<link>http://www.2paths.com/2007/10/19/eclipse-update-fix-for-home-and-end-keys/</link>
		<comments>http://www.2paths.com/2007/10/19/eclipse-update-fix-for-home-and-end-keys/#comments</comments>
		<pubDate>Fri, 19 Oct 2007 17:32:27 +0000</pubDate>
		<dc:creator>gord</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Utilities]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[osx]]></category>

		<guid isPermaLink="false">http://blog.2paths.com/eclipse-update-fix-for-home-and-end-keys.html</guid>
		<description><![CDATA[2Paths Eclipse Distro v2
I&#8217;ve put together a new disto of the latest Eclipse wtp with some added plugin goodness. I&#8217;ve found this version to be much more stable than v1, and it even works on Lorill&#8217;s machine without too much trouble. Among the new features is a regex tester plugin, and a filter plugin that [...]]]></description>
			<content:encoded><![CDATA[<p><strong>2Paths Eclipse Distro v2</strong><br />
I&#8217;ve put together a new disto of the latest Eclipse wtp with some added plugin goodness. I&#8217;ve found this version to be much more stable than v1, and it even works on Lorill&#8217;s machine without too much trouble. Among the new features is a regex tester plugin, and a filter plugin that allows you to run command line tools such as sed against a selection in the text editor.</p>
<p>Also note that I&#8217;ve put together a 2Paths preferences file that remaps the home and end keys in eclipse, and adds in the 2Paths code formatting templates. To import, once you&#8217;ve got the new eclipse up and running, select import and choose preferences.</p>
<p><a href="http://dev.2paths.com/~glea/blog/eclipse-2paths-v2.zip">Download Eclipse 2Paths Edition v2</a> (155.6MB)</p>
<p><strong>Fix for home and end keys</strong><br />
If you&#8217;re anything like me, you are used to having  your home and end keys go to the start of the line of text and the end of the line, respectively. The way OS X does it drives me insane, and I&#8217;ve finally found a solution that even fixes it in firefox: <a href="http://www.starryhope.com/tech/apple/2006/keyfixer/">KeyFixer</a>.</p>
<p>KeyFixer is a free utility that remaps those keys, there are 2 versions, the standard one that remaps it in OS X and most apps, and KeyFixer for Firefox which is self explanatory. I recommend installing them both if you want your home and end keys back.</p>
<p><a href="http://www.starryhope.com/downloads/KeyFixer.dmg">Download KeyFixer</a> (60KB)</p>
<p><a href="http://www.starryhope.com/downloads/keyfixer_firefox_0.2.dmg">Download KeyFixer for Firefox</a> (80KB)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.2paths.com/2007/10/19/eclipse-update-fix-for-home-and-end-keys/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

