<?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>Gavin Panella &#187; Computing</title>
	<atom:link href="http://gavinpanella.com/blog/category/computing/feed/" rel="self" type="application/rss+xml" />
	<link>http://gavinpanella.com/blog</link>
	<description></description>
	<lastBuildDate>Mon, 06 Jul 2009 09:27:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Twitter API encoding is somewhat bonkers</title>
		<link>http://gavinpanella.com/blog/2008/12/18/twitter-api-encoding-is-somewhat-bonkers/</link>
		<comments>http://gavinpanella.com/blog/2008/12/18/twitter-api-encoding-is-somewhat-bonkers/#comments</comments>
		<pubDate>Thu, 18 Dec 2008 14:57:44 +0000</pubDate>
		<dc:creator>Gavin Panella</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://gavinpanella.com/blog/?p=52</guid>
		<description><![CDATA[Take a look at the Encoding section in the Twitter API docs: The Twitter API supports UTF-8 encoding. Please note that angle brackets (&#8220;&#60;&#8221; and &#8220;&#62;&#8221;) are entity-encoded to prevent Cross-Site Scripting attacks for web-embedded consumers of JSON API output. The resulting encoded entities do count towards the 140 character limit. Does anyone notice the [...]]]></description>
			<content:encoded><![CDATA[<p>Take a look at the <a href="http://apiwiki.twitter.com/REST+API+Documentation#Encoding">Encoding</a> section in the Twitter API docs:</p>
<blockquote><p>The Twitter API supports UTF-8 encoding. Please note that angle brackets (&#8220;&lt;&#8221; and &#8220;&gt;&#8221;) are entity-encoded to prevent Cross-Site Scripting attacks for web-embedded consumers of JSON API output. The resulting encoded entities <strong>do</strong> count towards the 140 character limit.</p></blockquote>
<p>Does anyone notice the weirdness there? Apart from the <a href="http://php.net/magic_quotes">MAGIC_QUOTES</a> smell.</p>
<p>If I were feeling pathological, I could tweet a message of 140 characters all between the Unicode code-points U+010000-U+10FFFF. I think that would end up as 560 bytes. And I think that would be all fine with Twitter. Which is another way of saying that Twitter would, I assume, be happy to exceed 140 <em>bytes</em> for a message if it were written in, say, Japanese.</p>
<p>By contrast, while on my pathological holiday from good sense, I would only be able to tweet a message of 35 angle brackets &#8211; hence 140 characters, 140 bytes in UTF-8 &#8211; because the encoded angle-brackets count toward the number of <em>characters</em>. Seems a bit backwards doesn&#8217;t it?</p>
<p>Does anyone know the reasoning here? Or are the docs at fault?</p>
<p>Back to the angle-bracket quoting. Just as the PHP folk are finally ending their own embarrassing journey through that silliness, it looks to me like Twitter are now making a similar mistake. JSON should safely encapsulate angle-brackets, so perhaps I don&#8217;t understand the problem that they are trying to solve?</p>
<p>One more question: what if I tweet &#8220;&amp;gt;&#8221;? When using the API, can that be distinguished from a &#8220;&gt;&#8221;?</p>
<p>(You might have noticed that I&#8217;ve have so far been too lazy to experiment with all this stuff; I just wanted to write it down before I forgot. I&#8217;ll add a comment if I get the time to play.)</p>
]]></content:encoded>
			<wfw:commentRss>http://gavinpanella.com/blog/2008/12/18/twitter-api-encoding-is-somewhat-bonkers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mac OS X, I&#8217;m going to kill you!</title>
		<link>http://gavinpanella.com/blog/2008/07/18/mac-os-x-im-going-to-kill-you/</link>
		<comments>http://gavinpanella.com/blog/2008/07/18/mac-os-x-im-going-to-kill-you/#comments</comments>
		<pubDate>Fri, 18 Jul 2008 17:40:56 +0000</pubDate>
		<dc:creator>Gavin Panella</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://gavinpanella.com/blog/?p=17</guid>
		<description><![CDATA[Farking hell, Mac OS X is really annoying me now. This, in case you hadn&#8217;t guessed already, is going to be a vitriolic rant, and is really for my own benefit rather than yours. But please read on anyway&#8230; iTunes keeps skipping tracks half way through. It will suddenly start playing the next track for [...]]]></description>
			<content:encoded><![CDATA[<p>Farking hell, Mac OS X is really annoying me now. This, in case you hadn&#8217;t guessed already, is going to be a vitriolic rant, and is really for my own benefit rather than yours. But please read on anyway&#8230;</p>
<p><span id="more-17"></span></p>
<ol>
<li> <em>iTunes</em> keeps skipping tracks half way through. It will suddenly start playing the next track for no obvious reason. Restarting stops this for a while.</li>
<li>The keyboard focus keeps going&#8230; elsewhere &#8211; into the void &#8211; as I type in an X11 window. The one other person I&#8217;ve asked about this has the same issue.</li>
<li><em>Spaces</em> is, well, just a bit crap compared to the multiple-desktop systems that you can find for X (as in X-Windows, or X11).</li>
<li>Window/application focusing and switching are sometimes just wrong. For example, Cmd-Tab switches between the most recently used applications, but Cmd-` (back-tick) cycles through the windows of the current application. Good luck to you if your application has, say, 10 windows open.</li>
<li><em>Terminal</em> is broken. I gave up on it a long time ago, hence the need for X11.</li>
<li><a href="http://www.macports.org/"><em>MacPorts</em></a> is great, except for <code>port</code>, the package manager, which is actually less useful than, say, <code>tar</code>. Why o why o why did they write yet another package manager? <em>Fink</em> at least had the good sense to use APT, but I don&#8217;t use it because I prefer the packages in MacPorts.</li>
<li>Sleep. Specifically safe-sleep. Which doesn&#8217;t work on my MacBook Pro. If I use safe-sleep (which is the default), the laptop will take several minutes to go to sleep, several minutes to wake up, and every 3 or 4 times will simply not wake up. Sometimes it will wake up but no login dialog box will appear, which means I have to put it back to sleep (and wait), then wake it up again (and wait and hope), and if the dialog box doesn&#8217;t appear, it probably means I need to hard-reboot. It would have been quicker to just pull the battery out. Actually, I disabled safe-sleep on Tiger, so maybe it works now on Leopard, but I&#8217;m not in the mood to try.</li>
<li>External monitors. I have a nice 30&#8243; Apple Cinema Display, which is simply great. However, using it with my MBP is a PITA:
<ol>
<li>For best use, start with MBP switched off (cold, not asleep).</li>
<li>Plug in monitor.</li>
<li>Turn on MBP, and quickly shut the lid.</li>
<li>Don&#8217;t open the lid.</li>
<li>Don&#8217;t open the lid.</li>
<li>If you open the lid, Mac OS will add the laptop screen to the available display space, then rearrange your windows, backdrops, dock and menu bar. And then, if you close the lid, the MBP will go to sleep, then take 5 minutes to wake up and show the login dialog box on the 30&#8243; display. Then all your windows will be in different places and at different sizes.</li>
<li>Don&#8217;t plug/unplug the monitor unless the MBP is switched off. Doing so will work 2 times in 3, the other time it will leave your machine not crashed, but not working either. Hard-reboot required. If you want to take your supposedly mobile laptop computer into the other room, think again.</li>
</ol>
</li>
</ol>
<p>I am <strong>sure</strong> there are more things that irk me, but that&#8217;s all for now.</p>
<p>There are some things I do like:</p>
<ol>
<li><em>Mail</em>. It works better than any MUA I know. I just wish it wasn&#8217;t tethered to Mac OS X, highlighted URLs properly (it doesn&#8217;t understand ~ in URLs, which is, oh, only in half the URLs I get sent every day), and came with PGP/GnuPG working out of the box.</li>
<li><em>Time Machine</em>. Fantastic. I love it. It makes me feel so much better. I just hope it actually works when I need it.</li>
<li><em>iPhone</em>. Okay, I could use MS Windows to work with my iPhone, but&#8230; hah, I&#8217;m not that bloody stupid. Anyway, this is not really a feature of Mac OS, it&#8217;s just a requirement. Which is, actually, somewhat annoying. And the new iPhone 2.0 software is a bit shit too.</li>
</ol>
<p>I like 2.5 things (the iPhone &#8220;feature&#8221; gets 0.5). And I&#8217;m <strong>sure</strong> there aren&#8217;t any more.</p>
<p>I now realise that I would rather use Linux (again; I used to use Linux all the time on the desktop). But <a href="http://www.ubuntu.com/">Ubuntu</a> (which is my distro of choice) is a PITA all of its own to install on Apple hardware, so I&#8217;m just going to persevere with Mac OS X for now.</p>
<p>That, and because I have an iPhone. Grr, Apple, you now make me feel locked-in to your platform, and I don&#8217;t like that.</p>
]]></content:encoded>
			<wfw:commentRss>http://gavinpanella.com/blog/2008/07/18/mac-os-x-im-going-to-kill-you/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Shell FTW!</title>
		<link>http://gavinpanella.com/blog/2007/09/03/17/</link>
		<comments>http://gavinpanella.com/blog/2007/09/03/17/#comments</comments>
		<pubDate>Mon, 03 Sep 2007 07:05:17 +0000</pubDate>
		<dc:creator>Gavin Panella</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[First published at Premolo.com]]></category>

		<guid isPermaLink="false">http://www.premolo.com/blog/2007/09/03/17/</guid>
		<description><![CDATA[Ha, do this with a GUI: lsof -p $(ps ux &#124; egrep [/]opt/local &#124; awk '{print $2}' &#124; xargs &#124; sed 's/ /,/g') &#124; fgrep opt/local &#124; awk '{print $9}' &#124; sort -u &#124; xargs port provides &#124; sed 's/.*: //' &#124; sort -u &#124; xargs port -f upgrade The command line rules! It&#8217;s meant [...]]]></description>
			<content:encoded><![CDATA[<p>Ha, do this with a GUI:</p>
<p><code>lsof -p $(ps ux | egrep [/]opt/local | awk '{print $2}' | xargs | sed 's/ /,/g') | fgrep opt/local | awk '{print $9}' | sort -u | xargs port provides | sed 's/.*: //' | sort -u | xargs port -f upgrade<br />
</code></p>
<p>The command line rules!</p>
<p><span id="more-16"></span></p>
<p>It&#8217;s meant to rebuild every MacPorts package I&#8217;ve got installed that is loaded when I start XDarwin (the xfree86 port in MacPorts) in a vague attempt to fix the completely broken mouse pointer in X.</p>
]]></content:encoded>
			<wfw:commentRss>http://gavinpanella.com/blog/2007/09/03/17/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Disable Java</title>
		<link>http://gavinpanella.com/blog/2007/07/31/disable-java/</link>
		<comments>http://gavinpanella.com/blog/2007/07/31/disable-java/#comments</comments>
		<pubDate>Tue, 31 Jul 2007 14:59:34 +0000</pubDate>
		<dc:creator>Gavin Panella</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[First published at Premolo.com]]></category>

		<guid isPermaLink="false">http://www.premolo.com/blog/2007/07/31/disable-java/</guid>
		<description><![CDATA[A few weeks ago I disabled Java in every browser I use. No more applets. It feels liberating. Flash might be next. In a company far far away, I used to be a Java developer. At that time I thought that applets could be a good thing for the web. Since then, and for most [...]]]></description>
			<content:encoded><![CDATA[<p>A few weeks ago I disabled Java in every browser I use. No more applets. It feels liberating. Flash might be next.</p>
<p><span id="more-15"></span></p>
<p>In a company far far away, I used to be a Java developer. At that time I thought that applets could be a good thing for the web. Since then, and for most of this millennium, I&#8217;ve been somewhere between indifferent and blisteringly annoyed when encountering Java applets. I silently hoped they would go away.</p>
<p>But they just won&#8217;t die.</p>
<p>Recently I joined <a href="http://www.facebook.com/">Facebook</a>, and they use a crappy upload applet for photos. Which reminded me of the crappy upload applet that comes with <a href="http://gallery.menalto.com/">Gallery</a>. These might be the most beautifully crafted objects, whole Versailles of Java, but during the time the ruddy thing painfully loads I can&#8217;t use the browser, and the OS even mentions that things are not responding. Okay, Versailles was not built in a day, so I&#8217;ll go and feed the donkeys or something and come back when it&#8217;s done. But, of course, it&#8217;s not beautiful as promised. It&#8217;s an eyesore, a pig to use, and breaks just after I&#8217;ve invested 20 excruciating minutes choosing photos of family barbecues.</p>
<p>So I&#8217;m voting with my browser preferences, and I vote for no more Java on the web. Applets were cool for a month or two, but have been a mercilessly flogged but nevertheless dead horse ever since.</p>
<p>Flash, on the other hand, actually has a use. Video. After over a decade of squabbling between Real, Apple Quicktime and Microsoft SomethingMediocre, it took a vector animation program to pretty much solve cross-browser video.</p>
<p>That&#8217;s great. But I really really do not want to watch another whizzy website Flash-splash page or another Microsoft disinfomercial next to the news. So Flash might be next to get the chop.</p>
<p>I&#8217;ll be using <a href="http://lynx.isc.org/">Lynx</a> before the year&#8217;s out.</p>
]]></content:encoded>
			<wfw:commentRss>http://gavinpanella.com/blog/2007/07/31/disable-java/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Convert all your Apple Lossless files to FLAC</title>
		<link>http://gavinpanella.com/blog/2007/02/02/convert-all-your-apple-lossless-files-to-flac/</link>
		<comments>http://gavinpanella.com/blog/2007/02/02/convert-all-your-apple-lossless-files-to-flac/#comments</comments>
		<pubDate>Fri, 02 Feb 2007 21:10:09 +0000</pubDate>
		<dc:creator>Gavin Panella</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[Music]]></category>
		<category><![CDATA[First published at Premolo.com]]></category>

		<guid isPermaLink="false">http://www.premolo.com/blog/2007/02/02/convert-all-your-apple-lossless-files-to-flac/</guid>
		<description><![CDATA[I&#8217;ve written a Python script that converts audio files from Apple Lossless (.m4a) to FLAC (.flac) format. Crucially, it copies meta-data, with the exception of the cover art (for now at least). I&#8217;ve got about 1000 tracks in Apple Lossless (.m4a) format, all ripped from my CDs. Tools like MPlayer now support it, and Amarok [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve written <a href="http://gavinpanella.com/~gavin/Scripts/m4a-to-flac.py">a Python script that converts audio files from Apple Lossless (.m4a) to FLAC (.flac) format</a>. Crucially, <strong>it copies meta-data</strong>, with the exception of the cover art (for now at least).</p>
<p><span id="more-13"></span></p>
<p>I&#8217;ve got about 1000 tracks in Apple Lossless (.m4a) format, all ripped from my CDs. Tools like <a href="http://www.mplayerhq.hu/">MPlayer</a> now support it, and <a href="http://amarok.kde.org/">Amarok</a> can play them, so why bother converting them? Well, for a long time they were <em>not</em> supported so I could only listen to them on my Mac. I&#8217;ve also realised, if I&#8217;m going to keep a music collection on my computer, that the format I choose better be open so I can still listen to my tunes in a decade.</p>
<p>You&#8217;ll need the following:</p>
<ul>
<li><a href="http://www.python.org/">Python</a> 2.4 or later.</li>
<li><a href="http://www.sacredchao.net/quodlibet/wiki/Development/Mutagen">Mutagen</a> is a pure-Python meta-data library, and I wrote the script using version 1.8.</li>
<li><a href="http://www.mplayerhq.hu/">MPlayer</a> is used to convert from Apple Lossless to WAV. I was using version 1.0_rc1.</li>
<li><a href="http://flac.sourceforge.net/">FLAC</a> of course, to encode the WAV. My machine has version 1.1.2-r8 installed.</li>
</ul>
<p>So far I&#8217;ve only tested the script with one <a href="http://www.moloko.co.uk/">Moloko</a> album on a Linux machine. It&#8217;ll probably work just fine on any Unix-like OS, and may just work on Windows if you peddle hard. I&#8217;m going to convert all 1000 tracks soon, but first I need to find some disk space. My advice: <strong>take backups</strong>, because there are no warranties, and, though I don&#8217;t mean to scare you, the pieces are yours to keep if things break.</p>
<p>Happy converting, and try the magic <code>--help</code> switch if you&#8217;re lost.</p>
<p><em>[Edited to fix broken link, 2009-07-06]</em></p>
]]></content:encoded>
			<wfw:commentRss>http://gavinpanella.com/blog/2007/02/02/convert-all-your-apple-lossless-files-to-flac/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google Sitemap Gen v1.4 ebuild</title>
		<link>http://gavinpanella.com/blog/2007/02/01/google-sitemap-gen-v14-ebuild/</link>
		<comments>http://gavinpanella.com/blog/2007/02/01/google-sitemap-gen-v14-ebuild/#comments</comments>
		<pubDate>Thu, 01 Feb 2007 12:06:59 +0000</pubDate>
		<dc:creator>Gavin Panella</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[First published at Premolo.com]]></category>

		<guid isPermaLink="false">http://www.premolo.com/blog/2007/02/01/google-sitemap-gen-v14-ebuild/</guid>
		<description><![CDATA[It&#8217;s over a year since it was released, but for Gentoo users, I&#8217;ve posted an ebuild for version 1.4 of the Google Sitemap Generator in my Portage overlay. You&#8217;ll find it at www-misc/goog-sitemapgen. In other news, I want to apologise for my content-free blatherings about the Apple iPhone. I don&#8217;t think anyone reads this blog [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s over a year since it was released, but for <a href="http://www.gentoo.org/">Gentoo</a> users, I&#8217;ve posted an ebuild for version 1.4 of the <a href="http://goog-sitemapgen.sourceforge.net/">Google Sitemap Generator</a> in my <a href="http://www.premolo.net/~gavin/Portage/overlay/">Portage overlay</a>. You&#8217;ll find it at <code>www-misc/goog-sitemapgen</code>.</p>
<p>In other news, I want to apologise for my <a href="http://www.premolo.com/blog/2007/01/10/at-first-sight-the-apple-iphone-is-a-work-of-genius">content-free blatherings about the Apple iPhone</a>. I don&#8217;t think anyone reads this blog so I&#8217;m talking to myself, but I want to make my contrition public even so, for future readers :-)</p>
]]></content:encoded>
			<wfw:commentRss>http://gavinpanella.com/blog/2007/02/01/google-sitemap-gen-v14-ebuild/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Expire Junk script</title>
		<link>http://gavinpanella.com/blog/2007/01/31/expire-junk-script/</link>
		<comments>http://gavinpanella.com/blog/2007/01/31/expire-junk-script/#comments</comments>
		<pubDate>Wed, 31 Jan 2007 21:07:41 +0000</pubDate>
		<dc:creator>Gavin Panella</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[First published at Premolo.com]]></category>

		<guid isPermaLink="false">http://www.premolo.com/blog/2007/01/31/expire-junk-script/</guid>
		<description><![CDATA[Here is a small Python script to expire junk mail in an IMAP mailbox. Apple Mail can automatically delete old junk mail, but I also use KMail and SquirrelMail, and it&#8217;s often a long wait between the times I load up Mail, so I need something else. It requires Python 2.4 (perhaps earlier, but I&#8217;ve [...]]]></description>
			<content:encoded><![CDATA[<p>Here is a <a href="http://www.premolo.net/~gavin/Scripts/expire-old-mail.py">small Python script to expire junk mail in an IMAP mailbox</a>.</p>
<p>Apple Mail can automatically delete old junk mail, but I also use KMail and SquirrelMail, and it&#8217;s often a long wait between the times I load up Mail, so I need something else. It requires Python 2.4 (perhaps earlier, but I&#8217;ve not tried it), and that&#8217;s it. Run it with a <code>--help</code> to get started.</p>
<p>Incidentally, the script is also in a <a href="http://bazaar-vcs.org/">Bazaar</a> repository, and you can branch it if you want:</p>
<blockquote><p><code>bzr branch \</p>
<p>http://www.premolo.net/~gavin/Scripts</code></p></blockquote>
<p>Right now the script doesn&#8217;t care about SSL (I run it on the same box as my <a href="http://www.courier-mta.org/">Courier IMAP</a> server) and it uses CRAM-MD5 authentication which may not be to your taste. It&#8217;s not had a lot of testing either, so be careful, and <strong>take some backups first</strong> :-) It&#8217;s in the public domain though, so happy hacking, and I&#8217;m more than willing to merge patches.</p>
]]></content:encoded>
			<wfw:commentRss>http://gavinpanella.com/blog/2007/01/31/expire-junk-script/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Premolo packages available from PyPI</title>
		<link>http://gavinpanella.com/blog/2007/01/06/premolo-packages-available-from-pypi/</link>
		<comments>http://gavinpanella.com/blog/2007/01/06/premolo-packages-available-from-pypi/#comments</comments>
		<pubDate>Sat, 06 Jan 2007 11:13:43 +0000</pubDate>
		<dc:creator>Gavin Panella</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[First published at Premolo.com]]></category>

		<guid isPermaLink="false">http://www.premolo.com/blog/2007/01/06/premolo-packages-available-from-pypi/</guid>
		<description><![CDATA[In the last few days I&#8217;ve posted the Premolo packages to the Python Package Index, or PyPI. Source distributions and Eggs are available. The easiest way to install, say Alfie, is to use easy_install from setuptools: easy_install premolo-alfie I&#8217;ll be adding in script support for running Alfie from the command line, but in the meantime [...]]]></description>
			<content:encoded><![CDATA[<p>In the last few days I&#8217;ve posted the <a href="http://www.premolo.org/">Premolo packages</a> to the <a href="http://www.python.org/pypi">Python Package Index</a>, or <a href="http://www.python.org/pypi">PyPI</a>. Source distributions and Eggs are available.</p>
<p>The easiest way to install, say Alfie, is to use easy_install from <a href="http://peak.telecommunity.com/DevCenter/setuptools">setuptools</a>:</p>
<blockquote><p><code>easy_install premolo-alfie</code></p></blockquote>
<p>I&#8217;ll be adding in script support for running Alfie from the command line, but in the meantime you can use this slightly unwieldy incantation:</p>
<blockquote><p><code>python -c 'from premolo.alfie import template; from sys import argv; template.main(*argv[1:])'</code></p></blockquote>
<p>I&#8217;m working mostly on <a href="http://www.premolo.org/projects/alfie">Alfie</a> at the moment, and hoping to get a 1.0 release out the door in the first quarter of 2007.</p>
]]></content:encoded>
			<wfw:commentRss>http://gavinpanella.com/blog/2007/01/06/premolo-packages-available-from-pypi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why I won&#8217;t be using MySQL for my next project</title>
		<link>http://gavinpanella.com/blog/2006/10/15/why-i-wont-be-using-mysql-for-my-next-project/</link>
		<comments>http://gavinpanella.com/blog/2006/10/15/why-i-wont-be-using-mysql-for-my-next-project/#comments</comments>
		<pubDate>Sun, 15 Oct 2006 09:10:22 +0000</pubDate>
		<dc:creator>Gavin Panella</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[First published at Premolo.com]]></category>

		<guid isPermaLink="false">http://www.premolo.com/blog/2006/10/15/why-i-wont-be-using-mysql-for-my-next-project/</guid>
		<description><![CDATA[The world&#8217;s most popular database is also the VHS of databases. It gets the job done, but the picture is grainy, the sound wows in and out, and it gets jammed once in a while. That&#8217;s what I found out on a recent project with MySQL 4.1. First, some context. I recently launched a dating [...]]]></description>
			<content:encoded><![CDATA[<p>The world&#8217;s most popular database is also the VHS of databases. It gets the job done, but the picture is grainy, the sound wows in and out, and it gets jammed once in a while. That&#8217;s what I found out on a recent project with MySQL 4.1.</p>
<p>First, some context.</p>
<p>I recently launched a dating website for Luxembourg. &#8220;Oh no!&#8221; you scream, &#8220;Not another bleedin&#8217; dating website!&#8221;. No apologies though; Luxembourg needs some loving, and I was the man for the job.</p>
<p><span id="more-8"></span></p>
<p>As part of my preparations I wrote a few libraries to flex my <a href="http://www.python.org/">Python</a> muscles, which is to say that I didn&#8217;t want to write any namby-pamby front-end code just yet. I&#8217;m a real hacker goddammit and I&#8217;m going to build me some libs.</p>
<p>So I wrote a <a href="http://www.premolo.org/projects/alfie">templating system</a>, some <a href="http://www.premolo.org/projects/apache">tools to wrap around Apache/mod_python</a>, and collected several other little things into a <a href="http://www.premolo.org/projects/base">common package</a>.</p>
<p>I also needed an object-relational mapper, or ORM if you&#8217;re short of time and/or breath. I kept cutting my fingers on the sharp edges of <a href="http://sqlobject.org/">SQLObject</a>, and the sheer volume of impenetrable documentation for <a href="http://www.sqlalchemy.org/">SQLAlchemy</a> was intimidating, so <a href="http://www.premolo.org/projects/storage">I wrote my own</a>. In fairness, the documentation for SQLAlchemy was probably fine, and SQLObject could have been fixed, but I wanted to do it my way, being a <em>real hacker</em> and all.</p>
<p>And thus began the journey which led me to conclude that I&#8217;m not going to use MySQL any more.</p>
<p>I&#8217;m not going to actually relive that journey with you. It was long and had lots of swearing. My wife can let you know all about the frantic desk-slamming, the irritated pacing, and the endless cups of tea. I did a lot of cursing during my skirmishes with mod_python too, and my choice of (human) language was generic/base enough that my wife probably could not discern the MySQL-induced tantrums from the mod_python ones.</p>
<p>I didn&#8217;t pull my hair out though. That&#8217;s because I hardly have any, and standing in front of a mirror trying to find strands to tear out with tweezers gets in the way of the &#8216;moment&#8217;.</p>
<p>Back to the point, my beefs with MySQL.</p>
<h2>Doctor, &#8230;</h2>
<h3>CTRL-C does not do what it says on the tin</h3>
<p>Firstly, and this is a bit petty, but when I type <code>CTRL-C</code> in the <code>mysql</code> command-line client, the client exits. This is really annoying, because I have learned that <code>CTRL-C</code> in <em>every other</em> interactive (*nix) command-line means either (a) ditch the current line, or (b) cancel the current command. There is no &#8220;(c) Exit&#8221;, because it doesn&#8217;t exist. Except for MySQL, where you are instantly dumped back to your shell, transactions turned to dust, and left with that bubbling sensation at the top of your head as the blood boils and takes another couple of months off your life.</p>
<h3>REFERENCES</h3>
<p>Declaring a column with a <code>REFERENCES</code> clause has no effect. In the words of a friend, this makes the baby Jesus cry.</p>
<p>You may ask &#8220;Why is this a problem?&#8221;, and you&#8217;d be right to ask. &#8220;It&#8217;s there for compatibility with other dialects of SQL&#8221; is a good answer, but not good enough. &#8220;It&#8217;s a feature that will be introduced later on&#8221; is another reply, to which I laugh heartily, then shed a small tear of my own. The problem is that it is misleading and creates a false sense of security. People believe that they have an extra tool to maintain the consistency of their data, but alas, it is not so. MySQL is a <strong>data</strong>base, and as such it should not go playing fast and loose with the data that it holds.</p>
<p>This is another example of unexpected results, but more fundamental than the CTRL-C thing. I know it&#8217;s in the docs, but my brain is not big enough to remember every gotcha in the book. Someone else said this first, but software should either work, or fail hard. MySQL should not accept my request; it should totally barf on my shoes. Perhaps there should be an option to ignore these clauses, but <em>that</em> should be the thing that you have to look in the manual to discover, and the default should be to either respect them or throw them back in your face.</p>
<h3>Foreign keys</h3>
<p>I first learnt about relational databases on Oracle 7, so I quickly learnt to appreciate foreign keys and all other kinds of constraints. I could not get enough of the lovely little hairy fellows. Of course, there is a limit to how well they can keep your data in pristine condition, but they do help to catch problems early, especially during development.</p>
<p>So I was glad to see that MySQL supports foreign keys on InnoDB tables, and have eagerly used them. But they have shortcomings.</p>
<p>Like, not actually working.</p>
<p>I restored some invalid data from a dump, just for fun (actually, I was being stupid, but to admit that would make me appear fallible, which, as we both know, I am not). It was invalid because it should have violated at least one foreign key constraint, but MySQL didn&#8217;t notice. At first I thought that MySQL had probably disabled constraints during loading, then had problems re-enabling them at the end, and not told me about it.</p>
<p>But the keys <em>were</em> enabled, and I was unable to add new invalid data to the table. I deleted some of the invalid data and tried to re-insert it, but that was denied too. Hmm.</p>
<p>Data consistency is bread-and-butter stuff for a relational database, and I subverted it unexpectedly. If a constraint is enabled, I fully expect that nothing violates that constraint, and it&#8217;s not unfair to insist on that.</p>
<p>Foreign keys in MySQL are still useful, but they are no guarantee that the data is consistent. And to compensate, we have to write some scripts to verify our data, one of the things that we hoped to avoid by using foreign keys.</p>
<p>Okay, fair enough, this is probably a bug. At least, I hope it&#8217;s not a feature. But this is core functionality, and a gaping hole like this makes me tremble like a chicken at a KFC.</p>
<h3>Default values</h3>
<pre>mysql&gt; CREATE TABLE a (
    -&gt;   b VARCHAR(10) NOT NULL,
    -&gt;   c VARCHAR(10) NOT NULL,
    -&gt;   d INT NOT NULL
    -&gt; );
mysql&gt; INSERT INTO a (b) VALUES ('b');
mysql&gt; SELECT * FROM a;
+---+---+---+
| b | c | d |
+---+---+---+
| b |   | 0 |
+---+---+---+
1 row in set (0.00 sec)</pre>
<p>Whoops, I forgot to set values for the c and d columns. But how cute, MySQL has filled them in for me. That&#8217;s why it&#8217;s called <strong>My</strong>SQL, because it always looks out for me, aah.</p>
<p>NO! I set them NOT NULL with no default so that I would be forced to enter a value. If I don&#8217;t enter a default, don&#8217;t guess one for me. Tell me I&#8217;m an idiot and get me to think again. Why is there an assumption that the empty string or zero is good for me, now that I&#8217;ve rejected NULL?</p>
<blockquote><p>&#8220;I don&#8217;t want to work for NULL euros an hour!&#8221;</p>
<p>&#8220;Okay, let&#8217;s put you on our ZERO euros an hour rate instead.&#8221;</p></blockquote>
<h2>Roll it all up</h2>
<p>You&#8217;ve probably seen the pattern. Most or all of my problems with MySQL comes from differences between what I expect will happen, and what actually does happen. But I know these quirks now so they won&#8217;t cost me much development time any more, and I&#8217;ve built my ORM to cover the most obvious cracks.</p>
<p>But something still bothers me. The water still isn&#8217;t clear and I&#8217;m afraid there&#8217;s a slimy green monster in the depths. What quirks do I <em>not</em> know? Will they one day bite me on the rear like a three-jawed radioactive toad on an arse biting frenzy?</p>
<p>The default MyISAM engine lacks foreign keys and transactions, but InnoDB feels tacked on, and foreign keys still don&#8217;t work properly. MySQL tries to please everyone by accepting, yet ignoring, things like <code>REFERENCES</code> clauses. When inserting it has a habit of choosing default values for <code>NOT NULL</code> columns instead of telling me I&#8217;ve forgotten to specify a value. In trying to be accommodating it actually ends up surprising and frustrating.</p>
<p>Bizarrely enough, I still like MySQL. In the end it&#8217;s worked well for me. The performance is good, and it is easy to maintain and backup. But I won&#8217;t be using it again. When storing mission-critical data it is vitally important to do the right thing, and MySQL often does <strong>not</strong> do the right thing.</p>
]]></content:encoded>
			<wfw:commentRss>http://gavinpanella.com/blog/2006/10/15/why-i-wont-be-using-mysql-for-my-next-project/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
