1
0
mirror of synced 2025-01-29 19:41:45 +03:00

Preliminary support for DQL aggregate value selecting

This commit is contained in:
zYne 2006-08-25 18:17:20 +00:00
parent f547396124
commit d283fbf1c7
5 changed files with 134 additions and 36 deletions

View File

@ -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)

View File

@ -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];
}
}
}
?>

View File

@ -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();

View File

@ -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";

View File

@ -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 {