<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Ben Poole</title>
<link>http://benpoole.com</link>
<language>en-gb</language>
<description>Ben Poole: last 10 &#8217;blog entries filed under &#8220;Programming&#8221;</description>
<copyright>Copyright 1997 - 2012, Benedict Poole</copyright>
<generator>Domino SimpleFeed from http://foo-soft.com</generator>
<webMaster>site@benpoole.com (Ben Poole)</webMaster>
<atom:link href="http://benpoole.com/bp.nsf/blogs-cat.rss" rel="self" type="application/rss+xml" />
<item><title>HTTP 701 meh</title><pubDate>Sat, 28 Jan 2012 17:09 +0100</pubDate><description><![CDATA<p>Hopefully you are a <a href="https://github.com">github regular</a> and have already seen this README, but just in case not, be sure to check out John Barton’s RFC for some extra HTTP codes. My favourites are 701 and 748.</p>

<p><a href="https://github.com/joho/7XX-rfc#readme">John Barton&#8217;s RFC</a>.</p>]></description><link>http://benpoole.com/weblog/201201281709</link><dc:subject>http, github, fun</dc:subject><dc:creator>Ben Poole</dc:creator><guid isPermaLink="true">http://benpoole.com/weblog/201201281709</guid><comments>http://benpoole.com/weblog/201201281709#comments</comments></item><item><title>More on testable code</title><pubDate>Wed, 25 Jan 2012 19:23 +0100</pubDate><description><![CDATA<p>Following on from <a href="/weblog/201201170736">my previous post</a>, I stumbled across a most excellent resource, Miško Hevery&#8217;s <a href="http://misko.hevery.com/code-reviewers-guide/">Guide: Writing Testable Code</a>. This is detailed, helpful and above all eminently readable&#8212;well worth running off and keeping.</p>

<p>Hevery&#8217;s document contains a number of tips designed to make code more testable, but really it goes wider than that. Hevery picks out four basic flaws, gives examples of each, how to detect them (&#8220;warning signs&#8221; if you will), and of course, how to address them.</p>

<p>The four flaws:</p>

<ol>
<li>&#8220;Constructor does real work&#8221; (don&#8217;t do any more than basic assignment, and certainly don&#8217;t do any static &#8220;initialisation&#8221; method calls)</li>
<li>&#8220;Digging into collaborators&#8221; (avoid a deep chain of wrapper objects)</li>
<li>&#8220;Brittle global state &amp; singletons&#8221; (globally-accessible elements can / will cause havoc when trying to test and debug)</li>
<li>&#8220;Class does too much&#8221; (remember the classic principle of &#8220;single responsibility.&#8221; Also, spaghetti code is blummen&#8217; hard to test)</li>
</ol>

<p>Read more&hellip; <a href="http://misko.hevery.com/code-reviewers-guide/">Guide: Writing Testable Code</a>.</p>]></description><link>http://benpoole.com/weblog/201201251923</link><dc:subject>programming, testing, tips, miško hevery</dc:subject><dc:creator>Ben Poole</dc:creator><guid isPermaLink="true">http://benpoole.com/weblog/201201251923</guid><comments>http://benpoole.com/weblog/201201251923#comments</comments></item><item><title>Making code test-able</title><pubDate>Tue, 17 Jan 2012 07:36 +0100</pubDate><description><![CDATA<p>There are two things a developer needs to make his or her output testable (and therefore more robust. Hopefully):</p>

<ol>
<li>The &#8220;How would I test for xyz&#8221; mind-set, and;
<li>A fast simple development environment</li>
</ol>

<p>That&#8217;s it, that&#8217;s all you need. The first comes with practise, and the second is pretty straightforward nowadays. Of late I have been writing a lot of PHP in <a href="http://eclipse.org">Eclipse</a>, <a href="http://panic.com/coda/">Coda</a> and the new kid on the block, <a href="http://www.sublimetext.com/2">Sublime Text 2</a> (check it out: very nice). All of these tools make it easy to write test-able code, because one simply pulls in the unit testing framework of choice, and then one writes code: job done, very low barrier to entry.</p>

<p>As a small aside, I am constantly amazed at how much PHP stuff goes out the door with minimal-to-no tests, especially when one considers the fluid nature of the language (its typing and such). This contrasts sharply with the mind-set we see amongst Rubyists, who regard their language&#8217;s dynamism as <i>raison d&#8217;être</i> for excellent test coverage.</p>

