<?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>netCUBED Blog</title>
	<atom:link href="http://blog.netcubed.de/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.netcubed.de</link>
	<description>Just another web developer's weblog</description>
	<lastBuildDate>Mon, 29 Jun 2009 20:58:35 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Test for &#8220;forbidden&#8221; words?</title>
		<link>http://blog.netcubed.de/2009/06/test-for-forbidden-words/</link>
		<comments>http://blog.netcubed.de/2009/06/test-for-forbidden-words/#comments</comments>
		<pubDate>Mon, 29 Jun 2009 20:53:15 +0000</pubDate>
		<dc:creator>Moritz Onken</dc:creator>
				<category><![CDATA[Perl]]></category>
		<category><![CDATA[forbidden words]]></category>
		<category><![CDATA[regex]]></category>
		<category><![CDATA[test]]></category>

		<guid isPermaLink="false">http://blog.netcubed.de/?p=88</guid>
		<description><![CDATA[I&#8217;m developing a web app right now and as some of you might know there is a very popular javascript command which is used for debugging. It&#8217;s invoked via console.log() and takes anything as an argument. If you use Firefox with Firebug or Safari 4 the value you pass to console.log will be printed and [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m developing a web app right now and as some of you might know there is a very popular javascript command which is used for debugging. It&#8217;s invoked via <code>console.log()</code> and takes anything as an argument. If you use Firefox with Firebug or Safari 4 the value you pass to <code>console.log</code> will be printed and introspected via a debug window.</p>
<p>The problem is that I forget on a regular basis to remove those <code>console.log</code> statements. I wrote a very quick and dirty perl script which searches files with  an .js extension for console.log. I put that script in the t/ folder and named it <code>forbidden_words.t</code>.</p>
<p>It works great so far and my test suite fails as soon as there is still a console.log around. I plan to extend this script to something like Test::ForbiddenWords or something where you can specify file extensions and strings (or regexes).</p>
<p>I couldn&#8217;t find anything like this on the CPAN, so give me a comment if you like the idea or know something better.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.netcubed.de/2009/06/test-for-forbidden-words/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Create Apache2 VHosts on the fly with mod_perl</title>
		<link>http://blog.netcubed.de/2009/06/create-apache2-vhosts-on-the-fly-with-mod_perl/</link>
		<comments>http://blog.netcubed.de/2009/06/create-apache2-vhosts-on-the-fly-with-mod_perl/#comments</comments>
		<pubDate>Mon, 22 Jun 2009 05:56:05 +0000</pubDate>
		<dc:creator>Moritz Onken</dc:creator>
				<category><![CDATA[Perl]]></category>
		<category><![CDATA[apache2]]></category>
		<category><![CDATA[dynamic]]></category>
		<category><![CDATA[mod perl]]></category>
		<category><![CDATA[mod_perl]]></category>
		<category><![CDATA[mod_perl2]]></category>
		<category><![CDATA[virtual host]]></category>

		<guid isPermaLink="false">http://blog.netcubed.de/?p=154</guid>
		<description><![CDATA[This script is in use for many years now and does a decent job. I set up a MySQL table which specifies the basic configuration options for an Apache2 virtual host:

CREATE TABLE `vhosts` &#40;
  `id` int&#40;11&#41; NOT NULL AUTO_INCREMENT,
  `DocumentRoot` text NOT NULL,
  `ServerName` varchar&#40;255&#41; NOT NULL DEFAULT '',
  `ServerAlias` varchar&#40;255&#41; [...]]]></description>
			<content:encoded><![CDATA[<p>This script is in use for many years now and does a decent job. I set up a MySQL table which specifies the basic configuration options for an Apache2 virtual host:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #ff0000;">`vhosts`</span> <span style="color: #66cc66;">&#40;</span>
  <span style="color: #ff0000;">`id`</span> int<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">11</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span><span style="color: #66cc66;">,</span>
  <span style="color: #ff0000;">`DocumentRoot`</span> text <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span>
  <span style="color: #ff0000;">`ServerName`</span> varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #ff0000;">''</span><span style="color: #66cc66;">,</span>
  <span style="color: #ff0000;">`ServerAlias`</span> varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #ff0000;">''</span><span style="color: #66cc66;">,</span>
  <span style="color: #ff0000;">`ScriptAlias`</span> text <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span>
  <span style="color: #ff0000;">`CustomLog`</span> text <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span>
  <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span>  <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`id`</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span> ;</pre></div></div>

<p>In <code>/etc/apache2/conf.d/vhosts.perl.conf</code> I&#8217;ve put this little script:</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #009999;">&lt;Perl&gt;</span>
<span style="color: #000000; font-weight: bold;">use</span> DBI<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> File<span style="color: #339933;">::</span><span style="color: #006600;">Path</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dbh</span> <span style="color: #339933;">=</span> DBI<span style="color: #339933;">-&gt;</span><span style="color: #006600;">connect</span><span style="color: #009900;">&#40;</span> <span style="color: #ff0000;">&quot;DBI:mysql:vhosts&quot;</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;apache&quot;</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;password&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$sth</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;select * from vhosts&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span> <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$vhost</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">fetchrow_hashref</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">unless</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">-</span>d <span style="color: #009900;">&#40;</span> <span style="color: #000066;">split</span><span style="color: #009900;">&#40;</span> <span style="color: #009966; font-style: italic;">/ /</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$vhost</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>ScriptAlias<span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        mkpath<span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#40;</span> <span style="color: #000066;">split</span><span style="color: #009900;">&#40;</span> <span style="color: #009966; font-style: italic;">/ /</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$vhost</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>ScriptAlias<span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">unless</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">-</span>d <span style="color: #0000ff;">$vhost</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>DocumentRoot<span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        mkpath<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">$vhost</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>DocumentRoot<span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">unless</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">-</span>e <span style="color: #009900;">&#40;</span> <span style="color: #000066;">split</span><span style="color: #009900;">&#40;</span> <span style="color: #009966; font-style: italic;">/ /</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$vhost</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>CustomLog<span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dir</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$vhost</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>CustomLog<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
        <span style="color: #0000ff;">$dir</span> <span style="color: #339933;">=~</span> <span style="color: #009966; font-style: italic;">s/(.*)\/.*?$/$1/</span><span style="color: #339933;">;</span>
        mkpath<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$dir</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000066;">undef</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">$vhost</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>id<span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000066;">push</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">@VirtualHost</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span> <span style="color: #ff0000;">&quot;*&quot;</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">$vhost</span> <span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span>
<span style="color: #0000ff;">$sth</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">finish</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">disconnect</span><span style="color: #339933;">;</span>
<span style="color: #339933;">&lt;/</span>Perl<span style="color: #339933;">&gt;</span></pre></div></div>

<p>As you can see the script uses all columns from the table to set up the virtual host. You can easily add more columns (e.g. ErrorLog) to the table as long as their name is known to the apache2 configuration.</p>
<p>After you added a new vhost to the database you need to restart the apache server so that the perl script is run and the vhost is set up.</p>
<p>This will create the directories of any vhost which has been added to the table &#8220;vhosts&#8221; and create a virtual host inside of apache. This is very handy if you need to maintain multiple sites which share the same layout and need basic functionality.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.netcubed.de/2009/06/create-apache2-vhosts-on-the-fly-with-mod_perl/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Devel::IntelliPerl released on an unsuspecting world.</title>
		<link>http://blog.netcubed.de/2009/06/develintelliperl-released-on-an-unsuspecting-world/</link>
		<comments>http://blog.netcubed.de/2009/06/develintelliperl-released-on-an-unsuspecting-world/#comments</comments>
		<pubDate>Fri, 12 Jun 2009 14:52:29 +0000</pubDate>
		<dc:creator>Moritz Onken</dc:creator>
				<category><![CDATA[Perl]]></category>
		<category><![CDATA[code completion]]></category>
		<category><![CDATA[devel]]></category>
		<category><![CDATA[intelliperl]]></category>

		<guid isPermaLink="false">http://blog.netcubed.de/?p=132</guid>
		<description><![CDATA[I managed to pack my work on code completion to a distribution and released it to the CPAN. The source code is managed on github. Use it, watch it, fork it, break it, fix it, patch it &#8230; you know the game!
Watch the demo for new features (no audio).
So what is missing?
It would be great [...]]]></description>
			<content:encoded><![CDATA[<p>I managed to pack my work on code completion to a distribution and released it to the <a href="http://search.cpan.org/perldoc?Devel::IntelliPerl" target="_blank">CPAN</a>. The source code is managed on <a href="http://github.com/monken/Devel-IntelliPerl/tree/master" target="_blank">github</a>. Use it, watch it, fork it, break it, fix it, patch it &#8230; you know the game!</p>
<p>Watch the demo for new features (no audio).</p>
<span class='flash'><span id='flash-develintelliperl-released-on-an-unsuspecting-world2.41863422437E+32'></span></span>
<script type='text/javascript'>
var params = {
allowfullscreen: 'true'
};var flashvars = null
swfobject.embedSWF('http://blog.netcubed.de/wp-content/uploads/2009/06/00000005.swf', 'flash-develintelliperl-released-on-an-unsuspecting-world2.41863422437E+32', '500', '293', '9.0.0', '', flashvars, params, '');
</script>
<p>So what is missing?<br />
It would be great if code completion works for chained method calls:</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># DateTime</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$dt</span> <span style="color: #339933;">=</span> DateTime<span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #009900;">&#40;</span>year <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">2009</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$dt</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">add</span><span style="color: #009900;">&#40;</span> months <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span>_  <span style="color: #666666; font-style: italic;"># we are still a DateTime object!</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># in a DBIC environment</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$rs</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$schema</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">resultset</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'Foo'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span>_ <span style="color: #666666; font-style: italic;"># we get a MySchema::ResultSet::Foo</span></pre></div></div>

<p>What we need is a way to define the return values of methods. Moose&#8217;s type system is not much of a help because you cannot introspect what class is behind a custom type.</p>
<p>I was thinking about an IntelliPerl profile which is stored in the home directory as well as in each project. Those two are merged and define method signatures and variable types.</p>
<p>Possible syntax:</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># ~/.intelliperl</span>
<span style="color: #0000ff;">$schema</span> isa DBIx<span style="color: #339933;">::</span><span style="color: #006600;">Class</span><span style="color: #339933;">::</span><span style="color: #006600;">Schema</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$rs</span> isa DBIx<span style="color: #339933;">::</span><span style="color: #006600;">Class</span><span style="color: #339933;">::</span><span style="color: #006600;">ResultSet</span><span style="color: #339933;">;</span>
<span style="color: #0000ff;">$dt</span> isa DateTime<span style="color: #339933;">;</span>
&nbsp;
method DBIx<span style="color: #339933;">::</span><span style="color: #006600;">Class</span><span style="color: #339933;">::</span><span style="color: #006600;">ResultSet</span><span style="color: #339933;">::</span><span style="color: #006600;">search</span> returns DBIx<span style="color: #339933;">::</span><span style="color: #006600;">Class</span><span style="color: #339933;">::</span><span style="color: #006600;">ResultSet</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># ~/workspace/MyApp/.intelliperl</span>
&nbsp;
<span style="color: #0000ff;">$schema</span> isa MyApp<span style="color: #339933;">::</span><span style="color: #006600;">Model</span><span style="color: #339933;">::</span><span style="color: #006600;">DBIC</span>
<span style="color: #0000ff;">$rs</span> isa MyApp<span style="color: #339933;">::</span><span style="color: #006600;">Schema</span><span style="color: #339933;">::</span><span style="color: #006600;">ResultSet</span></pre></div></div>

<p>A different approach would be to add the method signature to the POD:</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;">&nbsp;
<span style="color: #666666; font-style: italic;">=head2 mymethod
&nbsp;
=for intelliperl
method mymethod ($dt DateTime) returns DateTime</span></pre></div></div>

<p>This will make <code>$dt</code> inside mymethod a DateTime variable and the returned value is a DateTime object as well.</p>
<p>For now only <a href="http://search.cpan.org/perldoc?Devel::IntelliPerl::Editor::TextMate" target="_blank">TextMate</a> is supported. See the documentation for details.</p>
<p>I&#8217;d love to see more Devel::IntelliPerl::Editor::s!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.netcubed.de/2009/06/develintelliperl-released-on-an-unsuspecting-world/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Perl autocompletion of methods for TextMate</title>
		<link>http://blog.netcubed.de/2009/06/perl-autocompletion-of-methods-for-textmate/</link>
		<comments>http://blog.netcubed.de/2009/06/perl-autocompletion-of-methods-for-textmate/#comments</comments>
		<pubDate>Wed, 10 Jun 2009 08:26:01 +0000</pubDate>
		<dc:creator>Moritz Onken</dc:creator>
				<category><![CDATA[Perl]]></category>
		<category><![CDATA[auto completion]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[completion]]></category>
		<category><![CDATA[textmate]]></category>

		<guid isPermaLink="false">http://blog.netcubed.de/?p=120</guid>
		<description><![CDATA[It is pretty hard to write a code completion script for perl since it&#8217;s hard to find out of which type a variable is. I use simple regexes and a comment to achieve this. Here is how it looks like:
It consists of a perl script which reads the current file from STDIN and gets the [...]]]></description>
			<content:encoded><![CDATA[<span class='flash'><span id='flash-perl-autocompletion-of-methods-for-textmate1.58507612528E+37'></span></span>
<script type='text/javascript'>
var params = {
allowfullscreen: 'true'
};var flashvars = null
swfobject.embedSWF('http://blog.netcubed.de/wp-content/uploads/2009/06/2009-06-10_1002.swf', 'flash-perl-autocompletion-of-methods-for-textmate1.58507612528E+37', '574', '474', '9.0.0', '', flashvars, params, '');
</script>
<p>It is pretty hard to write a code completion script for perl since it&#8217;s hard to find out of which type a variable is. I use simple regexes and a comment to achieve this. Here is how it looks like:</p>
<p>It consists of a perl script which reads the current file from STDIN and gets the current line number as well as the cursor position in that line. The script is run if the cursor is behind a <code>-&gt;</code> and the string before that looks like a class or a variable. If it&#8217;s a variable the script travels the lines up until it finds something like <code>$var = Class->new</code>, <code>$var = new Class</code> or <code> # $var isa Class</code>.</p>
<p><code>Class::MOP::Class</code> loads that class and retrieves all method names. It also evaluates the prefix which has been entered behind the <code>-></code> and displays those methods only which have the same prefix. Private methods are moved to the buttom as well as capitalized method names.</p>
<p>The second part of this script is embedded in TextMate. TextMate allows to define custom commands. You can define how the data shoud be rendered depending on the return value of the script. In this case STDERR is printed directly into the editor (if there is only one method left) and STDOUT is printed as tool tip.</p>
<p>I&#8217;d like to hear what you think about it and whether there are better / other approaches. I should probably use PPI instead of regexes to parse the document. This is one of the reasons why I did not release any code yet. Another shortcoming is speed. Especially for large classes like Catalyst or DateTime it takes a noticeable time until you get the results.</p>
<p>So long&#8230; I&#8217;ll keep you posted.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.netcubed.de/2009/06/perl-autocompletion-of-methods-for-textmate/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Format JavaScript in TextMate with JavaScript::Beautifier</title>
		<link>http://blog.netcubed.de/2009/06/format-javascript-in-textmate-with-javascriptbeautifier/</link>
		<comments>http://blog.netcubed.de/2009/06/format-javascript-in-textmate-with-javascriptbeautifier/#comments</comments>
		<pubDate>Thu, 04 Jun 2009 17:08:53 +0000</pubDate>
		<dc:creator>Moritz Onken</dc:creator>
				<category><![CDATA[Perl]]></category>
		<category><![CDATA[format]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[textmate]]></category>

		<guid isPermaLink="false">http://blog.netcubed.de/?p=104</guid>
		<description><![CDATA[TextMate has a number of great bundles which help you develop in many many languages. The feature I miss most is formatting for JavaScript just like Perl Tidy does it for Perl.
I recently saw JavaScript::Beautifier in the &#8220;Recent&#8221; list on the CPAN and was wondering if I can bind it to TextMate. This is how [...]]]></description>
			<content:encoded><![CDATA[<p>TextMate has a number of great bundles which help you develop in many many languages. The feature I miss most is formatting for JavaScript just like Perl Tidy does it for Perl.</p>
<p>I recently saw <a href="http://search.cpan.org/perldoc?JavaScript::Beautifier">JavaScript::Beautifier</a> in the &#8220;Recent&#8221; list on the CPAN and was wondering if I can bind it to TextMate. This is how I did it:</p>
<p>First of all, install it:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> cpan <span style="color: #660033;">-i</span> JavaScript::Beautifier</pre></div></div>

<p>Next, add the command to TextMate. Open the Bundle Editor (Bundles/Bundle Editor/Show Bundle Editor).</p>
<p style="text-align: center;"><img class="size-full wp-image-106   aligncenter" title="bild-1" src="http://blog.netcubed.de/wp-content/uploads/2009/06/bild-1.png" alt="bild-1" width="267" height="161" /></p>
<p style="text-align: left; clear:both">Then select JavaScript and click on &#8220;New Command&#8221; (bottom left).<img class="size-medium wp-image-107   aligncenter" title="bild-2" src="http://blog.netcubed.de/wp-content/uploads/2009/06/bild-2-300x220.png" alt="bild-2" width="300" height="220" /></p>
<p style="text-align: left; clear:both">Name it &#8220;Beautifier&#8221; (or whatever you want) and paste the following in the command text field:</p>
<pre>require_cmd js_beautify.pl 'sudo cpan -i JavaScript::Beautifier'

js_beautify.pl $TM_FILEPATH</pre>
<p>Set the rest of the options like this:</p>
<pre style="text-align: center;"><img class="size-full wp-image-108" title="bild-3" src="http://blog.netcubed.de/wp-content/uploads/2009/06/bild-3.png" alt="bild-3" width="457" height="466" /></pre>
<p>Now you are ready to go! Open up a JavaScript document and hit Shift+Crtl+H and the current document should be formatted.</p>
<p style="text-align: center;"><img class="size-full wp-image-105   aligncenter" title="bild-9" src="http://blog.netcubed.de/wp-content/uploads/2009/06/bild-9.png" alt="bild-9" width="234" height="134" /></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.netcubed.de/2009/06/format-javascript-in-textmate-with-javascriptbeautifier/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Phonetic search with DBIC</title>
		<link>http://blog.netcubed.de/2009/05/phonetic-search-with-dbic/</link>
		<comments>http://blog.netcubed.de/2009/05/phonetic-search-with-dbic/#comments</comments>
		<pubDate>Fri, 29 May 2009 14:49:42 +0000</pubDate>
		<dc:creator>Moritz Onken</dc:creator>
				<category><![CDATA[Perl]]></category>
		<category><![CDATA[dbic]]></category>
		<category><![CDATA[phonetic]]></category>
		<category><![CDATA[search]]></category>

		<guid isPermaLink="false">http://blog.netcubed.de/?p=97</guid>
		<description><![CDATA[I recently ran across the probem that there are many people with almost identical last names and it is hard to guess every possible spelling until you finally find the person you were looking for.
In german, there are a lot of possible spellings for the name &#8220;Maier&#8221; which all sound the same: Meyer, Meier, Mayer, [...]]]></description>
			<content:encoded><![CDATA[<p>I recently ran across the probem that there are many people with almost identical last names and it is hard to guess every possible spelling until you finally find the person you were looking for.</p>
<p>In german, there are a lot of possible spellings for the name &#8220;Maier&#8221; which all sound the same: Meyer, Meier, Mayer, Mayr, Meyr etc.</p>
<p>A phonetic algorithm reduces a given word to a digest which is the same for all names, which sound similar. After asking for a proper name on #dbix-class I came up with the DBIx-Class-PhoneticSearch module.</p>
<p>For now it is only avaiable from <a href="http://github.com/monken/DBIx-Class-PhoneticSearch/tree/master">github</a>. But sometime soon it will be on the CPAN :-)</p>
<p>The usage is pretty easy:</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;">    <span style="color: #000066;">package</span> MySchema<span style="color: #339933;">::</span><span style="color: #006600;">User</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">use</span> base <span style="color: #ff0000;">'DBIx::Class'</span><span style="color: #339933;">;</span>
&nbsp;
    __PACKAGE__<span style="color: #339933;">-&gt;</span><span style="color: #006600;">load_components</span><span style="color: #009900;">&#40;</span><span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span>PhoneticSearch Core<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    __PACKAGE__<span style="color: #339933;">-&gt;</span><span style="color: #006600;">table</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'user'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    __PACKAGE__<span style="color: #339933;">-&gt;</span><span style="color: #006600;">add_columns</span><span style="color: #009900;">&#40;</span>
      id       <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#123;</span> data_type <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'integer'</span><span style="color: #339933;">,</span> auto_increment <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      surname  <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#123;</span> data_type <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'character varying'</span><span style="color: #339933;">,</span> 
                    phonetic_search <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      forename <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#123;</span> data_type <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'character varying'</span><span style="color: #339933;">,</span> 
                    phonetic_search <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#123;</span> algorithm <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'Koeln'</span><span style="color: #339933;">,</span> 
                                         no_indices <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span> <span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
    <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    __PACKAGE__<span style="color: #339933;">-&gt;</span><span style="color: #006600;">set_primary_key</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'id'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    __PACKAGE__<span style="color: #339933;">-&gt;</span><span style="color: #006600;">resultset_class</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'DBIx::Class::ResultSet::PhoneticSearch'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>This defines a result class with a forename and surname column. Both are phonetic-enabled. forename uses the Koeln algorithm, which has been optimized for german names and words. Make sure you <code>deploy()</code> that schema again or add the two columns to your schema.</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">ALTER</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #ff0000;">`user`</span> <span style="color: #993333; font-weight: bold;">ADD</span> <span style="color: #993333; font-weight: bold;">COLUMN</span> <span style="color: #ff0000;">`surname_phonetic_phonix`</span> CHARACTER VARYING;
<span style="color: #993333; font-weight: bold;">ALTER</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #ff0000;">`user`</span> <span style="color: #993333; font-weight: bold;">ADD</span> <span style="color: #993333; font-weight: bold;">COLUMN</span> <span style="color: #ff0000;">`forename_phonetic_koeln`</span> CHARACTER VARYING;</pre></div></div>

<p>Now you can search for any user by a similar sounding name:</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;">  <span style="color: #0000ff;">$rs</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$schema</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">resultset</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'User'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #0000ff;">$rs</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">create</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> forename <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'John'</span><span style="color: #339933;">,</span> surname <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'Night'</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #0000ff;">$rs</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">search_phonetic</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> forename <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'Jon'</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">first</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">forename</span><span style="color: #339933;">;</span>  <span style="color: #666666; font-style: italic;"># John</span>
  <span style="color: #0000ff;">$rs</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">search_phonetic</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> surname <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'Knight'</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">first</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">surname</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;"># Night</span></pre></div></div>

<p>The default algorithm is <a href="http://search.cpan.org/perldoc?Text::Phonetic::Phonix">Phonix</a> which is IMHO far superior to the popular Soundex algorithm. E. g. the last example (Knight -> Night) does not work with Soundex.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.netcubed.de/2009/05/phonetic-search-with-dbic/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Reports with DBIC and Postgres</title>
		<link>http://blog.netcubed.de/2009/05/reports-with-dbic-and-postgres/</link>
		<comments>http://blog.netcubed.de/2009/05/reports-with-dbic-and-postgres/#comments</comments>
		<pubDate>Sat, 23 May 2009 10:52:47 +0000</pubDate>
		<dc:creator>Moritz Onken</dc:creator>
				<category><![CDATA[Perl]]></category>
		<category><![CDATA[dbic]]></category>
		<category><![CDATA[postgresql]]></category>
		<category><![CDATA[reports]]></category>

		<guid isPermaLink="false">http://blog.netcubed.de/?p=91</guid>
		<description><![CDATA[Currently I use plain SQL statements to create reports which, for instance, show me the number of logins of all users on a 5 minutes scale.
One of those statements looks similar to this:

INSERT INTO report_item 
    &#40;
        SELECT '2009-05-23 02:30:00+0200'::timestamp WITH time zone + &#40;s.a [...]]]></description>
			<content:encoded><![CDATA[<p>Currently I use plain SQL statements to create reports which, for instance, show me the number of logins of all users on a 5 minutes scale.</p>
<p>One of those statements looks similar to this:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> report_item 
    <span style="color: #66cc66;">&#40;</span>
        <span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">'2009-05-23 02:30:00+0200'</span>::timestamp <span style="color: #993333; font-weight: bold;">WITH</span> time zone <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#40;</span>s<span style="color: #66cc66;">.</span>a <span style="color: #66cc66;">||</span> <span style="color: #ff0000;">' minute'</span><span style="color: #66cc66;">&#41;</span>::interval <span style="color: #993333; font-weight: bold;">AS</span> timestamp<span style="color: #66cc66;">,</span> 
               COUNT<span style="color: #66cc66;">&#40;</span>source<span style="color: #66cc66;">.</span><span style="color: #ff0000;">&quot;created_on&quot;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> value
        <span style="color: #993333; font-weight: bold;">FROM</span> generate_series<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">595</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">5</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> s<span style="color: #66cc66;">&#40;</span>a<span style="color: #66cc66;">&#41;</span>
&nbsp;
        <span style="color: #993333; font-weight: bold;">LEFT</span> <span style="color: #993333; font-weight: bold;">JOIN</span> 
          <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">&quot;created_on&quot;</span> <span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #ff0000;">&quot;session&quot;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> source
          <span style="color: #993333; font-weight: bold;">ON</span> source<span style="color: #66cc66;">.</span><span style="color: #ff0000;">&quot;created_on&quot;</span> <span style="color: #66cc66;">&gt;=</span> <span style="color: #ff0000;">'2009-05-23 02:30:00+0200'</span>::timestamp <span style="color: #993333; font-weight: bold;">WITH</span> time zone <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#40;</span>s<span style="color: #66cc66;">.</span>a  <span style="color: #66cc66;">||</span> <span style="color: #ff0000;">' minute'</span><span style="color: #66cc66;">&#41;</span>::interval 
             <span style="color: #993333; font-weight: bold;">AND</span> source<span style="color: #66cc66;">.</span><span style="color: #ff0000;">&quot;created_on&quot;</span> <span style="color: #66cc66;">&lt;</span> <span style="color: #ff0000;">'2009-05-23 02:30:00+0200'</span>::timestamp <span style="color: #993333; font-weight: bold;">WITH</span> time zone <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#40;</span>s<span style="color: #66cc66;">.</span>a  <span style="color: #66cc66;">+</span> <span style="color: #cc66cc;">5</span> <span style="color: #66cc66;">||</span> <span style="color: #ff0000;">' minute'</span><span style="color: #66cc66;">&#41;</span>::interval
&nbsp;
        <span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> a
    <span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>This gives me the number of logins (or new sessions) per 5 minute time slot. Now it&#8217;s pretty easy to read the data from <code>report_item</code> and create a graph or do other nice things with it.</p>
<p>I was thinking about a more generic way to do these reports so that the user can choose, what kind of report he wants.</p>
<p>So I started to create a result class <code>Report</code> with the following columns:</p>
<ul>
<li>group_by<br/>The column which is used to group rows together. This is always a timestamp column, e.g. <code>created_on</code></li>
<li>interval_type<br/>Group by minutes, hours, days, weeks etc. (defaults to minutes)</li>
<li>interval_length<br/>Group by that amount of <code>interval_type</code> (defaults to 5)</li>
<li>aggregate_by<br/>Which SQL function should be used to aggregate data in a time slot (defaults to <code>COUNT</code>)</li>
<li>aggregate<br/>Which column should be aggregated</li>
<li>query<br/>Which data should be aggregated? This accepts a DBIC result set or a plain SQL statement
</ul>
<p>After you created a report in that table you call <code>$report->create_report</code> on that row. This will execute the query above with the correct values filled in and the result will be stored in a table <code>result_item</code>, which has a foreign key <code>report_id</code> to the report.</p>
<p>It does a decent job so far and I was wondering if anyone else did something like this before?</p>
<p>If anyone is interested in the code I can make a dist and upload it to github. Since the SQL is Postgres only I don&#8217;t want to push it to the CPAN.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.netcubed.de/2009/05/reports-with-dbic-and-postgres/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How do your DBIC result base classes look like?</title>
		<link>http://blog.netcubed.de/2009/05/how-do-your-dbic-result-base-classes-look-like/</link>
		<comments>http://blog.netcubed.de/2009/05/how-do-your-dbic-result-base-classes-look-like/#comments</comments>
		<pubDate>Thu, 21 May 2009 08:57:51 +0000</pubDate>
		<dc:creator>Moritz Onken</dc:creator>
				<category><![CDATA[Perl]]></category>
		<category><![CDATA[class]]></category>
		<category><![CDATA[dbic]]></category>
		<category><![CDATA[dbix-class]]></category>
		<category><![CDATA[examples]]></category>
		<category><![CDATA[result]]></category>
		<category><![CDATA[resultset]]></category>

		<guid isPermaLink="false">http://blog.netcubed.de/?p=56</guid>
		<description><![CDATA[I was wondering how you design your base classes for DBIC result(set) classes. I think it&#8217;s a good idea both in terms of startup speed and ease of use to not use DBIx::Class as base of your result classes but use a custom one instead. The same applies for the resultset classes. Here is how [...]]]></description>
			<content:encoded><![CDATA[<p>I was wondering how you design your base classes for DBIC result(set) classes. I think it&#8217;s a good idea both in terms of <a href="http://lists.scsys.co.uk/pipermail/dbix-class/2007-August/004824.html" target="_blank">startup speed</a> and ease of use to not use <code>DBIx::Class</code> as base of your result classes but use a custom one instead. The same applies for the resultset classes. Here is how I designed my DBIC classes:</p>
<p>Make sure you use <code>load_namespaces</code>in <code>MySchema.pm</code>!</p>
<p>Directory structure:</p>
<pre>MySchema.pm
MySchema/
         Base/
              Result.pm
              ResultSet.pm
         Result/
                User.pm
         ResultSet/
                   User.pm</pre>
<p>This has the advantage that the base classes in <code>base</code> are not being loaded. All classes in <code>Result</code> use <code>MySchema::Base::Result</code> as their base class. Classes in <code>ResultSet</code> use <code>MySchema::Base::ResultSet</code> respectively.</p>
<p>My current result base class looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000066;">package</span> MySchema<span style="color: #339933;">::</span><span style="color: #006600;">Base</span><span style="color: #339933;">::</span><span style="color: #006600;">Result</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> strict<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> warnings<span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> base <span style="color: #ff0000;">'DBIx::Class'</span><span style="color: #339933;">;</span>
&nbsp;
__PACKAGE__<span style="color: #339933;">-&gt;</span><span style="color: #006600;">load_components</span><span style="color: #009900;">&#40;</span><span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span>RandomColumns InflateColumn<span style="color: #339933;">::</span><span style="color: #006600;">FS</span> TimeStamp Core<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
__PACKAGE__<span style="color: #339933;">-&gt;</span><span style="color: #006600;">table</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'dummy'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
__PACKAGE__<span style="color: #339933;">-&gt;</span><span style="color: #006600;">add_columns</span><span style="color: #009900;">&#40;</span>
	id <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#123;</span>
      data_type <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'character'</span><span style="color: #339933;">,</span>
      is_random <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#123;</span>size <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">,</span> set <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#91;</span><span style="color: #ff0000;">'a'</span><span style="color: #339933;">..</span><span style="color: #ff0000;">'z'</span><span style="color: #339933;">,</span><span style="color: #ff0000;">'A'</span><span style="color: #339933;">..</span><span style="color: #ff0000;">'Z'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> check <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      size <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">,</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    created_on <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#123;</span>
        data_type <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'timestamp with time zone'</span><span style="color: #339933;">,</span>
        set_on_create <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span>
        is_nullable <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    updated_on <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#123;</span>
        data_type <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'timestamp with time zone'</span><span style="color: #339933;">,</span>
        set_on_create <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span>
        set_on_update <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span>
        is_nullable <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
__PACKAGE__<span style="color: #339933;">-&gt;</span><span style="color: #006600;">set_primary_key</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'id'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
<span style="color: #000000; font-weight: bold;">sub</span> sqlt_deploy_hook <span style="color: #009900;">&#123;</span>
  <span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$self</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$sqlt_table</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span>
  <span style="color: #000066;">map</span> <span style="color: #009900;">&#123;</span> <span style="color: #0000ff;">$sqlt_table</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">drop_constraint</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$_</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">if</span> <span style="color: #0000ff;">$_</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">type</span> <span style="color: #b1b100;">eq</span> <span style="color: #ff0000;">&quot;FOREIGN KEY&quot;</span> <span style="color: #009900;">&#125;</span> 
    <span style="color: #0000ff;">$sqlt_table</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">get_constraints</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
<span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span></pre></div></div>

<p>So what is going on here?</p>
<p>First I use <code>load_components</code> to load all the components which are valuable to all of my result classes. Since I always use a random combination of characters for the primary key column <code>id</code> I load <code>RandomColumns</code>. <code>InflateColumn::FS</code> makes sure that any BLOB is stored on the file system rather than in the database. <code>TimeStamp</code> can set columns to the current time on either update or create. It also loads <code>InflateColumn::DateTime</code> which is used to inflate any date or time columns to a DateTime object.</p>
<p>You need to define a table name, otherwise DBIC fails to compile. This table will never be created or seen in any of your result classes as long as you overwrite it in each class. So just name it <code>dummy</code> or something and you are good.</p>
<p>Next I create a couple of columns which should be avaiable on all result classes. My primary key is always called <code>id</code> so create that column for all my classes. To use the <code>RandomColumns</code> component you have to add that <code>is_random</code> line to the column definition. This will create a random 10-byte long string. Since I&#8217;m a little bit paranoid about collision I set the <code>check</code> parameter so the component checks before inserting a new row if a column with that id is already there. Although this is very unlikely because there are 52^10 combinations, <a href="http://www92.wolframalpha.com/input/?i=52%5E10" target="_blank">quite a lot&#8230;</a>  </p>
<p>The <code>created_on</code> and <code>updated_on</code> columns use the features of <code>TimeStamp</code> to set the time when the record was created or updated respectively. <code>timestamp with time zone</code> is a PostgreSQL specific column. You might need to the correct data type of your dbms.</p>
<p>I use <code>SQL::Translator</code>, <code>DBIx::Class::Schema::Versioned</code> and a few lines of code to deploy and update my database schema. Foreign key constraints on the database slow things down and DBIC handles them anyway so I decided to drop them from the SQL::Translator output. this is done in the <code>sqlt_deploy_hook</code> method.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.netcubed.de/2009/05/how-do-your-dbic-result-base-classes-look-like/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Dispatch Catalyst log output to Growl</title>
		<link>http://blog.netcubed.de/2009/05/dispatch-catalyst-log-output-to-growl/</link>
		<comments>http://blog.netcubed.de/2009/05/dispatch-catalyst-log-output-to-growl/#comments</comments>
		<pubDate>Sun, 10 May 2009 17:02:15 +0000</pubDate>
		<dc:creator>Moritz Onken</dc:creator>
				<category><![CDATA[Perl]]></category>
		<category><![CDATA[catalyst]]></category>
		<category><![CDATA[growl]]></category>
		<category><![CDATA[notification]]></category>

		<guid isPermaLink="false">http://blog.netcubed.de/?p=74</guid>
		<description><![CDATA[Growl is a nice notification utility for Mac OS X. There are many applications or plugins avaiable which interact with Growl (e. g. Skype, Mail, VLC etc.).
I thought it would be nice if I could redirect the catalyst debug output to it as well. Log::Dispatch has a nice appender Log::Dispatch::MacGrowl. Load Log::Dispatch as plugin in [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignright size-medium wp-image-76" title="My App Growls" src="http://blog.netcubed.de/wp-content/uploads/2009/05/bild-5-300x126.png" alt="My App Growls" width="300" height="126" /><a href="http://growl.info/" target="_blank">Growl</a> is a nice notification utility for Mac OS X. There are many applications or plugins avaiable which interact with Growl (e. g. Skype, Mail, VLC etc.).</p>
<p>I thought it would be nice if I could redirect the catalyst debug output to it as well. Log::Dispatch has a nice appender <a href="http://search.cpan.org/perldoc?Log::Dispatch::MacGrowl" target="_blank">Log::Dispatch::MacGrowl</a>. Load Log::Dispatch as plugin in MyApp.pm (after ConfigLoader):</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">use</span> Catalyst <span style="color: #000066;">qw</span><span style="color: #339933;">/-</span>Debug
                ConfigLoader
                Log<span style="color: #339933;">::</span><span style="color: #006600;">Dispatch</span>
                Static<span style="color: #339933;">::</span><span style="color: #006600;">Simple</span><span style="color: #339933;">/;</span></pre></div></div>

<p>and configure your app accordingly:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Log::Dispatch<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	class     = MacGrowl
	name      = growl
	app_name  = MyAppGrowls
	title     = MyApp
	sticky    = 0
	min_level = notice
	format    = [%p] %m %n
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Log::Dispatch<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>I cannot recommend to set <code>min_level</code> to <code>info</code> or below because this will add all start up log statements to be rendered on your screen. Kind of annoying.</p>
<p>Put a log statement anywhere in your code and start up your dev server. A growl notification should appear when you hit the log statement.</p>
<p>You can get a sample application <code>MyAppGrowls</code> from <a href="http://github.com/monken/MyAppGrowls/tree/master" target="_blank">GitHub</a>.</p>
<p>Make sure you have the following modules installed (or run <code>perl Makefile.PL</code>):</p>
<ul>
<li>Catalyst::Plugin::Log::Dispatch</li>
<li>Log::Dispatch::Config</li>
<li>Log::Dispatch::MacGrowl</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.netcubed.de/2009/05/dispatch-catalyst-log-output-to-growl/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Pod::Browser, yet another pod viewer</title>
		<link>http://blog.netcubed.de/2009/05/podbrowser-yet-another-pod-viewer/</link>
		<comments>http://blog.netcubed.de/2009/05/podbrowser-yet-another-pod-viewer/#comments</comments>
		<pubDate>Mon, 04 May 2009 22:27:04 +0000</pubDate>
		<dc:creator>Moritz Onken</dc:creator>
				<category><![CDATA[Perl]]></category>
		<category><![CDATA[browser]]></category>
		<category><![CDATA[catalyst]]></category>
		<category><![CDATA[controller]]></category>
		<category><![CDATA[extjs]]></category>
		<category><![CDATA[pod]]></category>
		<category><![CDATA[viewer]]></category>

		<guid isPermaLink="false">http://blog.netcubed.de/?p=44</guid>
		<description><![CDATA[Writing documentation is sometimes hard but inevitable. If you write code which is published on the CPAN you can always access the documentation through search.cpan.org. For those cases where you cannot publish your code on the CPAN it would be great if you had a web site like CPAN where you can access the documentation. For [...]]]></description>
			<content:encoded><![CDATA[<p>Writing documentation is sometimes hard but inevitable. If you write code which is published on the CPAN you can always access the documentation through search.cpan.org. For those cases where you cannot publish your code on the CPAN it would be great if you had a web site like CPAN where you can access the documentation. For this reason I wrote Pod::Browser a while back. <a href="http://search.cpan.org/perldoc?Pod::Browser" target="_blank">Pod::Browser</a> is a browser for all your local modules and all the modules from the CPAN. The interface is rendered by ExtJS, a powerful JavaScript framework.</p>
<div><a href="http://cpan.org/authors/id/P/PE/PERLER/pod-images/pod-encyclopedia-01.png" target="_blank"><img src="http://cpan.org/authors/id/P/PE/PERLER/pod-images/pod-encyclopedia-01.png" alt="Pod::Browser" width="400" /></a></div>
<p>After installing Pod::Browser and running the server (pod_browser_server.pl) you should be able to access the browser via http://localhost:3000. On the right hand side of the page is a tree which contains all the modules installed on your system. The main page contains a search box where you can search the CPAN via it&#8217;s XML interface. If you open a module which is also installed on your system, the local pod will be served. Otherwise the pod is read from the CPAN. Each module has its own ExtJS tab. This allows to have multiple documents open at the same time in a single browser window. The table of contents is shown in the upper left panel.</p>
<p>Since this browser has been implemented as a single Catalyst controller, you can simply create an empty controller in your application and use Catalyst::Controller::POD as base class:</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #000066;">package</span> MyApp<span style="color: #339933;">::</span><span style="color: #006600;">Controller</span><span style="color: #339933;">::</span><span style="color: #006600;">Docs</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">use</span> strict<span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">use</span> warnings<span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">use</span> base <span style="color: #ff0000;">'Catalyst::Controller::POD'</span><span style="color: #339933;">;</span>
  __PACKAGE__<span style="color: #339933;">-&gt;</span><span style="color: #006600;">config</span><span style="color: #009900;">&#40;</span>
    inc        <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span>
    namespaces <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#91;</span><span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span>Catalyst<span style="color: #339933;">::</span><span style="color: #006600;">Manual</span><span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
    self       <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span>
  <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span></pre></div></div>

<p>This will make the documentation to your application avaiable from /docs. The pod tree will also contain all the modules which are listed in the namespaces config attribute (in this case Catalyst::Manual).</p>
<p>For more information on <a href="http://search.cpan.org/perldoc?Pod::Browser" target="_blank">Pod::Browser</a> and <a href="http://search.cpan.org/perldoc?Catalyst::Controller::POD" target="_blank">Catalyst::Controller::POD</a> please read the documentation on the CPAN.</p>
<p><strong>Warning:</strong></p>
<p>If you set inc to 1 and leave the namespaces parameter blank it can take a while until all modules are indexed and presented in your browser. Be either patient or restrict the namespace to a sane subset of your modules.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.netcubed.de/2009/05/podbrowser-yet-another-pod-viewer/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
