Preliminary support for DQL aggregate value selecting
This commit is contained in:
parent
f547396124
commit
d283fbf1c7
@ -30,37 +30,39 @@ Doctrine::autoload('Doctrine_Access');
|
||||
*/
|
||||
abstract class Doctrine_Hydrate extends Doctrine_Access {
|
||||
/**
|
||||
* @var array $fetchmodes an array containing all fetchmodes
|
||||
* @var array $fetchmodes an array containing all fetchmodes
|
||||
*/
|
||||
protected $fetchModes = array();
|
||||
/**
|
||||
* @var array $tables an array containing all the tables used in the query
|
||||
* @var array $tables an array containing all the tables used in the query
|
||||
*/
|
||||
protected $tables = array();
|
||||
/**
|
||||
* @var array $collections an array containing all collections this parser has created/will create
|
||||
* @var array $collections an array containing all collections this parser has created/will create
|
||||
*/
|
||||
protected $collections = array();
|
||||
/**
|
||||
* @var array $joins an array containing all table joins
|
||||
* @var array $joins an array containing all table joins
|
||||
*/
|
||||
protected $joins = array();
|
||||
/**
|
||||
* @var array $data fetched data
|
||||
* @var array $data fetched data
|
||||
*/
|
||||
protected $data = array();
|
||||
/**
|
||||
* @var Doctrine_Connection $connection Doctrine_Connection object
|
||||
* @var Doctrine_Connection $connection Doctrine_Connection object
|
||||
*/
|
||||
protected $connection;
|
||||
/**
|
||||
* @var Doctrine_View $view Doctrine_View object
|
||||
* @var Doctrine_View $view Doctrine_View object
|
||||
*/
|
||||
protected $view;
|
||||
|
||||
|
||||
protected $inheritanceApplied = false;
|
||||
|
||||
/**
|
||||
* @var boolean $aggregate
|
||||
*/
|
||||
protected $aggregate = false;
|
||||
/**
|
||||
* @var array $tableAliases
|
||||
@ -245,7 +247,13 @@ abstract class Doctrine_Hydrate extends Doctrine_Access {
|
||||
else
|
||||
$query = $this->view->getSelectSql();
|
||||
|
||||
if($this->isLimitSubqueryUsed())
|
||||
$params = array_merge($params, $params);
|
||||
|
||||
$stmt = $this->connection->execute($query,$params);
|
||||
|
||||
if($this->aggregate)
|
||||
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
switch(count($this->tables)):
|
||||
case 0:
|
||||
@ -257,8 +265,6 @@ abstract class Doctrine_Hydrate extends Doctrine_Access {
|
||||
$name = $this->tables[$keys[0]]->getComponentName();
|
||||
|
||||
|
||||
$stmt = $this->connection->execute($query,$params);
|
||||
|
||||
while($data = $stmt->fetch(PDO::FETCH_ASSOC)):
|
||||
|
||||
foreach($data as $key => $value):
|
||||
@ -280,21 +286,19 @@ abstract class Doctrine_Hydrate extends Doctrine_Access {
|
||||
default:
|
||||
$keys = array_keys($this->tables);
|
||||
$root = $keys[0];
|
||||
|
||||
if($this->isLimitSubqueryUsed())
|
||||
$params = array_merge($params, $params);
|
||||
|
||||
|
||||
|
||||
$stmt = $this->connection->execute($query,$params);
|
||||
|
||||
$previd = array();
|
||||
|
||||
$coll = $this->getCollection($root);
|
||||
$prev[$root] = $coll;
|
||||
|
||||
|
||||
if($this->aggregate)
|
||||
$return = Doctrine::FETCH_ARRAY;
|
||||
|
||||
$array = $this->parseData($stmt);
|
||||
|
||||
|
||||
if($return == Doctrine::FETCH_VHOLDER) {
|
||||
return $this->hydrateHolders($array);
|
||||
} elseif($return == Doctrine::FETCH_ARRAY)
|
||||
|
@ -532,7 +532,19 @@ class Doctrine_Query extends Doctrine_Hydrate {
|
||||
}
|
||||
return $term;
|
||||
}
|
||||
|
||||
/**
|
||||
* sqlExplode
|
||||
*
|
||||
* explodes a string into array using custom brackets and
|
||||
* quote delimeters
|
||||
*
|
||||
* @param string $str
|
||||
* @param string $d the delimeter which explodes the string
|
||||
* @param string $e1 the first bracket, usually '('
|
||||
* @param string $e2 the second bracket, usually ')'
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function sqlExplode($str,$d = " ",$e1 = '(',$e2 = ')') {
|
||||
$str = explode("$d",$str);
|
||||
$i = 0;
|
||||
@ -724,7 +736,7 @@ class Doctrine_Query extends Doctrine_Hydrate {
|
||||
* @param string $currPath
|
||||
* @return void
|
||||
*/
|
||||
final public function parseFields($fullName, $tableName, $exploded, $currPath) {
|
||||
final public function parseFields($fullName, $tableName, array $exploded, $currPath) {
|
||||
$table = $this->tables[$tableName];
|
||||
|
||||
$fields = array();
|
||||
@ -732,20 +744,71 @@ class Doctrine_Query extends Doctrine_Hydrate {
|
||||
if(strpos($fullName, "-") === false) {
|
||||
$fetchmode = $table->getAttribute(Doctrine::ATTR_FETCHMODE);
|
||||
|
||||
if(isset($exploded[1]))
|
||||
$fields = explode(",",substr($exploded[1],0,-1));
|
||||
if(isset($exploded[1])) {
|
||||
if(count($exploded) > 2) {
|
||||
$fields = $this->parseAggregateValues($fullName, $tableName, $exploded, $currPath);
|
||||
} elseif(count($exploded) == 2) {
|
||||
$fields = explode(",",substr($exploded[1],0,-1));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(isset($exploded[1])) {
|
||||
$fetchmode = $this->parseFetchMode($exploded[1]);
|
||||
} else
|
||||
$fetchmode = $table->getAttribute(Doctrine::ATTR_FETCHMODE);
|
||||
|
||||
} else {
|
||||
if(isset($exploded[1])) {
|
||||
$fetchmode = $this->parseFetchMode($exploded[1]);
|
||||
} else
|
||||
$fetchmode = $table->getAttribute(Doctrine::ATTR_FETCHMODE);
|
||||
if(isset($exploded[2])) {
|
||||
if(substr_count($exploded[2], ")") > 1) {
|
||||
|
||||
if(isset($exploded[2]))
|
||||
} else {
|
||||
$fields = explode(",",substr($exploded[2],0,-1));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if( ! $this->aggregate)
|
||||
$this->loadFields($table, $fetchmode, $fields, $currPath);
|
||||
}
|
||||
public function parseAggregateFunction($func,$reference) {
|
||||
$pos = strpos($func,"(");
|
||||
|
||||
if($pos !== false) {
|
||||
$funcs = array();
|
||||
|
||||
$name = substr($func, 0, $pos);
|
||||
$func = substr($func, ($pos + 1), -1);
|
||||
$params = Doctrine_Query::bracketExplode($func, ",", "(", ")");
|
||||
|
||||
foreach($params as $k => $param) {
|
||||
$params[$k] = $this->parseAggregateFunction($param,$reference);
|
||||
}
|
||||
|
||||
$funcs = $name."(".implode(", ", $params).")";
|
||||
|
||||
return $funcs;
|
||||
|
||||
} else {
|
||||
if( ! is_numeric($func)) {
|
||||
|
||||
$func = $this->getTableAlias($reference).".".$func;
|
||||
|
||||
return $func;
|
||||
} else {
|
||||
return $func;
|
||||
}
|
||||
}
|
||||
}
|
||||
final public function parseAggregateValues($fullName, $tableName, array $exploded, $currPath) {
|
||||
$this->aggregate = true;
|
||||
$pos = strpos($fullName,"(");
|
||||
$name = substr($fullName, 0, $pos);
|
||||
$string = substr($fullName, ($pos + 1), -1);
|
||||
|
||||
$exploded = Doctrine_Query::bracketExplode($string, ',');
|
||||
foreach($exploded as $k => $value) {
|
||||
$exploded[$k] = $this->parseAggregateFunction($value, $currPath);
|
||||
$this->parts["select"][] = $exploded[$k];
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
@ -24,16 +24,37 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase {
|
||||
parent::prepareTables();
|
||||
|
||||
}
|
||||
/**
|
||||
public function testQueryPart() {
|
||||
$this->query->from[] = "User.Phonenumber";
|
||||
$this->query->from[] = "User.Email";
|
||||
public function testSelectingAggregateValues() {
|
||||
$q = new Doctrine_Query();
|
||||
$q->from("User(COUNT(1), MAX(name))");
|
||||
$array = $q->execute();
|
||||
$this->assertTrue(is_array($array));
|
||||
$this->assertEqual($array, array(array('COUNT(1)' => '8', 'MAX(entity.name)' => 'zYne')));
|
||||
$this->assertEqual($q->getQuery(), "SELECT COUNT(1), MAX(entity.name) FROM entity WHERE (entity.type = 0)");
|
||||
|
||||
$q = new Doctrine_Query();
|
||||
$q->from("Phonenumber(COUNT(1))");
|
||||
|
||||
$array = $q->execute();
|
||||
$this->assertTrue(is_array($array));
|
||||
$this->assertEqual($array, array(array('COUNT(1)' => '15')));
|
||||
$this->assertEqual($q->getQuery(), "SELECT COUNT(1) FROM phonenumber");
|
||||
|
||||
$q = new Doctrine_Query();
|
||||
$q->from("User.Phonenumber(COUNT(id))");
|
||||
$array = $q->execute();
|
||||
$this->assertTrue(is_array($array));
|
||||
|
||||
$this->assertEqual($array[0]['COUNT(phonenumber.id)'], 14);
|
||||
$this->assertEqual($q->getQuery(), "SELECT entity.id AS entity__id, entity.name AS entity__name, entity.loginname AS entity__loginname, entity.password AS entity__password, entity.type AS entity__type, entity.created AS entity__created, entity.updated AS entity__updated, entity.email_id AS entity__email_id, COUNT(phonenumber.id) FROM entity LEFT JOIN phonenumber ON entity.id = phonenumber.entity_id WHERE (entity.type = 0)");
|
||||
|
||||
$q = new Doctrine_Query();
|
||||
$q->from("User(MAX(id)).Email(MIN(address))");
|
||||
$array = $q->execute();
|
||||
$this->assertTrue(is_array($array));
|
||||
|
||||
$users = $this->query->execute();
|
||||
|
||||
$this->assertEqual($users->count(), 8);
|
||||
}
|
||||
*/
|
||||
|
||||
public function testMultipleFetching() {
|
||||
$count = $this->dbh->count();
|
||||
|
@ -93,7 +93,13 @@ class Doctrine_RecordTestCase extends Doctrine_UnitTestCase {
|
||||
|
||||
$this->assertEqual($coll->count(), 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function testDateTimeType() {
|
||||
$date = new DateTest();
|
||||
|
||||
|
||||
}
|
||||
public function testEnumType() {
|
||||
$enum = new EnumTest();
|
||||
$enum->status = "open";
|
||||
|
@ -386,7 +386,11 @@ class Validator_Test extends Doctrine_Record {
|
||||
$this->hasColumn("myemail2", "string", 100, "email|notblank");
|
||||
}
|
||||
}
|
||||
|
||||
class DateTest extends Doctrine_Record {
|
||||
public function setTableDefinition() {
|
||||
$this->hasColumn("date", "date", 20);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Tag extends Doctrine_Record {
|
||||
|
Loading…
x
Reference in New Issue
Block a user