<p>So a diligent approach to testing is one thing, but contrast my comments about editors above with other recent experiences writing Java in an Eclipse-based editor called Domino Designer (some of you may be familiar with it). Making <em>that</em> code test-able has been more problematic, given DDE&#8217;s reluctance to play nice with plug-ins like <a href="http://junit.org">JUnit</a>, and the way a typical Java agent is structured. So, a couple of tips:</p>

<ol>
<li>Abstraction is key: write as much of your Java code as you can abstracted away from the Domino object model. This way you can code in a proper Eclipse instance, and you can write easy test cases. Break up big problems into small solvable components, and test them. Your Java agents should be very &#8220;light&#8221;&#8212;minimal code perhaps just looping a collection or whatever. Let your custom, tested classes do the heavy lifting.</li>
<li>If you&#8217;re like me, and not at Lotusphere, you will be missing out on a session from Messrs. <a href="http://www.stickfight.co.uk">Myers</a> and <a href="http://www.nsftools.com">Robichaux</a> covering effective Java in the Domino environment. As soon as their presentation is made available, I have it on good authority that you will want it, and that the Wookiee has some tricks up his sleeve when it comes to JUnit <span class="smiley smile">:-)</span>.</li>

<p>(Finals words of &#8220;wisdom&#8221;: it is a lot quicker, and simpler, to write test-able code up-front. Adding tests after the fact is always more burdensome).</p>]></description><link>http://benpoole.com/weblog/201201170736</link><dc:subject>testing, programming</dc:subject><dc:creator>Ben Poole</dc:creator><guid isPermaLink="true">http://benpoole.com/weblog/201201170736</guid><comments>http://benpoole.com/weblog/201201170736#comments</comments></item><item><title>Resolutions for coders</title><pubDate>Thu, 5 Jan 2012 18:45 +0100</pubDate><description><![CDATA<p><a href="http://benpoole.com/bp.nsf/weblog/201201042230" title="Link to my post &#8220;Code Year and Site Design&#8221;">Yesterday</a> I posted about <a href="http://codeyear.com">Code Year</a>, an initiative to get people learning the gentle (chortle) art of programming. But what of the seasoned professional, the much-maligned code monkey, the long-suffering developer?</p>

<p>Well, <a href="http://matt.might.net">Matt Might</a> has a splendid list of twelve resolutions for the rest of us:</p>

<p>Matt Might, <a href="http://matt.might.net/articles/programmers-resolutions/">12 Resolutions for Programmers</a>.</p>]></description><link>http://benpoole.com/weblog/201201051845</link><dc:subject>programming, matt might, resolutions</dc:subject><dc:creator>Ben Poole</dc:creator><guid isPermaLink="true">http://benpoole.com/weblog/201201051845</guid><comments>http://benpoole.com/weblog/201201051845#comments</comments></item><item><title>Codeyear and site design</title><pubDate>Wed, 4 Jan 2012 22:30 +0100</pubDate><description><![CDATA<p>After checking out the <a href="http://codeyear.com">Code Year</a> site recently launched by <a href="http://www.codecademy.com">Codecademy</a>, I moved on to read an interesting post from that site&#8217;s designer, Sacha Greif: <a href="http://sachagreif.com/how-i-designed-codeyear-com-in-1-hour/">How I Designed CodeYear.com in 1 Hour</a>. Definitely check this post out: Sacha deftly guides the reader through the over-arching thought processes behind an effective site re-design. There are some handy tips and links along the way for any budding designers, or coders like you and I who simply want to to create more pleasant web experiences.</p>

<p>As for Code Year, what a great initiative!</p>

<blockquote cite="http://www.rushkoff.com/blog/2010/3/25/program-or-be-programmed.html">If you are not a programmer, you are one of the programmed. It&#8217;s that simple.</blockquote>

<p><a href="http://www.rushkoff.com/blog/2010/3/25/program-or-be-programmed.html" title="Link to Douglas Rushkoff, &#8220;Program or Be Programmed&#8221;">Douglas Rushkoff</a> says it best.</p>]></description><link>http://benpoole.com/weblog/201201042230</link><dc:subject>codeyear, douglas rushkoff, programming, codecademy</dc:subject><dc:creator>Ben Poole</dc:creator><guid isPermaLink="true">http://benpoole.com/weblog/201201042230</guid><comments>http://benpoole.com/weblog/201201042230#comments</comments></item><item><title>Friday posers…</title><pubDate>Fri, 9 Sep 2011 16:41 +0100</pubDate><description><![CDATA<p>Recent projects have meant lots and lots of Javascript. Other work has led to a need to really <em>study</em> the language, and look into more than the odd <a href="http://jquery.com">jQuery</a> plugin and wot-not. This has been a rewarding experience: challenging received wisdom, ensuring that I know more about all those concepts that spend years just floating out there on the edge of one&#8217;s understanding.</p>

