<?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>Ciaran&#039;s Random Writings &#187; Erlang</title>
	<atom:link href="http://ciarang.com/posts/category/software/erlang/feed" rel="self" type="application/rss+xml" />
	<link>http://ciarang.com</link>
	<description>Random things I&#039;ve written about stuff</description>
	<lastBuildDate>Thu, 02 Feb 2012 17:46:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Compiling ejabberd 2.0 on Debian (Etch)</title>
		<link>http://ciarang.com/posts/compiling-ejabberd-20-on-debian-etch</link>
		<comments>http://ciarang.com/posts/compiling-ejabberd-20-on-debian-etch#comments</comments>
		<pubDate>Sat, 12 Jul 2008 17:57:21 +0000</pubDate>
		<dc:creator>CiaranG</dc:creator>
				<category><![CDATA[Erlang]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[XMPP]]></category>

		<guid isPermaLink="false">http://blog.ciarang.com/?p=235</guid>
		<description><![CDATA[Etch has ejabberd 1.1 packaged but if you&#8217;re like me you&#8217;ll want to play with the new features in 2.0, in which case you&#8217;ll need to build from source. Etch&#8217;s packaged version of Erlang is apparently not up to date enough to support it (it compiles fine, but I couldn&#8217;t get TLS to work) so [...]]]></description>
			<content:encoded><![CDATA[<p>Etch has ejabberd 1.1 <a href="http://packages.debian.org/etch/ejabberd">packaged</a> but if you&#8217;re like me you&#8217;ll want to play with the new features in 2.0, in which case you&#8217;ll need to build from source. Etch&#8217;s packaged version of Erlang is apparently not up to date enough to support it (it compiles fine, but I couldn&#8217;t get TLS to work) so you&#8217;ll need to build a newer version of that as well. Luckly it&#8217;s all easy. This following is all from your home directory on a fresh install of Debian:</p>
<p><span id="more-235"></span></p>
<p>Stuff you need:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">sudo apt-get install build-essential
sudo apt-get install libexpat1-dev zlib1g-dev libssl-dev
sudo apt-get install m4 libncurses5-dev</pre></div></div>

<p>Erlang:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">wget http://www.erlang.org/download/otp_src_R12B-3.tar.gz
tar -xzf otp_src_R12B-3.tar.gz
cd otp_src_R12B-3
./configure
make
sudo make install</pre></div></div>

<p>Ejabberd:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">wget http://www.process-one.net/downloads/ejabberd/2.0.1/ejabberd-2.0.1_2.tar.gz
tar -xzf ejabberd-2.0.1_2.tar.gz
cd ejabberd-2.0.1/src
./configure
make
sudo make install</pre></div></div>

<p>With that done just edit the config in /etc/ejabberd as required, generate or otherwise obtain an SSL certificate, and you&#8217;re ready to go.</p>
]]></content:encoded>
			<wfw:commentRss>http://ciarang.com/posts/compiling-ejabberd-20-on-debian-etch/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New CouchDB build system</title>
		<link>http://ciarang.com/posts/new-couchdb-build-system</link>
		<comments>http://ciarang.com/posts/new-couchdb-build-system#comments</comments>
		<pubDate>Mon, 01 Oct 2007 12:39:05 +0000</pubDate>
		<dc:creator>CiaranG</dc:creator>
				<category><![CDATA[CouchDB]]></category>
		<category><![CDATA[Erlang]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://blog.ciarang.com/index.php/archives/150</guid>
		<description><![CDATA[Noah Slater has been very busy upgrading the CouchDB build system and the changes have been merged to the trunk version tonight, so it&#8217;s time to update my test box build scripts. This lot replaces the earlier stuff found here sudo apt-get install libicu36 libicu36-dev libreadline5-dev sudo apt-get install subversion-tools xsltproc automake libtool svn -r [...]]]></description>
			<content:encoded><![CDATA[<p>Noah Slater has been very busy upgrading the CouchDB build system and the changes have been merged to the trunk version tonight, so it&#8217;s time to update my test box build scripts. This lot replaces the earlier stuff found <a href="http://ciarang.com/index.php/archives/107">here</a></p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">sudo apt-get install libicu36 libicu36-dev libreadline5-dev
sudo apt-get install subversion-tools xsltproc automake libtool
svn -r 305 co http://couchdb.googlecode.com/svn/trunk/ couchdb
cd couchdb
./bootstrap
./configure --with-erlang=/usr/local/lib/erlang
make
sudo make install</pre></div></div>

<p>Starting up CouchDB is now more straightforward:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">couchdb</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://ciarang.com/posts/new-couchdb-build-system/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Mnesia performance basics</title>
		<link>http://ciarang.com/posts/mnesia-performance-basics</link>
		<comments>http://ciarang.com/posts/mnesia-performance-basics#comments</comments>
		<pubDate>Wed, 26 Sep 2007 22:10:17 +0000</pubDate>
		<dc:creator>CiaranG</dc:creator>
				<category><![CDATA[Erlang]]></category>
		<category><![CDATA[Mnesia]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://blog.ciarang.com/index.php/archives/149</guid>
		<description><![CDATA[I thought I&#8217;d continue the whirlwind guide to Mnesia that I began in Getting started with Mnesia. I have no idea how many of the thousands of readers actually found the last part useful. At least one, judging by the comments, but more to the point it&#8217;s rather handy for me to write this stuff [...]]]></description>
			<content:encoded><![CDATA[<p>I thought I&#8217;d continue the whirlwind guide to <a href="http://www.erlang.org/doc/apps/mnesia/application_frame.html" class="broken_link">Mnesia</a> that I began in <a href="http://ciarang.com/index.php/archives/139">Getting started with Mnesia</a>. I have no idea how many of the thousands of readers actually found the last part useful. At least one, judging by the comments, but more to the point it&#8217;s rather handy for me to write this stuff down as I&#8217;m flitting between various new (to me) things at the moment.</p>
<p><span id="more-149"></span></p>
<p>Let&#8217;s start with indexing. Last time we defined a table and queried it as follows:</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #014ea4;">-</span><span style="color: #5400b3;">record</span><span style="color: #109ab8;">&#40;</span><span style="color: #d400ed;">animal</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span>name<span style="color: #6bb810;">,</span>legs<span style="color: #6bb810;">,</span>noise<span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff4e18;">mnesia</span>:<span style="color: #ff3c00;">create_table</span><span style="color: #109ab8;">&#40;</span>animal<span style="color: #6bb810;">,</span>
                         <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#123;</span>disc_copies<span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #fa6fff;">node</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span>
                          <span style="color: #109ab8;">&#123;</span>attributes<span style="color: #6bb810;">,</span> <span style="color: #ff3c00;">record_info</span><span style="color: #109ab8;">&#40;</span>fields<span style="color: #6bb810;">,</span>animal<span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
&nbsp;
<span style="color: #45b3e6;">Fun</span> <span style="color: #186895;">fun</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
  <span style="color: #ff4e18;">mnesia</span>:<span style="color: #ff3c00;">match_object</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#123;</span>animal<span style="color: #6bb810;">,</span><span style="">'_'</span><span style="color: #6bb810;">,</span><span style="color: #ff9600;">4</span><span style="color: #6bb810;">,</span><span style="">'_'</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#41;</span>
  <span style="color: #186895;">end</span><span style="color: #6bb810;">,</span>
<span style="color: #109ab8;">&#123;</span>atomic<span style="color: #6bb810;">,</span><span style="color: #45b3e6;">Results</span><span style="color: #109ab8;">&#125;</span><span style="color: #014ea4;">=</span><span style="color: #ff4e18;">mnesia</span>:<span style="color: #ff3c00;">transaction</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Fun</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></pre></div></div>

<p>Our query is returning us all animals with 4 legs, but if we&#8217;ve got any sizable amount of records in that table it&#8217;s going to run like a dog. The solution is simple:</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #ff4e18;">mnesia</span>:<span style="color: #ff3c00;">create_table_index</span><span style="color: #109ab8;">&#40;</span>animal<span style="color: #6bb810;">,</span>legs<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></pre></div></div>

<p>The <i>legs</i> field is now indexed, and the <i>match_object</i> function will automatically pick up on that and give us more sensible performance that doesn&#8217;t involve full table scanning. Remember, as I said last time, that the first field is always considered to be the key, and is always indexed, so you only need to explicitly create an index for additional fields you intend matching against.</p>
<p>Another way of speeding things up is using &#8216;dirty&#8217; access methods. These involve bypassing the transaction layer altogether, losing the Atomicity and Isolation from Mnesia&#8217;s ACID properties, but gaining a major reduction in overhead. Most of the normal access functions have a dirty equivalent &#8211; for example, <i>dirty_match_object</i> is the direct equivalent of the <i>match_object</i> function we&#8217;re using above. Methods specific to dirty operations are also available, including the wonderfully specific <i>dirty_update_counter</i>.</p>
<p>Using replicated copies of a table across multiple nodes, as well as providing redundancy, allows parallel access to the data. I can see a case for using this to improve performance by distributing the workload across multiple nodes, although in this case it needs to be a table which is read often and written occasionally, since there is a transactional penalty to writing to replicated tables.</p>
<p>Table fragmentation (i.e. the ability to distribute a table across multiple nodes) has performance possibilities too, since with different parts of the table on different nodes, operations can be conducted in parallel between them. I haven&#8217;t got fragmentation up and running yet though, so I don&#8217;t know how well this will work in practice.</p>
<p>When you consider that in addition to the above, Mnesia already has a head start due to the fact that it&#8217;s running in the same address space as the code, and with no mismatch between the Mnesia and Erlang to slow things down, the potential for high performance looks very good indeed. I&#8217;ve already got an Mnesia/Erlang back-end up and running which seems to be outperforming the MySQL/Erlang equivalent, although my tests so far are rather unscientific. More to come on this when time allows.</p>
]]></content:encoded>
			<wfw:commentRss>http://ciarang.com/posts/mnesia-performance-basics/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>When Erlang goes bad</title>
		<link>http://ciarang.com/posts/when-erlang-goes-bad</link>
		<comments>http://ciarang.com/posts/when-erlang-goes-bad#comments</comments>
		<pubDate>Mon, 24 Sep 2007 22:19:40 +0000</pubDate>
		<dc:creator>CiaranG</dc:creator>
				<category><![CDATA[Erlang]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://blog.ciarang.com/index.php/archives/147</guid>
		<description><![CDATA[I had to post this, mainly for the entertainment value but also as a reminder to myself not to start playing with new stuff after a long hard day of &#8216;real&#8217; development. I just needed a quick bit of code that starts out with a string of the form &#8220;inc=45,56,76,102&#038;exc=10,11,15,98&#8243; and spits out two lists [...]]]></description>
			<content:encoded><![CDATA[<p>I had to post this, mainly for the entertainment value but also as a reminder to myself not to start playing with new stuff after a long hard day of &#8216;real&#8217; development. I just needed a quick bit of code that starts out with a string of the form &#8220;inc=45,56,76,102&#038;exc=10,11,15,98&#8243; and spits out two lists of integers. I somehow ended up with this:</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">% On entry, A#arg.querydata is a string of the form &quot;inc=n,n,n&amp;exc=n,n,n</span>
<span style="color: #45b3e6;">QueryArgs</span><span style="color: #014ea4;">=</span><span style="color: #ff4e18;">string</span>:<span style="color: #ff3c00;">tokens</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">A</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">arg</span><span style="color: #6bb810;">.</span>querydata<span style="color: #6bb810;">,</span><span style="color: #ff7800;">&quot;&amp;&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
<span style="color: #45b3e6;">QueryArgs2</span><span style="color: #014ea4;">=</span><span style="color: #ff4e18;">lists</span>:<span style="color: #ff3c00;">map</span><span style="color: #109ab8;">&#40;</span><span style="color: #186895;">fun</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">T</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #ff4e18;">string</span>:<span style="color: #ff3c00;">tokens</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">T</span><span style="color: #6bb810;">,</span><span style="color: #ff7800;">&quot;=&quot;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">end</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">QueryArgs</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
<span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">_</span>|IncP<span style="color: #109ab8;">&#93;</span>|_<span style="color: #109ab8;">&#93;</span><span style="color: #014ea4;">=</span><span style="color: #ff4e18;">lists</span>:<span style="color: #ff3c00;">filter</span><span style="color: #109ab8;">&#40;</span><span style="color: #186895;">fun</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">T</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">N</span>|_Rest<span style="color: #109ab8;">&#93;</span><span style="color: #014ea4;">=</span><span style="color: #45b3e6;">T</span><span style="color: #6bb810;">,</span><span style="color: #ff7800;">&quot;inc&quot;</span><span style="color: #014ea4;">==</span><span style="color: #45b3e6;">N</span> <span style="color: #186895;">end</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">QueryArgs2</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
<span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">_</span>|ExcP<span style="color: #109ab8;">&#93;</span>|_<span style="color: #109ab8;">&#93;</span><span style="color: #014ea4;">=</span><span style="color: #ff4e18;">lists</span>:<span style="color: #ff3c00;">filter</span><span style="color: #109ab8;">&#40;</span><span style="color: #186895;">fun</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">T</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">N</span>|_Rest<span style="color: #109ab8;">&#93;</span><span style="color: #014ea4;">=</span><span style="color: #45b3e6;">T</span><span style="color: #6bb810;">,</span><span style="color: #ff7800;">&quot;exc&quot;</span><span style="color: #014ea4;">==</span><span style="color: #45b3e6;">N</span> <span style="color: #186895;">end</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">QueryArgs2</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
<span style="color: #45b3e6;">IncS</span><span style="color: #014ea4;">=</span><span style="color: #ff4e18;">string</span>:<span style="color: #ff3c00;">tokens</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff4e18;">lists</span>:<span style="color: #ff3c00;">nth</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff9600;">1</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">IncP</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span><span style="color: #ff7800;">&quot;,&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
<span style="color: #45b3e6;">ExcS</span><span style="color: #014ea4;">=</span><span style="color: #ff4e18;">string</span>:<span style="color: #ff3c00;">tokens</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff4e18;">lists</span>:<span style="color: #ff3c00;">nth</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff9600;">1</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">ExcP</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span><span style="color: #ff7800;">&quot;,&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
<span style="color: #45b3e6;">Includes</span><span style="color: #014ea4;">=</span><span style="color: #ff4e18;">lists</span>:<span style="color: #ff3c00;">map</span><span style="color: #109ab8;">&#40;</span><span style="color: #186895;">fun</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">T</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">-&gt;</span><span style="color: #fa6fff;">list_to_integer</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">T</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">end</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">IncS</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
<span style="color: #45b3e6;">Excludes</span><span style="color: #014ea4;">=</span><span style="color: #ff4e18;">lists</span>:<span style="color: #ff3c00;">map</span><span style="color: #109ab8;">&#40;</span><span style="color: #186895;">fun</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">T</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">-&gt;</span><span style="color: #fa6fff;">list_to_integer</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">T</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">end</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">ExcS</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
<span style="color: #666666; font-style: italic;">% On exit, Includes=[n1,n2,...] and Excludes=[n1,n2,...]</span></pre></div></div>

<p>Just as shocking as the code are the facts that a) it took me half an hour to make it work, and b) it actually works at all. Worse still, I don&#8217;t even need the code, since ultimately it will all be handled via JSON-RPC and not some nasty ad-hoc HTTP query processing &#8211; I just wanted to do a quick test in the meantime. The mission was accomplished, but surely there&#8217;s a far more elegant way to do the above. Unfortunately, I&#8217;m not going to find it today. I will be compelled to come back to it of course, and when I do I hope I can keep the lovely [[_|IncP]|_] part.</p>
]]></content:encoded>
			<wfw:commentRss>http://ciarang.com/posts/when-erlang-goes-bad/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Parallel List Operations in Erlang</title>
		<link>http://ciarang.com/posts/parallel-list-operations-in-erlang</link>
		<comments>http://ciarang.com/posts/parallel-list-operations-in-erlang#comments</comments>
		<pubDate>Thu, 20 Sep 2007 22:09:07 +0000</pubDate>
		<dc:creator>CiaranG</dc:creator>
				<category><![CDATA[Erlang]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://blog.ciarang.com/index.php/archives/140</guid>
		<description><![CDATA[One of the first things that struck me when I was first browsing through the documentation for the Erlang lists module was the lack of support for parallelism. Functions such as lists:map are clearly prime candidates for this, although obviously you might sometimes require a serial implementation. Needless to say, Erlang makes it easy to [...]]]></description>
			<content:encoded><![CDATA[<p>One of the first things that struck me when I was first browsing through the documentation for the Erlang <i>lists</i> module was the lack of support for parallelism. Functions such as lists:map are clearly prime candidates for this, although obviously you might sometimes require a serial implementation.</p>
<p><span id="more-140"></span></p>
<p>Needless to say, Erlang makes it easy to implement this kind of thing anyway but I just expected to find it there. You can imagine my excitement then when I came across <a href="http://code.google.com/p/plists/">plists</a>, a module that&#8217;s compatible on a function-by-function basis with Erlang&#8217;s lists module, adding a range of powerful but simple to use parallel processing options. In addition, mapreduce and several other operations are added.</p>
<p>I haven&#8217;t had a chance to play yet, and it&#8217;s far too late in the evening to start now, so for the full low-down have a read <a href="http://plists.wordpress.com/2007/09/20/introducing-plists-an-erlang-module-for-doing-list-operations-in-parallel/">here</a> and then move on to the docs <a href="http://freeyourmind.googlepages.com/plists.html">here</a>. On top of all the nice looking functionality, you&#8217;ll soon be able to discuss &#8216;malts&#8217; with those in the know.</p>
]]></content:encoded>
			<wfw:commentRss>http://ciarang.com/posts/parallel-list-operations-in-erlang/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Getting started with Mnesia</title>
		<link>http://ciarang.com/posts/getting-started-with-mnesia</link>
		<comments>http://ciarang.com/posts/getting-started-with-mnesia#comments</comments>
		<pubDate>Wed, 19 Sep 2007 19:20:09 +0000</pubDate>
		<dc:creator>CiaranG</dc:creator>
				<category><![CDATA[Erlang]]></category>
		<category><![CDATA[Mnesia]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://blog.ciarang.com/index.php/archives/139</guid>
		<description><![CDATA[Though Mnesia, Erlang&#8217;s &#8220;built-in&#8221; database, has a lot going for it, one area that definitely doesn&#8217;t stand out is the documentation so here is the whirlwind tour I could have used when getting started. I won&#8217;t dwell on any particular subject, so consider this a starting point for further research &#8211; the documentation is actually [...]]]></description>
			<content:encoded><![CDATA[<p>Though Mnesia, Erlang&#8217;s &#8220;built-in&#8221; database, has a lot going for it, one area that definitely doesn&#8217;t stand out is the documentation so here is the whirlwind tour I could have used when getting started. I won&#8217;t dwell on any particular subject, so consider this a starting point for further research &#8211; the documentation is actually ok once you know what it is you&#8217;re looking for!</p>
<p><span id="more-139"></span></p>
<p>Mnesia works best in conjunction with Erlang&#8217;s records. A simple record might look something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #014ea4;">-</span><span style="color: #5400b3;">record</span><span style="color: #109ab8;">&#40;</span><span style="color: #d400ed;">animal</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span>name<span style="color: #6bb810;">,</span>legs<span style="color: #6bb810;">,</span>noise<span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></pre></div></div>

<p>Here we&#8217;ve defined a record called &#8220;animal&#8221; with three fields. We can use this record definition to create an Mnesia table like this:</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;">  <span style="color: #ff4e18;">mnesia</span>:<span style="color: #ff3c00;">create_schema</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span><span style="color: #fa6fff;">node</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
  <span style="color: #ff4e18;">mnesia</span>:<span style="color: #ff3c00;">start</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
  <span style="color: #ff4e18;">mnesia</span>:<span style="color: #ff3c00;">create_table</span><span style="color: #109ab8;">&#40;</span>animal<span style="color: #6bb810;">,</span>
                         <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#123;</span>disc_copies<span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #fa6fff;">node</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span>
                          <span style="color: #109ab8;">&#123;</span>attributes<span style="color: #6bb810;">,</span> <span style="color: #ff3c00;">record_info</span><span style="color: #109ab8;">&#40;</span>fields<span style="color: #6bb810;">,</span>animal<span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></pre></div></div>

<p>When running this code, you will most likely want to use an Erlang command-line option like <i>-mnesia dir &#8216;&#8221;db&#8221;&#8216;</i> in order to specify the directory where the database will be created. It&#8217;s also important to pay attention to your node name and Erlang cookies if you intend to run a distributed Mnesia database.</p>
<p>Once we have a table, we can easily add records. The first point to note here is that ALL access to Mnesia goes within a transaction, which is defined in the form of a function. Here&#8217;s some simple code to add an item to the table we just defined:</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;">  <span style="color: #45b3e6;">Fun</span> <span style="color: #014ea4;">=</span> <span style="color: #186895;">fun</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #ff4e18;">mnesia</span>:<span style="color: #ff3c00;">write</span><span style="color: #109ab8;">&#40;</span>#<span style="color: #d400ed;">animal</span><span style="color: #109ab8;">&#123;</span>name<span style="color: #014ea4;">=</span><span style="color: #ff7800;">&quot;cow&quot;</span><span style="color: #6bb810;">,</span>legs<span style="color: #014ea4;">=</span><span style="color: #ff9600;">4</span><span style="color: #6bb810;">,</span>noise<span style="color: #014ea4;">=</span><span style="color: #ff7800;">&quot;moo&quot;</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#41;</span>
    <span style="color: #186895;">end</span><span style="color: #6bb810;">,</span>
  <span style="color: #ff4e18;">mnesia</span>:<span style="color: #ff3c00;">transaction</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Fun</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></pre></div></div>

<p>Getting the data out again is also straightfoward, although there are many options. Firstly, note that by default Mnesia considers the first field in the record to be the key. With that in mind, you can use mnesia:read/2 to retreive a row by key:</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;">  <span style="color: #45b3e6;">Fun</span> <span style="color: #014ea4;">=</span> <span style="color: #186895;">fun</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #ff4e18;">mnesia</span>:<span style="color: #ff3c00;">read</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#123;</span>animal<span style="color: #6bb810;">,</span><span style="color: #ff7800;">&quot;cow&quot;</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#41;</span>
    <span style="color: #186895;">end</span><span style="color: #6bb810;">,</span>
  <span style="color: #109ab8;">&#123;</span>atomic<span style="color: #6bb810;">,</span><span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">Row</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#125;</span><span style="color: #014ea4;">=</span><span style="color: #ff4e18;">mnesia</span>:<span style="color: #ff3c00;">transaction</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Fun</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
  <span style="color: #ff4e18;">io</span>:<span style="color: #ff3c00;">format</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;~p~n&quot;</span><span style="color: #6bb810;">,</span><span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">Row</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">animal</span><span style="color: #6bb810;">.</span>noise<span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></pre></div></div>

<p>All being well, the above should output &#8220;moo&#8221;. Another useful method for retreiving records is mnesia:match_object, which works as follows:</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;">  <span style="color: #45b3e6;">Fun</span> <span style="color: #014ea4;">=</span> <span style="color: #186895;">fun</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
    <span style="color: #ff4e18;">mnesia</span>:<span style="color: #ff3c00;">match_object</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#123;</span>animal<span style="color: #6bb810;">,</span><span style="">'_'</span><span style="color: #6bb810;">,</span><span style="color: #ff9600;">4</span><span style="color: #6bb810;">,</span><span style="">'_'</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#41;</span>
    <span style="color: #186895;">end</span><span style="color: #6bb810;">,</span>
  <span style="color: #109ab8;">&#123;</span>atomic<span style="color: #6bb810;">,</span><span style="color: #45b3e6;">Results</span><span style="color: #109ab8;">&#125;</span><span style="color: #014ea4;">=</span><span style="color: #ff4e18;">mnesia</span>:<span style="color: #ff3c00;">transaction</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Fun</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></pre></div></div>

<p>Here we end up with Results being a list of all the animals with four legs. Each entry in the list is a complete &#8216;animal&#8217; record. Yet another option, and a very powerful one, is the Query List Comprehension. This uses the same concept as normal List Comprehensions, but mapped onto Mnesia, with some clever tricks behind the scenes to make it efficient. A quick example which simply retrieves all the animal records:</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;">  <span style="color: #ff4e18;">mnesia</span>:<span style="color: #ff3c00;">transaction</span><span style="color: #109ab8;">&#40;</span><span style="color: #186895;">fun</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #ff4e18;">qlc</span>:<span style="color: #ff3c00;">eval</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff4e18;">qlc</span>:<span style="color: #ff3c00;">q</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">X</span> <span style="color: #014ea4;">||</span> <span style="color: #45b3e6;">X</span> <span style="color: #014ea4;">&lt;-</span> <span style="color: #ff4e18;">mnesia</span>:<span style="color: #ff3c00;">table</span><span style="color: #109ab8;">&#40;</span>animal<span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #186895;">end</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></pre></div></div>

<p>Finally, there is a very useful tool hidden away within the YAWS source that allows you to peruse your database from a browser. The code in question is <b>ymnesia.erl</b>, a YAWS appmod which can be found in the main src directory although it isn&#8217;t compiled by default. I found the easiest thing to do was to pull the file out into my project and run the appmod with <a href="http://ciarang.com/index.php/archives/96">YAWS in embedded mode</a> as part of my application, which ensures it&#8217;s accessing the same database.</p>
<p>Any corrections to the above are welcome, since I&#8217;ve mostly typed it up from memory. I&#8217;ll no doubt cover more aspects of Mnesia at a later date, but in the meantime you can look at my earlier <a href="http://ciarang.com/index.php/archives/98">XML import code</a> for a complete working example.</p>
]]></content:encoded>
			<wfw:commentRss>http://ciarang.com/posts/getting-started-with-mnesia/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>A CouchDB GUI front end</title>
		<link>http://ciarang.com/posts/a-couchdb-gui-front-end</link>
		<comments>http://ciarang.com/posts/a-couchdb-gui-front-end#comments</comments>
		<pubDate>Wed, 12 Sep 2007 20:07:44 +0000</pubDate>
		<dc:creator>CiaranG</dc:creator>
				<category><![CDATA[CouchDB]]></category>
		<category><![CDATA[Erlang]]></category>
		<category><![CDATA[SharpDevelop]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://blog.ciarang.com/index.php/archives/109</guid>
		<description><![CDATA[I decided to hack together a quick GUI front end for CouchDB to help with my tinkering around. Most people will probably groan and stop reading now, because I implemented it in C#/.NET. Although I&#8217;m not going to apologise for that, I do feel the need to justify it: I didn&#8217;t want to spend any [...]]]></description>
			<content:encoded><![CDATA[<p>I decided to hack together a quick GUI front end for <a href="http://www.couchdb.org">CouchDB</a> to help with my tinkering around. Most people will probably groan and stop reading now, because I implemented it in C#/.NET. Although I&#8217;m not going to apologise for that, I do feel the need to justify it:</p>
<p><span id="more-109"></span></p>
<ul>
<li>I didn&#8217;t want to spend any time on it, and for various reasons I can do this kind of crap in C# with my eyes shut and no RTFMing.</li>
<li>I needed a C# wrapper class to patch into an existing application, and this started out as a testbed for that.</li>
</ul>
<p>If you haven&#8217;t been scared off already, here&#8217;s a brief summary of what you can do:</p>
<ul>
<li>Browse, create and delete databases</li>
<li>Execute &#8216;queries&#8217; (temporary views)</li>
<li>Browse the documents in a database</li>
<li>Create and delete documents</li>
</ul>
<p>Here are some screenshots of the imaginitively titled CouchBrowse application:</p>
<p><center>
<p>
<img src='http://ciarang.com/wp-content/uploads/2007/09/couchbrowse1.png' alt='CouchBrowse 1' /><br/><br/><img src='http://ciarang.com/wp-content/uploads/2007/09/couchbrowse2.png' alt='CouchBrowse 2' /><br/><br/><img src='http://ciarang.com/wp-content/uploads/2007/09/couchbrowse3.png' alt='CouchBrowse 3' />
</p>
<p></center></p>
<p>It&#8217;s worth pointing out that it&#8217;s still fairly rudimentary, but working. In particular, it needs some proper JSON parsing rather than the ad-hoc horrors I threw together, and some decent formatting and syntax highlighting would be good too, but it suits my purposes for now.</p>
<p>If anyone is actually interested in getting hold of it, shout and I&#8217;ll stick the code and/or binaries somewhere. It was built with SharpDevelop 2.2 on Windows &#8211; I don&#8217;t know how hard it would be to get it running under Mono.</p>
]]></content:encoded>
			<wfw:commentRss>http://ciarang.com/posts/a-couchdb-gui-front-end/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>More CouchDB</title>
		<link>http://ciarang.com/posts/more-couchdb</link>
		<comments>http://ciarang.com/posts/more-couchdb#comments</comments>
		<pubDate>Mon, 10 Sep 2007 23:02:42 +0000</pubDate>
		<dc:creator>CiaranG</dc:creator>
				<category><![CDATA[CouchDB]]></category>
		<category><![CDATA[Erlang]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://blog.ciarang.com/index.php/archives/108</guid>
		<description><![CDATA[At the end of the my last post I hadn&#8217;t managed to get all my test data uploaded to the CouchDB database. It turns out there was not one problem, but two. The first was due to xmerl returning unexpected data when an ampersand was present in an attribute value. Say, for example, the attribute [...]]]></description>
			<content:encoded><![CDATA[<p>At the end of the my <a href="http://ciarang.com/index.php/archives/107">last post</a> I hadn&#8217;t managed to get all my test data uploaded to the CouchDB database. It turns out there was not one problem, but two.</p>
<p><span id="more-108"></span></p>
<p>The first was due to xmerl returning unexpected data when an ampersand was present in an attribute value. Say, for example, the attribute has a value of &#8220;A&#038;ampB&#8221;, I would expect Element#xmlAttributeValue to return the list [65,38,66]. What it actually returns is [65,[38],66]. That&#8217;s not just my expectation either &#8211; <a href="http://www.erlang-projects.org/Public/news/ejson/view" class="broken_link">ejson</a>, on which <a href="http://code.google.com/p/erlcouch/">erlcouch</a> is based, goes into a terminal sulk when asked to encode that. That&#8217;s surely a bug, it should at least fail rather than sitting there indefinitely. I&#8217;m inclined to think the xmerl output is wrong in the first place, as I can&#8217;t find anything in the documentation that says it would return anything other than a flat list.</p>
<p>In any case, the simple solution to that problem was to lists:flatten(Element#xmlAttribute).</p>
<p>The second problem was a bit more predictable &#8211; UTF-8 encoding. (Damn that Björk). I thought this must have been the same bug reported by <a href="http://intertwingly.net/blog/2007/09/07/Ascetic-Database-Architectures">Sam Ruby</a> the other day, and I can see some UTF-8 related stuff in SVN since I last took at copy, but updating to latest revision (184) didn&#8217;t solve my problem. To get it working I had to do this:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">cp</span> <span style="color: #660033;">-r</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>erlang<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>xmerl-1.1.4<span style="color: #000000; font-weight: bold;">/</span> <span style="color: #007800;">$HOME</span><span style="color: #000000; font-weight: bold;">/</span>couchdb<span style="color: #000000; font-weight: bold;">/</span>lib</pre></div></div>

<p>For some reason, CouchDB couldn&#8217;t find the xmerl_ucs library until I did. Presumably something wrong with my setup, although it works fine from the Erlang shell. (<b>Update:</b> see comments for a better fix.)</p>
<p>After that, it transpired that I had to UTF-8 encode the data myself BEFORE handing it to erlcouch, so with all the above in mind (and a bit of de-windification of the filename field) the new import code looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #014ea4;">-</span><span style="color: #5400b3;">module</span><span style="color: #109ab8;">&#40;</span>djimportc<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">export</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span>start<span style="color: #014ea4;">/</span><span style="color: #ff9600;">0</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">include_lib</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;/usr/local/lib/erlang/lib/xmerl-1.1.4/include/xmerl.hrl&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">start</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">% Connect to CouchDB and create database...</span>
  <span style="color: #45b3e6;">Host</span> <span style="color: #014ea4;">=</span> couch:<span style="color: #ff3c00;">get_host</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#123;</span>host<span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;localhost&quot;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span>port<span style="color: #6bb810;">,</span> <span style="color: #ff9600;">8888</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
  <span style="color: #45b3e6;">DB</span> <span style="color: #014ea4;">=</span> couch:<span style="color: #ff3c00;">create_db</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Host</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;dj&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">% Parse the document and add record records to the table...</span>
  <span style="color: #109ab8;">&#123;</span> <span style="color: #45b3e6;">Xml</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_Rest</span> <span style="color: #109ab8;">&#125;</span> <span style="color: #014ea4;">=</span> <span style="color: #ff4e18;">xmerl_scan</span>:<span style="color: #ff3c00;">file</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;../media/LwDJState.xml&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
  <span style="color: #45b3e6;">Records</span> <span style="color: #014ea4;">=</span> <span style="color: #ff4e18;">xmerl_xpath</span>:<span style="color: #ff3c00;">string</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;/lwdj/record&quot;</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">Xml</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
  <span style="color: #ff3c00;">process_record</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Records</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">DB</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #666666; font-style: italic;">% Process a list of records...</span>
<span style="color: #ff3c00;">process_record</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">DB</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #006600;">ok</span><span style="color: #6bb810;">;</span>
<span style="color: #ff3c00;">process_record</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">Head</span>|Rest<span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">DB</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
  <span style="color: #ff3c00;">process_record_attrs</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Head</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">xmlElement</span><span style="color: #6bb810;">.</span>attributes<span style="color: #6bb810;">,</span><span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">DB</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
  <span style="color: #ff3c00;">process_record</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Rest</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">DB</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #666666; font-style: italic;">% Process attributes for a record...</span>
<span style="color: #ff3c00;">process_record_attrs</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">New_rec</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">DB</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
  <span style="color: #ff4e18;">io</span>:<span style="color: #ff3c00;">format</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;Writing document: ~p~n&quot;</span><span style="color: #6bb810;">,</span><span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">New_rec</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
  <span style="color: #109ab8;">&#123;</span><span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">_</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">_</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">_</span><span style="color: #109ab8;">&#125;</span><span style="color: #014ea4;">=</span>couch:<span style="color: #ff3c00;">save_doc</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">DB</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">New_rec</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">;</span>
&nbsp;
<span style="color: #ff3c00;">process_record_attrs</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">Head</span>|Rest<span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">New_rec</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">DB</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
  <span style="color: #45b3e6;">Fieldname</span><span style="color: #014ea4;">=</span><span style="color: #45b3e6;">Head</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">xmlAttribute</span><span style="color: #6bb810;">.</span>name<span style="color: #6bb810;">,</span>
  <span style="color: #45b3e6;">V</span><span style="color: #014ea4;">=</span><span style="color: #ff4e18;">lists</span>:<span style="color: #ff3c00;">flatten</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Head</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">xmlAttribute</span><span style="color: #6bb810;">.</span>value<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
  <span style="color: #186895;">if</span>
    <span style="color: #45b3e6;">Fieldname</span><span style="color: #014ea4;">==</span>filename <span style="color: #6bb810;">-&gt;</span>
      <span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">_</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">Value2</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">_</span><span style="color: #109ab8;">&#125;</span><span style="color: #014ea4;">=</span><span style="color: #ff4e18;">regexp</span>:<span style="color: #ff3c00;">gsub</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">V</span><span style="color: #6bb810;">,</span><span style="color: #ff7800;">&quot;<span style="color: #000099; font-weight: bold;">\\</span><span style="color: #000099; font-weight: bold;">\\</span>&quot;</span><span style="color: #6bb810;">,</span><span style="color: #ff7800;">&quot;/&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
      <span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">_</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">Value</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">_</span><span style="color: #109ab8;">&#125;</span><span style="color: #014ea4;">=</span><span style="color: #ff4e18;">regexp</span>:<span style="color: #ff3c00;">gsub</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Value2</span><span style="color: #6bb810;">,</span><span style="color: #ff7800;">&quot;M:&quot;</span><span style="color: #6bb810;">,</span><span style="color: #ff7800;">&quot;&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">;</span>
    true <span style="color: #6bb810;">-&gt;</span>
      <span style="color: #45b3e6;">Value</span><span style="color: #014ea4;">=</span><span style="color: #45b3e6;">V</span>
  <span style="color: #186895;">end</span><span style="color: #6bb810;">,</span>
  <span style="color: #ff3c00;">process_record_attrs</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Rest</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">New_rec</span><span style="color: #014ea4;">++</span><span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">Fieldname</span><span style="color: #6bb810;">,</span>xmerl_ucs:<span style="color: #ff3c00;">to_utf8</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Value</span><span style="color: #109ab8;">&#41;</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">DB</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></pre></div></div>

<p>With that done, I have some data to play with, and I must say I was surprised (pleasantly) to see it all come back to me with the non-ASCII stuff intact when I tested it from the Javascript console.</p>
]]></content:encoded>
			<wfw:commentRss>http://ciarang.com/posts/more-couchdb/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A quick look at CouchDB</title>
		<link>http://ciarang.com/posts/a-quick-look-at-couchdb</link>
		<comments>http://ciarang.com/posts/a-quick-look-at-couchdb#comments</comments>
		<pubDate>Sun, 09 Sep 2007 23:06:12 +0000</pubDate>
		<dc:creator>CiaranG</dc:creator>
				<category><![CDATA[CouchDB]]></category>
		<category><![CDATA[Erlang]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://blog.ciarang.com/index.php/archives/107</guid>
		<description><![CDATA[There&#8217;s been a lot of talk about CouchDB lately, some of it in a rather foolish &#8220;this heralds the death of the RDBMS&#8221; style. A more sensible view is that it&#8217;s an interesting database that could be very useful in some circumstances. I&#8217;m particularly interested because it seems to use a number of techniques I&#8217;ve [...]]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s been a lot of talk about <a href="http://couchdb.org/">CouchDB</a> lately, some of it in a rather foolish &#8220;this heralds the death of the RDBMS&#8221; style. A more sensible view is that it&#8217;s an interesting database that could be very useful in some circumstances. I&#8217;m particularly interested because it seems to use a number of techniques I&#8217;ve implemented and developed in my own database engine. Although I am very fond of mine, it wasn&#8217;t designed to scale, and as such it doesn&#8217;t. Anyway, that&#8217;s a topic for another day, so back to CouchDB:</p>
<p><span id="more-107"></span></p>
<p>This is how I built it from source, using my <a href="http://ciarang.com/index.php/archives/103">previously documented Debian test setup</a> as a base system:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> libicu36 libicu36-dev
<span style="color: #c20cb9; font-weight: bold;">mkdir</span> src
<span style="color: #7a0874; font-weight: bold;">cd</span> src
<span style="color: #c20cb9; font-weight: bold;">svn</span> <span style="color: #c20cb9; font-weight: bold;">co</span> <span style="color: #660033;">-r</span> <span style="color: #000000;">180</span> http:<span style="color: #000000; font-weight: bold;">//</span>couchdb.googlecode.com<span style="color: #000000; font-weight: bold;">/</span>svn<span style="color: #000000; font-weight: bold;">/</span>trunk<span style="color: #000000; font-weight: bold;">/</span> couchdb
<span style="color: #7a0874; font-weight: bold;">cd</span> couchdb
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">ERLANG_INCLUDE_DIR</span>=<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>erlang<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>include
.<span style="color: #000000; font-weight: bold;">/</span>build.sh
.<span style="color: #000000; font-weight: bold;">/</span>build.sh <span style="color: #660033;">--install</span>=<span style="color: #007800;">$HOME</span></pre></div></div>

<p>For whatever reason, I had to use a different <i>libicu</i> to <a href="http://intertwingly.net/blog/2007/09/04/Building-CouchDB">Sam Ruby</a>, but it worked. Starting it up:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">~<span style="color: #000000; font-weight: bold;">/</span>couchdb<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>startCouchDb.sh</pre></div></div>

<p>Working with CouchDB is easy from any language or platform, since it&#8217;s based around a straightforward HTTP/REST interface. For the purposes of my initial experiments, I&#8217;m using <a href="http://code.google.com/p/erlcouch/">erlcouch</a>, which is a wrapper library for Erlang. I did this to set it up:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">cd</span> ~
<span style="color: #c20cb9; font-weight: bold;">svn</span> <span style="color: #c20cb9; font-weight: bold;">co</span> <span style="color: #660033;">-r</span> <span style="color: #000000;">4</span> http:<span style="color: #000000; font-weight: bold;">//</span>erlcouch.googlecode.com<span style="color: #000000; font-weight: bold;">/</span>svn<span style="color: #000000; font-weight: bold;">/</span>trunk<span style="color: #000000; font-weight: bold;">/</span> erlcouch</pre></div></div>

<p>The SVN version includes the compiled BEAM files, so I didn&#8217;t bother building anything, and went straight to importing the same dataset as I did into Mnesia <a href="">previously</a>, with an adapted version of that Erlang program as follows:</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #014ea4;">-</span><span style="color: #5400b3;">module</span><span style="color: #109ab8;">&#40;</span>djimportc<span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">export</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span>start<span style="color: #014ea4;">/</span><span style="color: #ff9600;">0</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #014ea4;">-</span><span style="color: #5400b3;">include_lib</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;/usr/local/lib/erlang/lib/xmerl-1.1.4/include/xmerl.hrl&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #ff3c00;">start</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">% Connect to CouchDB and create database...</span>
  <span style="color: #45b3e6;">Host</span> <span style="color: #014ea4;">=</span> couch:<span style="color: #ff3c00;">get_host</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#123;</span>host<span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;localhost&quot;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#123;</span>port<span style="color: #6bb810;">,</span> <span style="color: #ff9600;">8888</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
  <span style="color: #45b3e6;">DB</span> <span style="color: #014ea4;">=</span> couch:<span style="color: #ff3c00;">create_db</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Host</span><span style="color: #6bb810;">,</span> <span style="color: #ff7800;">&quot;dj&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">% Parse the document and add record records to the table...</span>
  <span style="color: #109ab8;">&#123;</span> <span style="color: #45b3e6;">Xml</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">_Rest</span> <span style="color: #109ab8;">&#125;</span> <span style="color: #014ea4;">=</span> <span style="color: #ff4e18;">xmerl_scan</span>:<span style="color: #ff3c00;">file</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;../media/LwDJState.xml&quot;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
  <span style="color: #45b3e6;">Records</span> <span style="color: #014ea4;">=</span> <span style="color: #ff4e18;">xmerl_xpath</span>:<span style="color: #ff3c00;">string</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;/lwdj/record&quot;</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">Xml</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
  <span style="color: #ff3c00;">process_record</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Records</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">DB</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #666666; font-style: italic;">% Process a list of records...</span>
<span style="color: #ff3c00;">process_record</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">DB</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span> <span style="color: #006600;">ok</span><span style="color: #6bb810;">;</span>
<span style="color: #ff3c00;">process_record</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">Head</span>|Rest<span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">DB</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
  <span style="color: #ff4e18;">io</span>:<span style="color: #ff3c00;">format</span><span style="color: #109ab8;">&#40;</span><span style="color: #ff7800;">&quot;Processing record~n&quot;</span><span style="color: #6bb810;">,</span><span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
  <span style="color: #ff3c00;">process_record_attrs</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Head</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">xmlElement</span><span style="color: #6bb810;">.</span>attributes<span style="color: #6bb810;">,</span><span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">DB</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">,</span>
  <span style="color: #ff3c00;">process_record</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Rest</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">DB</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span>
&nbsp;
<span style="color: #666666; font-style: italic;">% Process attributes for a record...</span>
<span style="color: #ff3c00;">process_record_attrs</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">New_rec</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">DB</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
  <span style="color: #006600;">couch</span>:<span style="color: #ff3c00;">save_doc</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">DB</span><span style="color: #6bb810;">,</span> <span style="color: #45b3e6;">New_rec</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">;</span>
&nbsp;
<span style="color: #ff3c00;">process_record_attrs</span><span style="color: #109ab8;">&#40;</span><span style="color: #109ab8;">&#91;</span><span style="color: #45b3e6;">Head</span>|Rest<span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">New_rec</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">DB</span><span style="color: #109ab8;">&#41;</span> <span style="color: #6bb810;">-&gt;</span>
  <span style="color: #45b3e6;">Fieldname</span><span style="color: #014ea4;">=</span><span style="color: #45b3e6;">Head</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">xmlAttribute</span><span style="color: #6bb810;">.</span>name<span style="color: #6bb810;">,</span>
  <span style="color: #45b3e6;">Value</span><span style="color: #014ea4;">=</span><span style="color: #45b3e6;">Head</span><span style="color: #ff9600;">#</span><span style="color: #d400ed;">xmlAttribute</span><span style="color: #6bb810;">.</span>value<span style="color: #6bb810;">,</span>
  <span style="color: #ff3c00;">process_record_attrs</span><span style="color: #109ab8;">&#40;</span><span style="color: #45b3e6;">Rest</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">New_rec</span><span style="color: #014ea4;">++</span><span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#123;</span><span style="color: #45b3e6;">Fieldname</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">Value</span><span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">,</span><span style="color: #45b3e6;">DB</span><span style="color: #109ab8;">&#41;</span><span style="color: #6bb810;">.</span></pre></div></div>

<p>The good news is that it sort of worked, in that 44 of the 6714 records were uploaded before the HTTP sending process seemed to stall. I could see that the data was in the database using the Javascript console (http://localhost:8888/_utils/shell.html), so I suspect that either something is wrong in erlcouch, or I have done something stupid in the above code &#8211; CouchDB itself seemed to be quite happy and responsive. The bad news is that I&#8217;m determined to get enough sleep tonight, what with having real work to do tomorrow, so no answers will be forthcoming until tomorrow night at the earliest.</p>
]]></content:encoded>
			<wfw:commentRss>http://ciarang.com/posts/a-quick-look-at-couchdb/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Virtual Debian test/dev setup</title>
		<link>http://ciarang.com/posts/virtual-debian-testdev-setup</link>
		<comments>http://ciarang.com/posts/virtual-debian-testdev-setup#comments</comments>
		<pubDate>Sat, 08 Sep 2007 07:47:43 +0000</pubDate>
		<dc:creator>CiaranG</dc:creator>
				<category><![CDATA[Erlang]]></category>
		<category><![CDATA[ErlyWeb]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[XMPP]]></category>
		<category><![CDATA[YAWS]]></category>

		<guid isPermaLink="false">http://blog.ciarang.com/index.php/archives/103</guid>
		<description><![CDATA[I decided to switch my multi-virtual machine test/dev setup over to a minimal Debian install, not least because I couldn&#8217;t keep my mind off the fact that I was carting around a full desktop installation along with various &#8216;pretty&#8217; desktop backgrounds, system administration for GUI-monkeys applications, and god knows what else. One batch of this [...]]]></description>
			<content:encoded><![CDATA[<p>I decided to switch my multi-virtual machine test/dev setup over to a minimal Debian install, not least because I couldn&#8217;t keep my mind off the fact that I was carting around a full desktop installation along with various &#8216;pretty&#8217; desktop backgrounds, system administration for GUI-monkeys applications, and god knows what else. One batch of this stuff is bad enough, but repeated N times it&#8217;s too much for me to handle.</p>
<p><span id="more-103"></span></p>
<p>I also can&#8217;t help viewing those VMware &#8216;appliance&#8217; things with suspicion, and I&#8217;m starting to put real data on these things now, so I went for a clean install from debian-40r1-i386-netinst.iso. Doing the initial setup via the VMware Server console, viewed via VNC, is unbelievably painful but all that was needed after the actual install was to reconfigure the networking and install sshd before getting back to a nice clean SSH login.</p>
<p>I&#8217;m slightly cross with myself for not having scripted the rest of the setup yet, but on the other hand I&#8217;m pleased I was anal enough to document it all in the first place, because all I had to do was copy the commands out of my previous posts here and paste them into the SSH window to get back to where I was. I also set up Debian to use sudo, because I prefer that to using su.</p>
<p>The only differences in all the setup steps from the previous &#8216;doing X on Ubuntu&#8217; posts due to the change of distribution were:</p>
<ul>
<li>The m4 package was already installed.</li>
<li>Instead of libssl-dev, I needed openssl.</li>
<li>I left out the detail of how to fix ejabberdctl. (added as a comment to <a href="http://ciarang.com/index.php/archives/94">that post</a>)</li>
</ul>
<p>I didn&#8217;t go as far as the Mnesia data import stage, stopping instead after installing and testing Erlyweb, for reasons that will become apparent later. For the record, the steps were:</p>
<ul>
<li><a href="http://ciarang.com/index.php/archives/93">Erlang</a></li>
<li><a href="http://ciarang.com/index.php/archives/94">Ejabberd</a></li>
<li><a href="http://ciarang.com/index.php/archives/95">Jabberlang</a></li>
<li><a href="http://ciarang.com/index.php/archives/96">YAWS</a></li>
<li><a href="http://ciarang.com/index.php/archives/97">ErlyWeb</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://ciarang.com/posts/virtual-debian-testdev-setup/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

