DQL - SQL conversion LIMIT clause parsing examples added
This commit is contained in:
parent
45bca0358a
commit
8755e5ab50
@ -50,6 +50,7 @@ class Doctrine_Form implements Iterator {
|
||||
} else {
|
||||
$elements[$column] = "<textarea name='data[$column]' cols=80 rows=25>".$this->record->get($column)."</textarea>\n";
|
||||
}
|
||||
|
||||
}
|
||||
return $elements[$column];
|
||||
} else {
|
||||
|
@ -24,7 +24,7 @@ DQL QUERY: FROM User(id) WHERE User.Group.Phonenumber.phonenumber LIKE '123 123'
|
||||
SQL QUERY: SELECT entity.id AS entity__id FROM entity LEFT JOIN groupuser ON entity.id = groupuser.user_id LEFT JOIN entity AS entity2 ON entity2.id = groupuser.group_id LEFT JOIN phonenumber ON entity2.id = phonenumber.entity_id WHERE phonenumber.phonenumber LIKE '123 123' AND (entity.type = 0 AND (entity2.type = 1 OR entity2.type IS NULL))
|
||||
";
|
||||
|
||||
|
||||
function renderQueries($str) {
|
||||
$e = explode("\n",$str);
|
||||
$color = "367FAC";
|
||||
|
||||
@ -37,16 +37,50 @@ foreach($e as $line) {
|
||||
$l = str_replace("SELECT","<br \><font color='$color'><b>SELECT</b></font>",$line);
|
||||
$l = str_replace("FROM","<br \><font color='$color'><b>FROM</b></font>",$l);
|
||||
$l = str_replace("LEFT JOIN","<br \><font color='$color'><b>LEFT JOIN</b></font>",$l);
|
||||
$l = str_replace("INNER JOIN","<br \><font color='$color'><b>INNER JOIN</b></font>",$l);
|
||||
$l = str_replace("WHERE","<br \><font color='$color'><b>WHERE</b></font>",$l);
|
||||
$l = str_replace("AS","<font color='$color'><b>AS</b></font>",$l);
|
||||
$l = str_replace("ON","<font color='$color'><b>ON</b></font>",$l);
|
||||
$l = str_replace("ORDER BY","<font color='$color'><b>ORDER BY</b></font>",$l);
|
||||
$l = str_replace("LIMIT","<font color='$color'><b>LIMIT</b></font>",$l);
|
||||
$l = str_replace("OFFSET","<font color='$color'><b>OFFSET</b></font>",$l);
|
||||
$l = str_replace("DISTINCT","<font color='$color'><b>DISTINCT</b></font>",$l);
|
||||
$l = str_replace(" ","<dd>",$l);
|
||||
if(substr($l,0,3) == "DQL") print "<hr valign='left' class='small'>";
|
||||
|
||||
print $l."<br>";
|
||||
|
||||
if(substr($l,0,3) == "SQL") print "<hr valign='left' class='small'>";
|
||||
}
|
||||
|
||||
}
|
||||
renderQueries($str);
|
||||
?>
|
||||
Propably the most complex feature DQL parser has to offer is its LIMIT clause parser. In pure
|
||||
sql the limit clause limits the number of rows returned. So for example when fetching users and their
|
||||
phonenumbers using limit 20 you might get anything between 1-20 users, since the first user might have 20 phonenumbers and
|
||||
hence the record set would consist of 20 rows.
|
||||
<br \><br \>
|
||||
DQL overcomes this problem with subqueries and with complex but efficient subquery analysis. In the next example
|
||||
we are going to fetch first 20 users and all their phonenumbers with single efficient query. Notice how the DQL parser is smart enough
|
||||
to use column aggregation inheritance even in the subquery.
|
||||
<br \><br \>
|
||||
<?php
|
||||
$str = "
|
||||
DQL QUERY: FROM User.Phonenumber LIMIT 20
|
||||
|
||||
SQL QUERY: SELECT entity.id AS entity__id, phonenumber.id AS phonenumber__id, phonenumber.phonenumber AS phonenumber__phonenumber, phonenumber.entity_id AS phonenumber__entity_id FROM entity LEFT JOIN phonenumber ON entity.id = phonenumber.entity_id WHERE entity.id IN (SELECT DISTINCT entity.id FROM entity WHERE (entity.type = 0) LIMIT 20) AND (entity.type = 0)
|
||||
";
|
||||
renderQueries($str);
|
||||
?>
|
||||
In the next example
|
||||
we are going to fetch first 20 users and all their phonenumbers and only those users that actually have phonenumbers (hence the usage of colon operator = INNER JOIN) with single efficient query.
|
||||
Notice how the DQL parser is smart enough to use the INNER JOIN in the subquery.
|
||||
<br \>
|
||||
<?php
|
||||
$str = "
|
||||
DQL QUERY: FROM User:Phonenumber LIMIT 20
|
||||
|
||||
SQL QUERY: SELECT entity.id AS entity__id, phonenumber.id AS phonenumber__id, phonenumber.phonenumber AS phonenumber__phonenumber, phonenumber.entity_id AS phonenumber__entity_id FROM entity INNER JOIN phonenumber ON entity.id = phonenumber.entity_id WHERE entity.id IN (SELECT DISTINCT entity.id FROM entity INNER JOIN phonenumber ON entity.id = phonenumber.entity_id WHERE (entity.type = 0) LIMIT 20) AND (entity.type = 0)
|
||||
";
|
||||
renderQueries($str);
|
||||
?>
|
||||
|
||||
|
||||
|
@ -166,12 +166,13 @@ $menu = array("Getting started" =>
|
||||
"Using SQL",
|
||||
"Adding components",
|
||||
"Method overloading"),
|
||||
/**
|
||||
"Statement - <font color='red'>UNDER CONSTRUCTION</font>" => array("Introduction",
|
||||
"Setting parameters",
|
||||
"Getting parameters",
|
||||
"Getting row count",
|
||||
"Executing the statement"),
|
||||
|
||||
*/
|
||||
"Exceptions" => array(
|
||||
"Overview",
|
||||
"List of exceptions"
|
||||
|
@ -76,6 +76,7 @@ class Doctrine_Query_Limit_TestCase extends Doctrine_UnitTestCase {
|
||||
$this->query->from("User(id):Phonenumber");
|
||||
$this->query->limit(5);
|
||||
|
||||
|
||||
$sql = $this->query->getQuery();
|
||||
|
||||
$users = $this->query->execute();
|
||||
|
Loading…
x
Reference in New Issue
Block a user