<p>To that end, here are a few interesting tid-bits which I have found&#8212;typically whilst researching more involved stuff like prototypical inheritance and closures <span class="smiley smile">:-)</span>. It&#8217;s amazing how much we <em>think</em> we know&hellip;</p>

<p>A couple of the more involved posers have specimen answers attached; the others are too easy for me to do that! It&#8217;s all interesting though:</p>

<pre class="prettyprint">// What do these two alerts produce, and why?
alert('1' + 3);
alert('3' - 1);

// If expressed as tests, what do each of these return?
"1" == 1;
"1" === 1;
"1" == true;
"1" === false;

// What do these calls produce?
parseInt("05");
parseInt("010");
parseInt("09");

// What are the five main data types in Javascript?

// How would you create a class in Javascript, with a private method?
function MyClass()
{
    function somePrivateMethod() {
        console.log("this is a private method");
    }
}

//… how would you add a public method to this class?
MyClass.prototype = {
    somePublicMethod: function() {
        console.log("This is a public function, whoop!");
    }
}</pre>]></description><link>http://benpoole.com/weblog/201109091641</link><dc:subject>javascript, programming, fun, tips</dc:subject><dc:creator>Ben Poole</dc:creator><guid isPermaLink="true">http://benpoole.com/weblog/201109091641</guid><comments>http://benpoole.com/weblog/201109091641#comments</comments></item><item><title>HTML5 field types (in brief)</title><pubDate>Thu, 18 Aug 2011 11:44 +0100</pubDate><description><![CDATA<p>If you&#8217;ve been following some of my recent posts on off-line apps, Web SQL and all that, you will have seen that all my mark-up snippets were in HTML5. And no doubt you have seen a lot of the brou-ha-ha around HTML5 too, and probably know that introduces some more field types and attributes.</p><p>Rather than go into a whole exposition of HTML5 (which <a href="http://diveintohtml5.org" title="Link to Mark Pilgrim&#8216;s excellent &#8220;Dive Into HTML5&#8221;">others have already done brilliantly</a>) I want to take a moment at some real-life applications of some of this HTML5 lark. I&#8217;ve already talked about off-line web apps and using local storage options (in the form of Web SQL), so let&#8217;s take a brief look at fields. I&#8217;ve coded a few production sites and applications so far that take advantage of the new types offered in HTML5 (specifically email, number, range and date fields), and having these expanded options in one&#8217;s arsenal is not to be sniffed-at. What I especially like in HTML5 is the in-built support for the new &#8220;placeholder&#8221; attribute. No more do we have label and Javascript <code>onfocus()</code> hacks (at least, not in some browsers). Instead, this wee bit of mark-up does everything we need, with the placeholder text disappearing and re-appearing as the field contents are changed (you will have seen this in <a href="http://benpoole.com/bp.nsf/weblog/201106302211" title="More local Web SQL">my previous demo</a>):</p><pre class="prettyprint">&lt;label for="winklename"&gt;Your winkle&#8217;s name&lt;/label&gt;
&lt;input name="winklename" id="winklename" placeholder="Winkle's full name, e.g. 'Pansy Trueshell'"/&gt;</pre><p><img class="feature-image" src="http://benpoole.com/bp.nsf/files/html5fields/$file/placeholder.png" width="429" height="65" alt="Screenshot of placeholder feld mark-up in action" /></p><p>Isn&#8217;t that smashing ladies and gentlemen? Of course, it&#8217;s not (yet) all roses in the HTML5 garden: some browsers simply don&#8217;t support every bit of this emerging standard. A fine idea is to make use of something like <a href="http://www.modernizr.com">Modernizr</a> for feature detection, but if placeholder support is a feature you need to test for explicitly, something like this should help:</p>
<pre class="prettyprint">function placeholderSupport(){
  return 'placeholder' in document.createElement('input');
}</pre><p>(This function returns <samp>true</samp> for sensible browsers like Safari, Chrome and Firefox, and <samp>false</samp>, predictably, for things like IE8). Now, what I <em>really</em> like is that by introducing new data types for fields, HTML5 also allows the easy manipulation of said fields in the app framework of your choice. So, if I want a whizzy date-picker for my date fields, or a lovely slider for my range fields, it all becomes a hell of a lot easier to apply with a decent framework. For example, here&#8217;s an HTML5 date field which is rendered using the <a href="http://dev.jtsage.com/jQM-DateBox/">DateBox</a> plugin alongside <a href="http://jquerymobile.com">jQuery Mobile</a>:</p>
<p><img class="feature-image" src="http://benpoole.com/bp.nsf/files/html5fields/$file/datebox.png" alt="Screenshot of datebox plugin on a date field" height="428" width="526" /></p><p>A corollary of these new field types is that many mobile devices support them. So, for example, if I want my mobile device&#8217;s keyboard to show an @ sign when filling in an email field, I just need to ensure the field type is set appropriately&#8212;iOS / Android / You Name It will do the rest for me. You&#8217;ve probably seen this in action yourself. So, make sure your apps play nice&#8212;mobile is crucial!</p>]></description><link>http://benpoole.com/weblog/201108181144</link><dc:subject>html5, web design, mobile, html, tips</dc:subject><dc:creator>Ben Poole</dc:creator><guid isPermaLink="true">http://benpoole.com/weblog/201108181144</guid><comments>http://benpoole.com/weblog/201108181144#comments</comments></item><item><title>More local Web SQL</title><pubDate>Thu, 30 Jun 2011 22:11 +0100</pubDate><description><![CDATA<p><a href="http://benpoole.com/bp.nsf/weblog/201106222227" title="Off-line web apps: local Web SQL &amp; Javascript">In my last post on this topic</a>, we looked at how one might use Web SQL in a local web application, and I supplied some code which initialised a local database and pulled data from its lone table. All well and good, but what about the realities of using this data? Specifically, let us look at how one re-loads, edits and saves the data.</p><p>&#8220;Eh?&#8221; I hear you ask. &#8220;Surely you just load up data in the normal way, and then, um, well put it somewhere&hellip;&#8221; <i>(reader tails off quietly, and there is a momentary embarrassed silence).</i> Yes, in my last post the provided code shows how to do a basic save and bulk load from the fabled <samp>winkles</samp> table, I grant you, but that in and of itself isn&#8217;t that much use. Sure, you can iterate query results and present them in a page, but what about <strong>editing</strong> said data? This is where the fun starts. You&#8217;re running a local web app remember: no web server, no box to which you may post forms for processing! But that won&#8217;t stop us, dear me no! I will show you how you can save a form within a web page to your database table, and then how you can load that data back into the same web page for editing and more saving. No server tricks! Splendid.</p><p>First up, grab a shiny new Javascript source file from a new gist I created here: <a href="http://gist.github.com/1057251">Web SQL javascript</a> (it&#8217;s the JS we used <a href="http://benpoole.com/bp.nsf/weblog/201106222227" title="Off-line web apps: local Web SQL &amp; Javascript">in my previous post</a>, broken out into its own source file, with some added goodies). The gist tells you what to call the file. Then, in the same directory, create a new HTML page and whack the following mark-up into it. It&#8217;s a simple HTML5 page, with a wee bit of Javascript injection, a tiny form, and that&#8217;s about it (<strong>note</strong>: as with my other examples, this page requires <a href="http://jquery.com">jQuery</a> in addition to the supplied Javascript).</p><pre class="prettyprint">&lt;!DOCTYPE HTML&gt;
&lt;html&gt;
 &lt;head&gt;
  &lt;meta charset="UTF-8" /&gt;
  &lt;title&gt;Winkles! Form a line!&lt;/title&gt;
 
  &lt;style type="text/css"&gt;
   body {font-family: Helvetica, sans-serif; font-size: 100%; line-height: 1.4em}
   input, button {width: 25em; font-size: 100%; padding: .25em}
   label {display: block; margin-top: 1em}
  &lt;/style&gt;
 
  &lt;script type="text/javascript" src="jquery.js"&gt;&lt;/script&gt;
  &lt;script type="text/javascript" src="winkling.js"&gt;&lt;/script&gt;
  
  &lt;script type="text/javascript"&gt;
  $(function(){
   var form = $("#winkle-form");
   form.submit(function(event){
    event.preventDefault();
    var values = form.serializeJSON();
    saveWinkle(values, function(){
     alert($('#winklename').val() + "'s data has been saved, thanks.");
     location.reload(true);
    })
   });

   loadWinkles("", updatePageWithLinks);
   $('#clear-btn').click(function(){resetWinkle();});
  });
  &lt;/script&gt;
 &lt;/head&gt;

 &lt;body&gt;
  &lt;h1&gt;Winkles! Form a line!&lt;/h1&gt;
  &lt;p&gt;Here&#8217;s where you enter some winkle-related data. And it gets saved. And you can load stuff too.&lt;/p&gt;
  
  &lt;form id="winkle-form" action="" method="POST"&gt;
   &lt;label for="winklename"&gt;Your winkle&#8217;s name&lt;/label&gt;
   &lt;input name="winklename" id="winklename" placeholder="Winkle's full name, e.g. 'Pansy Trueshell'"/&gt;
   &lt;label for="location"&gt;Your winkle&#8217;s location&lt;/label&gt;
   &lt;input name="location" id="location" placeholder="Type in a location here, e.g. 'Ayrshire'" /&gt;
   &lt;input type="hidden" name="id" id="id" /&gt;
   &lt;p&gt;&lt;input type="submit" value="Save Winkle" /&gt;&lt;input type="button" id="clear-btn" value="Clear form" /&gt;&lt;/p&gt;
  &lt;/form&gt;
  
  &lt;h2&gt;Previously-saved winkles&lt;/h2&gt;
  &lt;p&gt;Tap or click on a link below to load that winkle&#8217;s data into the form above:&lt;/p&gt;
  &lt;ul id="winkle-list"&gt;&lt;/ul&gt;
 &lt;/body&gt;
