Quote Originally Posted by hantu
I'd even be content with a good Query/Criteria implementation instead of HQL/OQL, yet OQL support would be a very cool and mighty feature.
The problems of defining query criteria at runtime are that they require query composition code in the runtime classes that only bloat your data object classes and they also prevent the evolution to a more efficient implementation of the queries using stored procedures.

Using an Object Query Language (OQL), you can use a compiler that generates optimized SQL queries at compile time. This way you take off the bloat of an eventual query criteria builder from the runtime classes and you can even have it generate stored procedures that can execute queries much faster as stored procedures are compiler by the database server at instalation time.

Metastorage uses this approach. It features its own OQL for defining object query filter criteria defined with a XML syntax, like everything else in CPML (Component Persistence Markup Language).

Below is an example from the sample CMS project that comes with Metastorage. The <filter> section defines an OQL expression. Once compiled, the getarticlesbytitleandauthor function takes runtime arguments author and title and executes an SQL query that retrieves all article objects that belong to a collection of articles of a category object that matches the given author and title names.

This is not a trivial criteria to define with simple query criteria building code as it envolves a many-to-many relationship, in this case between a category class and an article class.

Fortunately, Metastorage simplifies a lot the compilation of arbitrarily complex SQL queries. Furthermore, it generates very compact code that will run faster. In the case of this function for the category class, you may want to verify for yourself that it generates just a one liner function call. The compiled SQL criteria looks like this:

PHP Code:
'article_categories_category_articles.category_articles=' $this->id ' AND article_categories_category_articles.article_categories=article.id AND article.title=' quote($title) . ' AND author.id=article.author AND author.alias=' quote($author
One final comment regarding the objections that some people raised against code generation based solutions, keep in mind that there is code generation and code generation. This means that not all code generation tools are as imature as you may imagine. You need to check for yourselves the generated code before you take your own conclusions so you do not make the mistake that all code generation solutions produce inappropriate code.

You may recall that the history of PHP template engines could be basically divided in: before Smarty and after Smarty. After Smarty, many template engine developers realized that it was a brilliant idea to compile templates generating equivalent PHP code to produce the same output, as it would run much faster and efficient.

The same can be said about code generated from compiled OQL. Not to mention that using persistence layers generated by mature tools from an object model, drastically reduces your development time. This way you can concentrate more time in hand coding what is really specific about your applications, which are the business rules.

HTML Code:
   <class>
      <name>category</name>
    
    <variable>
  	 <name>name</name>
  	 <type>text</type>
     </variable>
    
     <variable>
  	  <name>description</name>
  	  <type>text</type>
     </variable>
    
       <collection>
    	 <name>articles</name>
    	  <class>article</class>
    	  <reference>categories</reference>
       </collection>
    
    	<function>
    	  <name>getarticlesbytitleandauthor</name>
    	  <type>getcollection</type>
    	  <argument>
  	     <name>title</name>
    	     <type>text</type>
    	  </argument>
    	  <argument>
    	     <name>author</name>
    	     <type>text</type>
    	  </argument>
    	  <parameters>
    		<collection>articles</collection>
    		<filter>
    			<variable>
    			   <name>title</name>
    			   <object>article</object>
    			</variable>
    		   <equalto />
    			<argument>title</argument>
    		   <and />
    		     <object>
    			  <name>author</name>
    			  <class>writer</class>
    			  </object>
    		   <equalto />
    			  <variable>
    			 <object>article</object>
    			 <name>author</name>
    			  </variable>
    		   <and />
    		     <variable>
    			  <object>author</object>
    			  <name>alias</name>
    			  </variable>
    		    <equalto />
    		     <argument>author</argument>
    		</filter>
    	   </parameters>
    	</function>
    
      </class>