<?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/"
	xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule"
>

<channel>
	<title>A mind less ordinary &#187; Coding</title>
	<atom:link href="http://www.dmi.me.uk/blog/tag/coding/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.dmi.me.uk/blog</link>
	<description></description>
	<lastBuildDate>Wed, 23 Nov 2011 16:01:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/3.0/</creativeCommons:license>
		<item>
		<title>A content-based file manager</title>
		<link>http://www.dmi.me.uk/blog/2009/06/04/a-content-based-file-manager/</link>
		<comments>http://www.dmi.me.uk/blog/2009/06/04/a-content-based-file-manager/#comments</comments>
		<pubDate>Thu, 04 Jun 2009 22:12:38 +0000</pubDate>
		<dc:creator>Dave</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Insight (semantic filesystem)]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[Braindump]]></category>
		<category><![CDATA[file manager]]></category>
		<category><![CDATA[ideas]]></category>

		<guid isPermaLink="false">http://www.dmi.me.uk/blog/?p=124</guid>
		<description><![CDATA[I've been thinking recently about Insight again, and I've been considering part of the problem with naming and uniqueness. Names in a traditional file system are made unique based on a full path to the file, but most people think of a file name as just the final component. This would then cause a problem [...]]]></description>
			<content:encoded><![CDATA[<p>I've been thinking recently about Insight again, and I've been considering part of the problem with naming and uniqueness.</p>
<p>Names in a traditional file system are made unique based on a full path to the file, but most people think of a file name as just the final component. This would then cause a problem with the move to Insight, as a file could appear in multiple directories, and its only distinguishing feature would be the final component of its path. This is counter-intuitive and can cause all sorts of problems.</p>
<p>Consider makefiles, for example. They rely on a standard named file (<tt>Makefile</tt>) appearing at various levels in the hierarchy in order to work. Obviously, you would want different makefiles at different levels and in different projects, but Insight as it stands has no way to handle this.</p>
<p>I then started thinking about what makes a file unique. In the end, I came up with two things: name and content. This covers the makefile case (same name, different content) as well as the backup case (same content, different name). It then occurred to me that, in the general case, all you need to distinguish a file is its content, and then actually finding it can all be left up to metadata.</p>
<p><span id="more-124"></span>If files are then thought of as containers for data that happen to have a unique internal identifier (which never needs to be exposed to the user, although it can be accessed as, say, the file's inode number) then the idea of a content-based file manager comes into play. These examples work best with visual media, particularly images, but there is no reason in principle that this could not be extended.</p>
<p>Imagine searching for a file. You know it's a photo, but you have a large collection of them. With a digital camera and a large-capacity memory card, who needs to ever delete a photo? We'll assume that you've dilligently tagged the photos with metadata as you've imported them from the camera, through some easy batch process.</p>
<p>On the tagging point: a lot can be taken from the metadata stored by the camera (date/time, resolution, orientation, black and white/colour, perhaps GPS co-ordinates) and with the right tools, more can be inferred (auto-tagging faces, buildings, perhaps recognising common events like football matches, converting GPS co-ordinates to places, ...). As time goes on, people will need to do less and less manual tagging.</p>
<p>Anyway, back to the file manager. You know you are after a picture or a set of pictures. Normal thought processes will probably follow a path similar to: "Yeah, I wanted to show dad those <strong>photos</strong> from that <strong>holiday</strong> in <strong>Paris</strong> that we had <strong>two months ago</strong>. I think he'd particularly like the ones we got of the <strong>Louvre</strong>, as well as the ones <strong>with me in</strong>, of course." I've highlighted various key words that can be translated directly to metadata searches. Notice how these all involve a narrowing down of the query.</p>
<p>To convert these to filters, we then have:</p>
<ul>
<li>type: <strong>photo</strong></li>
<li><strong>holiday</strong></li>
<li>location: <strong>Paris</strong></li>
<li>date: <strong>two months ago</strong></li>
<li>at least one of:
<ul>
<li>location: <strong>Louvre</strong></li>
<li>person: <strong>Me</strong></li>
</ul>
</li>
</ul>
<p>This could also be represented by a query:</p>
<blockquote>
<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">type:photo AND holiday AND location:Paris AND date:-2m<br />
AND (location:Louvre OR person:me)</div></div>
</blockquote>
<p>Breaking it down in this way feels fairly technical and wordy, however. I'd much prefer a visual view.</p>
<p>Imagine a black field, speckled with points of light representing your photos:</p>
<p><img class="aligncenter size-full wp-image-131" title="Content File Manager 1" src="http://www.dmi.me.uk/blog/wp-content/uploads/2009/06/content-file-manager-1.png" alt="Content File Manager 1" width="450" height="340" /></p>
<p>You filter by "holiday", and (because it learns based on previous searches) it then groups by location. The ones which have been filtered out fade into nothing, and the photos group into labelled blobs and enlarge slightly:</p>
<p><img class="aligncenter size-full wp-image-132" title="Content File Manager 2" src="http://www.dmi.me.uk/blog/wp-content/uploads/2009/06/content-file-manager-2.png" alt="Content File Manager 2" width="450" height="340" /></p>
<p>You filter by date, and as you drag the slider, irrelevant items fade away and relevant ones enlarge:</p>
<p><img class="aligncenter size-full wp-image-133" title="Content File Manager 3" src="http://www.dmi.me.uk/blog/wp-content/uploads/2009/06/content-file-manager-3.png" alt="Content File Manager 3" width="450" height="340" /></p>
<p>Then you add the final filters and set the photos up for viewing, perhaps as a slideshow... and you're done!</p>
<p>Pretty neat, I think.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dmi.me.uk/blog/2009/06/04/a-content-based-file-manager/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>Modules for Apache and PHP</title>
		<link>http://www.dmi.me.uk/blog/2008/08/13/modules-for-apache-and-php/</link>
		<comments>http://www.dmi.me.uk/blog/2008/08/13/modules-for-apache-and-php/#comments</comments>
		<pubDate>Wed, 13 Aug 2008 20:26:54 +0000</pubDate>
		<dc:creator>Dave</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[extensions]]></category>
		<category><![CDATA[modules]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://www.dmi.me.uk/blog/?p=74</guid>
		<description><![CDATA[The number of projects I have in mind just keeps growing... I really need to get something together to organise them, and remember them! But here are two more to add to the list: an Apache module for dynamic configuration generation and a PHP framework inside an extension. Read on for a monster post with [...]]]></description>
			<content:encoded><![CDATA[<p>The number of projects I have in mind just keeps growing... I really need to get something together to organise them, and remember them! But here are two more to add to the list: an Apache module for dynamic configuration generation and a PHP framework inside an extension. Read on for a monster post with more information...</p>
<p><span id="more-74"></span></p>
<h2>Apache module</h2>
<p>The first thing I have in mind is to create an Apache 2.2 module that uses the APR (Apache Portable Runtime) to make configuration file templating easy.</p>
<p>On my server, there are a lot of very similar Apache configuration files. At the moment, they are semi-automatically generated by running a Perl script that reads the configuration from a database and then creates the output files as required. This is all well and good, but changing anything requires running the Perl script, regenerating all of the configuration files, then prodding Apache to reload its configuration. There has to be a better way, especially one that doesn't require elevated permissions like that.</p>
<p>Enter my proposed solution: <tt>mod_sqltemplate</tt>. This module will add a few extra settings and (at least) two extra sections to the standard Apache configuration. The propsed features are:</p>
<ul>
<li><tt>SQLTemplate_DBDriver «driver»</tt> – sets the APR driver to be used</li>
<li><tt>SQLTemplate_DBOpts «option-string»</tt> – options for the driver (e.g. database name, username, password...)</li>
<li><tt>SQLTemplate_Caching «on|off»</tt> – enable/disable configuration caching</li>
<li><tt>SQLTemplate_CacheDir «path»</tt> – directory in which to save cached configurations</li>
<li><tt>&lt;SQLRepeat «query»&gt;</tt> – new section, as described below</li>
<li><tt>&lt;SQLCatSet «sep» «query»&gt;</tt> – new section, as described below</li>
</ul>
<h3>SQLRepeat</h3>
<p>The <tt>SQLRepeat</tt> section is probably going to be the most-used new directive. It provides templating functionality similar to <a title="mod_macro by Fabien Coelho" href="http://cri.ensmp.fr/~coelho/mod_macro/" target="_blank"><tt>mod_macro</tt></a>, although the template variables are taken from the column names of the query rather than being explicitly specified. The section will then be repeated for each row of the resultset, substitutions occurring as required.</p>
<p>Perhaps an example would help:</p>
<pre lang="apache">&lt;SQLRepeat "SELECT id,hostname,domain FROM apache_hosts"&gt;
&lt;VirtualHost *:80&gt;
  DocumentRoot /var/www/${hostname}.${domain}
  ServerName ${hostname}.${domain}
  # ...
&lt;/VirtualHost&gt;
&lt;/SQLRepeat&gt;</pre>
<p>For this example, I've avoided the configuration directives for clarity, assuming they are specified elsewhere. Supposing the database table contains simply:</p>
<table border="0">
<tbody>
<tr>
<th>ID</th>
<th>hostname</th>
<th>domain</th>
</tr>
<tr>
<td>1</td>
<td>www</td>
<td>example.com</td>
</tr>
<tr>
<td>3</td>
<td>test</td>
<td>example.com</td>
</tr>
<tr>
<td>12</td>
<td>yourhost</td>
<td>somewhere.local</td>
</tr>
</tbody>
</table>
<p>Then this will expand to be equivalent to:</p>
<pre lang="apache">&lt;VirtualHost *:80&gt;
  DocumentRoot /var/www/www.example.com
  ServerName www.example.com
  # ...
&lt;/VirtualHost&gt;
&lt;VirtualHost *:80&gt;
  DocumentRoot /var/www/test.example.com
  ServerName test.example.com
  # ...
&lt;/VirtualHost&gt;
&lt;VirtualHost *:80&gt;
  DocumentRoot /var/www/yourhost.somewhere.local
  ServerName yourhost.somewhere.local
  # ...
&lt;/VirtualHost&gt;</pre>
<p>And so on. These sections can be nested, so if you wanted to store a list of aliases as well:</p>
<table border="0">
<tbody>
<tr>
<th>ID</th>
<th>hostid</th>
<th>alias</th>
<th>target</th>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>/icons</td>
<td>/var/www/_share/icons</td>
</tr>
<tr>
<td>2</td>
<td>1</td>
<td>/example</td>
<td>/var/www/_share/foo</td>
</tr>
<tr>
<td>5</td>
<td>12</td>
<td>/bar</td>
<td>/var/www/_share/foo</td>
</tr>
</tbody>
</table>
<p>You could use something like this:</p>
<pre lang="apache">&lt;SQLRepeat "SELECT id,hostname,domain FROM apache_hosts"&gt;
&lt;VirtualHost *:80&gt;
  DocumentRoot /var/www/${hostname}.${domain}
  ServerName ${hostname}.${domain}
  # ...
  &lt;SQLRepeat "SELECT alias,target FROM apache_aliases WHERE hostid=?" ${id}&gt;
    Alias "${alias}" "${target}"
  &lt;/SQLRepeat&gt;
&lt;/VirtualHost&gt;
&lt;/SQLRepeat&gt;</pre>
<p>which would then expand to:</p>
<pre lang="apache">&lt;VirtualHost *:80&gt;
  DocumentRoot /var/www/www.example.com
  ServerName www.example.com
  # ...
    Alias "/icons" "/var/www/_share/icons"
    Alias "/example" "/var/www/_share/foo"
&lt;/VirtualHost&gt;
&lt;VirtualHost *:80&gt;
  DocumentRoot /var/www/test.example.com
  ServerName test.example.com
  # ...
&lt;/VirtualHost&gt;
&lt;VirtualHost *:80&gt;
  DocumentRoot /var/www/yourhost.somewhere.local
  ServerName yourhost.somewhere.local
  # ...
    Alias "/bar" "/var/www/_share/foo"
&lt;/VirtualHost&gt;</pre>
<p>So far, so good. Something to note is that the variable names above did not conflict. If we had included "id" in the list of columns for the inner <tt>SQLRepeat</tt>, then included <tt>${id}</tt>, the module should use the innermost scope. Disambiguation should be obtained by table alias prefixing (e.g. <tt>${apache_hosts.id}</tt> or <tt>${apache_aliases.id}</tt>). Full variable names should always be specified for clarity. This also shows that if the query returns no results, the repeating section is not included, as you would expect. Also note that queries that use variable substitution should use the prepared statement format, with variables specified afterwards. Variables will be included directly, so anything that might contain spaces must be quoted.</p>
<p>However, there are some directives like <tt>ServerAlias</tt> that must be specified once with a list of space-separated values. Enter <tt>SQLCatSet</tt>...</p>
<h3>SQLCatSet</h3>
<p>This acts in a similar way to <tt>SQLRepeat</tt>, but it concatenates all of the results for each field before substituting, and it includes its content at most once. If there are no results for the query, then it will not include its content. For example, with a server aliases table like:</p>
<table border="0">
<tbody>
<tr>
<th>ID</th>
<th>hostid</th>
<th>alias</th>
</tr>
<tr>
<td>1</td>
<td>3</td>
<td>test2.example.com</td>
</tr>
<tr>
<td>2</td>
<td>3</td>
<td>test.example.net</td>
</tr>
<tr>
<td>5</td>
<td>12</td>
<td>*.somewhere.local</td>
</tr>
</tbody>
</table>
<p>You could use something like this:</p>
<pre lang="apache">&lt;SQLRepeat "SELECT id,hostname,domain FROM apache_hosts"&gt;
&lt;VirtualHost *:80&gt;
  DocumentRoot /var/www/${hostname}.${domain}
  ServerName ${hostname}.${domain}
  &lt;SQLCatSet " " "SELECT alias FROM apache_server_aliases WHERE hostid=?" ${id}&gt;
    ServerAlias ${alias}
  &lt;/SQLCatSet&gt;
  # ...
  &lt;SQLRepeat "SELECT alias,target FROM apache_aliases WHERE hostid=?" ${id}&gt;
    Alias "${alias}" "${target}"
  &lt;/SQLRepeat&gt;
&lt;/VirtualHost&gt;
&lt;/SQLRepeat&gt;</pre>
<p>which would then expand to:</p>
<pre lang="apache">&lt;VirtualHost *:80&gt;
  DocumentRoot /var/www/www.example.com
  ServerName www.example.com
  # ...
    Alias "/icons" "/var/www/_share/icons"
    Alias "/example" "/var/www/_share/foo"
&lt;/VirtualHost&gt;
&lt;VirtualHost *:80&gt;
  DocumentRoot /var/www/test.example.com
  ServerName test.example.com
    ServerAlias test2.example.com test.example.net
  # ...
&lt;/VirtualHost&gt;
&lt;VirtualHost *:80&gt;
  DocumentRoot /var/www/yourhost.somewhere.local
  ServerName yourhost.somewhere.local
    ServerAlias *.somewhere.local
  # ...
    Alias "/bar" "/var/www/_share/foo"
&lt;/VirtualHost&gt;</pre>
<p>This would seem to cover the major functionality needed for automatically generating configurations in a really flexible way, although I'm sure more will probably be needed at some point... like <tt>SQLIf</tt>, perhaps.</p>
<h2>PHP Framework</h2>
<p>It occurs to me that having a framework's code in PHP itself could mean that it is quite slow. It would be interesting to put together a framework in C and embedded as a module, to see if there are any memory/speed improvements possible. It might just be a case of implementing an ORM (Object Relational Model) system to begin with. Obviously, this idea is nowhere near as fully-formed!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dmi.me.uk/blog/2008/08/13/modules-for-apache-and-php/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/3.0/</creativeCommons:license>
	</item>
	</channel>
</rss>