&lt;/html&gt;</pre><p>All done. Now for some testing in your browser! As with my previous local SQL example, there are a couple of gotchas to bear in mind when previewing this stuff locally:</p><ol><li>Don&#8217;t preview with the <code>file://</code> protocol, you will hit strange security exceptions in your browser. Use a proper web server, something that can serve up as <code>http://</code>. (I use OS X, so I preview in the bundled local Apache 2 installation, which is handy).</li><li>I have only tested this code in Chrome and Safari. It <em>should</em> work in Opera, but I make no warranties for it working anywhere (and it most certainly will <strong>not</strong> run in Internet Explorer <span class="smiley wink">;-)</span>).</li><li>There&#8217;s no validation: it is entirely possible for you to save empty winkle data (shocker).</li></ol><p>Let&#8217;s look at the code in this web page. First, we override the form&#8217;s default <code>onSubmit</code> action so that it doesn&#8217;t actually try to <code>POST</code> anywhere, it just triggers <code>saveWinkle()</code>, a function which grabs all the data in the form (yes, all two fields of it. Well, OK, all <em>three</em> fields, what with the hidden one), saves it to the <samp>winkles</samp> table, and then kicks off a callback function (a grand term for a simple <code>alert</code> call, I think you will agree). Easy-peasy.</p><p>Where things get a little more interesting is with the other bits of Javascript you see triggered when the page is ready. The first function, <code>loadWinkles()</code> comprises some Web SQL Javascript which <code>SELECT</code>s every winkle in the table, and then passes the <code>SQLResultSet</code> over to a callback, <code>updatePageWithLinks</code>. That function iterates the resultset, and writes the data out to the bottom of the web page (the <code>winkle-list</code> unordered list to be precise). Now, this code is all familiar from my previous post. Where things diverge is in what that function writes out: it&#8217;s not plain text as before, it&#8217;s a list of <em>links</em>.</p><p>(Oh yes, I also add a <code>click</code> event to a form reset button, but that&#8217;s not very interesting, so I shan&#8217;t talk about it).</p><p>If you take a look at <code>updatePageWithLinks</code> in the Javascript source provided, you will see that the links are written out to the page with reference to a new function, <code>loadMe</code>. This takes a single parameter, which is the relevant winkle&#8217;s database record &#8220;id&#8221;, so that <code>loadMe</code> knows which winkle&#8217;s details to load up.</p><p><code>loadMe</code>, surprise surprise, is callback-mungous, like a lot of the other code here. First, it triggers a routine to perform the <code>SELECT</code> and pull back the relevant record. Then this SQL result is passed over to a small function called <code>loadFormWithData</code>&hellip; and you can guess what that does.</p><p>There you have it. Loading and saving data to and from a web page, no server required. Now, I grant you, this form injection stuff all seems a bit fiddly. Why not use querystring parameters and the like to pass round the record ID required? Well, that&#8217;s where you hit one of the limitations of local web applications: as soon as you start involving things like href hashes, or querystrings, your web client will assume a server is involved. And if you&#8217;re running off-line (remember how <a href="http://benpoole.com/bp.nsf/weblog/201106151740" title="Offline web apps: the cache (serious this time)">this series of posts started!</a>), that&#8217;s a no-no, and your browser will forget all about appcaches and the like, and will attempt to contact the (potentially unreachable) server. Doh!</p>]></description><link>http://benpoole.com/weblog/201106302211</link><dc:subject>websql, html5, javascript</dc:subject><dc:creator>Ben Poole</dc:creator><guid isPermaLink="true">http://benpoole.com/weblog/201106302211</guid><comments>http://benpoole.com/weblog/201106302211#comments</comments></item><item><title>Off-line web apps: local Web SQL &amp; Javascript</title><pubDate>Wed, 22 Jun 2011 22:27:24 +0100</pubDate><description><![CDATA<p>So, you know how to take our site off-line: events are triggered, caches are swapped, and even though you still have that (apparent) server-based <abbr title="Uniform Resource Locator">URL</abbr> going on in your address bar, you are off-line! Yes! Stick your device in airplane mode and revel in how your website is still doing its thing. Clever.</p>

