<?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>woblog &#187; doctrine</title>
	<atom:link href="http://www.whiteoctober.co.uk/blog/tag/doctrine/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.whiteoctober.co.uk/blog</link>
	<description>great stuff about the web</description>
	<lastBuildDate>Mon, 05 Dec 2011 16:53:15 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Stored functions with Symfony and Doctrine</title>
		<link>http://www.whiteoctober.co.uk/blog/2011/01/05/stored-functions-with-symfony-and-doctrine/</link>
		<comments>http://www.whiteoctober.co.uk/blog/2011/01/05/stored-functions-with-symfony-and-doctrine/#comments</comments>
		<pubDate>Wed, 05 Jan 2011 09:17:12 +0000</pubDate>
		<dc:creator>Rich</dc:creator>
				<category><![CDATA[Web development]]></category>
		<category><![CDATA[doctrine]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://www.whiteoctober.co.uk/blog/?p=665</guid>
		<description><![CDATA[A Symfony project I’m working on currently requires a couple of MySQL stored functions to be available. In the interests of making the code I write reusable in future, some of it has been moved into a plugin, but this code relies on a couple of stored functions being available.]]></description>
			<content:encoded><![CDATA[<p>A <a href="http://www.symfony-project.org/">Symfony</a> project I&#8217;m working on currently requires a couple of <a href="http://www.mysql.com/">MySQL</a> stored functions to be available.  In the interests of making the code I write reusable in future, some of it has been moved into a plugin, but this code relies on a couple of stored functions being available.  As this code is also unit tested, I needed to make sure the stored functions were available on database drop-and-load which happens in the unit test bootstrap (via the <a href="http://www.doctrine-project.org/">Doctrine</a> tasks provided).</p>
<p>First of all, my stored functions are in separate .sql files in my plugin&#8217;s <code>data/sql/</code> directory in the interests of following convention within the project&#8217;s directory structure.</p>
<p>Secondly, in myPlugin/config/MyPluginConfiguration.class.php file, I have the following for the <code>initialize()</code> method.:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> initialize<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  sfConfig<span style="color: #339933;">::</span><span style="color: #004000;">set</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;zz_myplugin_dir&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getRootDir</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">dispatcher</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;command.post_command&quot;</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'initializeStoredFuncs'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>We listen for the <code>command.post_command</code> event which we can then check to see if it&#8217;s a Doctrine insert-sql task being run.  We also check to see if the function already exists before attempting to create it &#8211; if not, then carry on.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> static <span style="color: #000000; font-weight: bold;">function</span> initializeStoredFuncs<span style="color: #009900;">&#40;</span>sfEvent <span style="color: #000088;">$event</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  static <span style="color: #000088;">$doneConfig</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$doneConfig</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// Already done it.</span>
    <span style="color: #b1b100;">return</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$event</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getSubject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> instanceof sfDoctrineInsertSqlTask<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// Not inserting any SQL. No point continuing</span>
    <span style="color: #b1b100;">return</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// Get database connection</span>
  <span style="color: #000088;">$con</span> <span style="color: #339933;">=</span> Doctrine_Manager<span style="color: #339933;">::</span><span style="color: #004000;">connection</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// Configure function 1</span>
  <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">addStoredRoutine</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$con</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;myFuncName1&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;myFuncName1.sql&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// Configure function 2</span>
  <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">addStoredRoutine</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$con</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;someOtherFunc&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;someOtherFunc.sql&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// Set config completed flag for later</span>
  <span style="color: #000088;">$doneConfig</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
* Adds a stored procedure into the database
*
* @param string $con Connection to use
* @param string $routineName Routine name
* @param string $routineFile Filename inside our [plugin dir]/data/sql/
*/</span>
protected static <span style="color: #000000; font-weight: bold;">function</span> addStoredRoutine<span style="color: #009900;">&#40;</span><span style="color: #000088;">$con</span><span style="color: #339933;">,</span> <span style="color: #000088;">$routineName</span><span style="color: #339933;">,</span> <span style="color: #000088;">$routineFile</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #000088;">$options</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$con</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getOptions</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$dsn</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$options</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;dsn&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
  <span style="color: #990000;">preg_match</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/dbname=([^;]+)[;]?/&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$dsn</span><span style="color: #339933;">,</span> <span style="color: #000088;">$matches</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$dbname</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$matches</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000088;">$sql</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;SELECT COUNT(*) AS c FROM information_schema.routines WHERE routine_name = '<span style="color: #006699; font-weight: bold;">{$routineName}</span>' AND routine_schema = '<span style="color: #006699; font-weight: bold;">{$dbname}</span>'&quot;</span><span style="color: #339933;">;</span>
  try
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$dbh</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$con</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getDbh</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  catch <span style="color: #009900;">&#40;</span>Exception <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// No database available - can't carry on</span>
    <span style="color: #b1b100;">return</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000088;">$resultSet</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$dbh</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$sql</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$results</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$resultSet</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">fetch</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$results</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;c&quot;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// Create the function</span>
    <span style="color: #000088;">$sqlRoutine</span> <span style="color: #339933;">=</span> <span style="color: #990000;">file_get_contents</span><span style="color: #009900;">&#40;</span>sfConfig<span style="color: #339933;">::</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;zz_myplugin_dir&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;/data/sql/&quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$routineFile</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$con</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getDbh</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$sqlRoutine</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>I&#8217;m not a massive fan of the way the database name has been retrieved but it works for now :-) I&#8217;m pretty sure there&#8217;s a neater way of accomplishing the above too, but this is working consistently and allows the stored functions to become part of a plugin, so that if the plugin is removed at a later date, then any subsequent database builds will not have unnecessary routines hanging around.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.whiteoctober.co.uk/blog/2011/01/05/stored-functions-with-symfony-and-doctrine/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Don&#8217;t be afraid to NOT use the ORM&#8230;</title>
		<link>http://www.whiteoctober.co.uk/blog/2009/10/16/dont-be-afraid-to-not-use-the-or/</link>
		<comments>http://www.whiteoctober.co.uk/blog/2009/10/16/dont-be-afraid-to-not-use-the-or/#comments</comments>
		<pubDate>Fri, 16 Oct 2009 15:06:03 +0000</pubDate>
		<dc:creator>Rich</dc:creator>
				<category><![CDATA[Web development]]></category>
		<category><![CDATA[Web technologies]]></category>
		<category><![CDATA[doctrine]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://www.whiteoctober.co.uk/blog/?p=353</guid>
		<description><![CDATA[I&#8217;ve been racking my brains the past couple of days with a Doctrine issue within a Symfony project. I was constructing a bank statement-esque page, which iterated over a &#8220;StatementEntry&#8221; table and displayed the results. Entries could either be of model Type A or model Type B, with the relevant model ID stored in the [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been racking my brains the past couple of days with a <a title="Doctrine" href="http://www.doctrine-project.org/">Doctrine</a> issue within a <a title="Symfony" href="http://www.symfony-project.org/">Symfony</a> project.  I was constructing a bank statement-esque page, which iterated over a &#8220;StatementEntry&#8221; table and displayed the results.  Entries could either be of model Type A or model Type B, with the relevant model ID stored in the StatementEntry table.  The relationship was defined by a &#8220;type&#8221; column.  Type A and B models also had other relationships after the initial one.</p>
<p>The problem I discovered was that obviously Doctrine didn&#8217;t know what the conditional relationships were, since it was dependant on the type column.  I researched some different approaches:</p>
<ol>
<li> <strong>Doctrine&#8217;s RawSql</strong>
<p>This approach worked for generating the correct SQL query without a problem, but the issue then arose of how Doctrine could hydrate the result set.  Answer was &#8211; it couldn&#8217;t :-) Well, I lie &#8211; I could use Doctrine::HYDRATE_SCALAR but I had issues with other related models, where I was joining to a table twice but under different aliases, which failed, since the scalar hydration would override earlier joins on the same table.</li>
<li> <strong>Column aggregation</strong>
<p>Column aggregation looked great initially &#8211; I could have a &#8220;TypeAEntry&#8221; and a &#8220;TypeBEntry&#8221;, and Doctrine would have handled the typing of the Entry automatically.  I couldn&#8217;t however see a way to query &#8220;in reverse&#8221; &#8211; get all Entries and their associated models.</li>
<li> <strong>Write a raw SQL query, and use Doctrine&#8217;s PDO instance to retrieve the data.</strong></li>
</ol>
<p>Option 3) was the one I settled for in the end.  It meant of course that I had to specify column names, and perform all the joins myself, but it did mean I could specify precisely what data I wanted back.  This came back in the form of a normal array.  I&#8217;d tried to stay away from this option intially, but after spending too long researching the other 2 and hitting brick walls, I bit the bullet and dropped down to the raw stuff.  And hey presto!</p>
<p>Note &#8211; this approach will only work if you want the data to be read-only.  If you want to then use Doctrine&#8217;s model goodness, you&#8217;ll need to work out how to transform that *back* into a model.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.whiteoctober.co.uk/blog/2009/10/16/dont-be-afraid-to-not-use-the-or/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