<p>However, your world is incomplete. You have some pages going on, some links between them, stylesheets&#8212;maybe some whacked-out Javascript doing wondrous things&#8212;but something is still <em>missing</em>. And that something is <em>persistence</em>, a proper local data store that goes beyond the capabilities of the humble, fragile wee cookie.</p>

<p>Until the newer browser technology started to become mainstream (arguably aided by the early efforts of things like <a href="http://gears.google.com">Google Gears</a>), this was a big sticking point for off-line sites and apps, because there was nowhere to store one&#8217;s data. Now though? Sea-change, oh yes. Depending on your browser of choice, you have two options: 1) an embedded local relational database (the generic &#8220;Web SQL&#8221; standard, that in practice actually means <a href="http://www.sqlite.org/">SQLite</a>) or <a href="http://www.w3.org/TR/webstorage/" title="W3C Working Draft for &#8220;Web Storage&#8220;">Web Storage</a>, which is a simple key-value store.</p>

<p>IndexedDB is one for another day. For now, we&#8217;re thinking about a local instance of SQLite with a Javascript framework to access it, which can be found in all up-to-date <a href="http://en.wikipedia.org/wiki/WebKit#Ports" title="Link to Wikipedia page on WebKit, and its ports">WebKit-based browsers</a>, and also in Opera. &#8220;Web SQL&#8221; works well, and is surprisingly well-featured, but we hit the main hiccup with its uptake when we consider the supporting web clients: Chrome and Safari (including mobile variants thereof) are golden of course. Opera is popular, and includes a mobile instance too&#8212;again, good&#8212;but Firefox and Internet Explorer are out in the cold, with no Web SQL support (in fairness to Mozilla, Firefox instead supports <a href="http://developer.mozilla.org/en/IndexedDB">IndexedDB</a> which appears to be the preferred local data store going forward anyway&#8212;see &#8220;Further reading&#8221; section). Only you can decide whether this is an issue, but seeing as I&#8217;m been coming from the mobile web dev. angle, I&#8217;m OK with it <span class="smiley smile">:-)</span></p>

<h4>On to the code</h4>
<p>The Javascript <abbr title="Application Programming Interface">API</abbr> that overlays all this SQLite goodness is pretty simple to use. It is callback-mungous though, so if you&#8217;re not used to coding your JS that way, you soon will be. Here is a snippet of Javascript which opens a database for logging <a href="http://en.wikipedia.org/wiki/Common_periwinkle" title="Link to the Wikipedia page on periwinkles, if you really must know more">periwinkles</a>. The code creates the main table (if it doesn&#8217;t already exist), which is a simple three column affair: a generated id, plus two text values for a given winkle&#8217;s name and location:</p>

<pre class="prettyprint">/* Open &amp; initialise our database. Note the required parameters, 
   which comprise a short name, a version, a display name 
   &amp; expected maximum size (in bytes)
*/
var db = openDatabase("winkles", "1.0", "Winkles Of The World", 32678);

/* Create the winkles table (if it doesn't already exist), with 
   an automatic id key, plus two columns for name &amp; location
*/
db.transaction(function(transaction){
  transaction.executeSql("CREATE TABLE IF NOT EXISTS winkles (" +
    "id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT," + 
      "winklename TEXT NOT NULL, location TEXT NOT NULL);");
});
</pre>

<p>So the database and table exist (and will still be there when you close your browser session of course), and now we want to do stuff with the table. Assuming we&#8217;ve magically generated some winkle data, let&#8217;s say I now want to see the names of all winkles found in Ayrshire. Here&#8217;s how it&#8217;s done:</p>

<pre class="prettyprint">var showWinkles = function(location, successCallback){
  db.transaction(function(transaction){
    transaction.executeSql(("SELECT * FROM winkles WHERE location=?"), [location],
      function(transaction, results){successCallback(results);}, errCallback);
    });
  };</pre>

<p>A few things to note here: the SQL statement is wrapped in a <code>transaction</code> instance, which is asynchronous. As such, the call to <code>showWinkles</code> is expected to pass over two things. One is the location  we want data for (&#8220;Ayrshire&#8221;), and the other is a callback (<code>successCallback</code>). This should be a function that the SQL results get passed to for onward processing. Finally, you can see reference to some random thing called <code>errCallback</code>. This is optional, but recommended, and in this instance it&#8217;s a reference to an <strong>error state</strong> callback function. You can define this in your main Javascript code, something along these lines perhaps:</p>

<pre class="prettyprint">// Generic error callback
var errCallback = function(){
  alert("Oh noes! There haz bin a datamabase error!");
}</pre>

<p>Well you get the idea.</p>

<h4>Is this thing on?</h4>
<p>A quick aside: let&#8217;s fire up the Web Inspector found in all WebKit browsers, and see just what we&#8217;ve got there:</p>

<p><img src="http://benpoole.com/bp.nsf/files/web-inspector/$file/web-inspector.png" width="629" height="465" class="feature-image" alt="Screenshot of Safari Web Inspector showing our winkles database" /></p>

<p>Not bad eh? There&#8217;s our database, our <samp>winkles</samp> table, and some data, right there. In fact, the Web Inspector window is quite powerful: highlight the databases icon, and the pane to the right becomes a console into which you can type SQL directly&#8212;perform updates, queries, drops, anything you want (you even get some auto-complete on your SQL).</p>

<h4>Success</h4>
<p>Back to the code. Let&#8217;s look at a typical &#8220;success&#8221; callback in more depth. How might one usefully call <code>showWinkles</code> within a web page? How about a button (with the id <code>show-me</code>), that when clicked, retrieves all the winkle data for a given area and presents it in a list? Anyone familiar with the &#8220;subversive injections&#8221; presentation I did with <a href="http://www.stickfight.co.uk">the Wookiee</a> at <a href="http://uklug.londondevelopercoop.com" title="Link to our presentation site for UKLUG 2009 in Edinburgh">UKLUG 2009</a> will know I like to inject code into web pages willy-nilly (dirty devil). So, when your document&#8217;s ready, bind some code to our button like so (note: all the following snippets use jQuery for brevity, selectors, and a couple of other things):</p>

<pre class="prettyprint">$('#show-me').click(function(){showWinkles('Ayrshire', updatePage);});</pre>

<p>Now, let&#8217;s write the routine mentioned above as the callback we pass to <code>showWinkles</code>&#8212;we&#8217;re calling it <code>updatePage</code>. This function needs to get a handle on our <abbr title="HyperText Markup Language">HTML</abbr> list (to which I have granted the imaginative epithet <code>winkle-list</code>), iterate our <code>SQLResultSet</code>, and write out a list item for each row in said results (or not, if there&#8217;s no data). Again, I&#8217;m using jQuery here, both for selectors and for <code>$.each</code> (which I like very much):</p>

<pre class="prettyprint">var updatePage = function(results){
  var winkles = $("#winkle-list");
  winkles.empty();  // Clear down before re-creating
  if (results.rows.length==0){
    // Nothing in the table
    alert("Alas, there be no winkles here.");
  } else {
    // Iterate the SQLResultSet
    $.each(results.rows, function(i){
      var row = results.rows.item(i);
      // Write out a list item for each row
      winkles.append("&lt;li&gt;" + row.winklename + " who resides in " + 
        row.location + "&lt;/li&gt;");
    });
  }
};</pre>

<p>All done! So there, in a nutshell, is how to query data in a SQLite database running in your WebKit browser. Now, the more astute amongst you will have noted that this isn&#8217;t the whole story&#8212;I&#8217;ve not listed any code to <em>save</em> my winkles for a start, nor is the mark-up I&#8217;m tinkering with detailed. Do not fear, the complete source code for this post (a single HTML page with all the required Javascript) is available on GitHub, in a thing called a &#8220;gist&#8221;:</p>

<p><a href="https://gist.github.com/1041277">gist - Javascript &amp; Web SQL example</a></p>

<p>Now, this code is a simple introduction to Javascript and SQLite in a local web page. It is not production-ready for a number of reasons, not least that it&#8217;s all just straight Javascript function calls and wot-not. Any developer worth his or her salt would rip this apart and create a nice <abbr title="Data Access Object">DAO</abbr> which can then be used as a &#8220;service class&#8221; of sorts, tucking away all those nasty brackets and SQL statements (in fact, that&#8217;s just what I did for a client project recently <span class="smiley wink">;-)</span>), so there&#8217;s some homework for you right there!</p>]></description><link>http://benpoole.com/weblog/201106222227</link><dc:subject>html5, javascript, websql</dc:subject><dc:creator>Ben Poole</dc:creator><guid isPermaLink="true">http://benpoole.com/weblog/201106222227</guid><comments>http://benpoole.com/weblog/201106222227#comments</comments></item><item><title>The old “native vs. web” chestnut</title><pubDate>Thu, 16 Jun 2011 10:24:38 +0100</pubDate><description><![CDATA<p>What ho! Just over a week ago I picked up on this opinion piece from Hutch Carpenter, in which there is much discussion about mobile apps&#8212;specifically why enterprises should look at the <strong>mobile web</strong> route, rather than native applications. Carpenter makes a number of points supporting his case, and I can&#8217;t say I disagree. <em>Of course</em> there are scenarios when a native app is the only way to go, but for a lot of this stuff the web is spot-on (and the web can still have a part to play in native apps&#8212;think cross-compilers such as those in <a href="http://www.appcelerator.com">Appcelerator</a> and <a href="http://phonegap.com">PhoneGap</a>). Anyway, here is one of Carpenter&#8217;s clinchers:</p>

<blockquote cite="http://bhc3.wordpress.com/2011/06/06/four-reasons-enterprise-software-should-skip-native-mobile-apps/">Indeed, designing for a mobile experience is actually a great exercise for enterprise software vendors. It puts the focus on simplicity and the most commonly used functions. It&#8217;s also a chance to re-imagine the <abbr title="User eXperience">UX</abbr> of the software. It wouldn&#8217;t surprise me if elements the mobile optimized HTML <i>[a strange sentence, but I&#8217;m sure you get his point - BP]</i> find their way back to the main web experience.</blockquote>

<p>Hutch Carpenter: <a href="http://bhc3.wordpress.com/2011/06/06/four-reasons-enterprise-software-should-skip-native-mobile-apps/">Four reasons enterprise software should skip native mobile apps</a>.</p>

<p>There&#8217;s a parallel here; look at where Apple are going with iOS, OSX (and the respective app stores) with noticeable feature and paradigm exchanges between the Mac and its iBrethren. The interplay between iOS and OSX has come to the point that the forthcoming release of the Mac&#8217;s operating system (&#8220;Lion&#8221;) will include a number of innovations originally seen in iOS. It&#8217;s clear that this is happening in the mobile space too. Constraints in screen real estate, functionality and memory have all led to some real innovation. The provision of decent mobile browsers (mainly courtesy of WebKit) now means that we have some amazing frameworks for all major devices. And what technologies do some of these frameworks base themselves on? Why, good old HTML and Javascript! Look at the aforementioned Appcelerator and PhoneGap, or the web frameworks <a href="http://jquerymobile.com">jQuery Mobile</a> and <a href="http://www.sencha.com">Sencha</a> if you don&#8217;t believe me (heck, look at the <a href="http://www.youtube.com/watch?v=p92QfWOw88I" title="Link to Microsoft video, &#8220;Building 'Windows 8' - Video #1&#8221;">demonstration of Windows 8</a> that&#8217;s out there).</p>

<p>So developers, if you&#8217;re looking for some new stuff to learn, by all means roll with Ruby, partake of some Python, simper with Scala&hellip; but don&#8217;t neglect trusty mark-up and its pal Javascript&#8212;in case it&#8217;s not become clear yet, you will need your web skills more and more.</p>

<p class="footnote"><strong>Shameless plug:</strong> if you need some mobile web development for your organisation, get in touch. We fellows at the <a href="http://londondevelopercoop.com">London Developer Co-op</a> are doing more and more in this space).</p>]></description><link>http://benpoole.com/weblog/201106161024</link><dc:subject>mobile, frameworks, mobile+web</dc:subject><dc:creator>Ben Poole</dc:creator><guid isPermaLink="true">http://benpoole.com/weblog/201106161024</guid><comments>http://benpoole.com/weblog/201106161024#comments</comments></item>	</channel>
</rss>

