Commit 143b2749 authored by doctrine's avatar doctrine

Query parser refactoring

parent cff3c430
...@@ -246,6 +246,7 @@ final class Doctrine { ...@@ -246,6 +246,7 @@ final class Doctrine {
case "Sensei": case "Sensei":
case "Iterator": case "Iterator":
case "View": case "View":
case "Query":
$a[] = $path.DIRECTORY_SEPARATOR.$entry; $a[] = $path.DIRECTORY_SEPARATOR.$entry;
break; break;
default: default:
......
...@@ -5,7 +5,7 @@ class Doctrine_Cache_Query_Sqlite implements Countable { ...@@ -5,7 +5,7 @@ class Doctrine_Cache_Query_Sqlite implements Countable {
*/ */
const CACHE_TABLE = 'doctrine_query_cache'; const CACHE_TABLE = 'doctrine_query_cache';
/** /**
* @var Doctrine_Table $table the table object this cache container belongs to * @var Doctrine_Session $session the table object this cache container belongs to
*/ */
private $table; private $table;
/** /**
...@@ -21,19 +21,19 @@ class Doctrine_Cache_Query_Sqlite implements Countable { ...@@ -21,19 +21,19 @@ class Doctrine_Cache_Query_Sqlite implements Countable {
* *
* Doctrine_Table $table * Doctrine_Table $table
*/ */
public function __construct(Doctrine_Table $table) { public function __construct(Doctrine_Session $session) {
$this->table = $table; $this->session = $session;
$dir = $this->table->getSession()->getAttribute(Doctrine::ATTR_CACHE_DIR); $dir = $session->getAttribute(Doctrine::ATTR_CACHE_DIR);
if( ! is_dir($dir)) if( ! is_dir($dir))
mkdir($dir, 0777); mkdir($dir, 0777);
$this->path = $dir.DIRECTORY_SEPARATOR; $this->path = $dir.DIRECTORY_SEPARATOR;
$this->dbh = $this->table->getSession()->getCacheHandler();
$this->dbh = new PDO("sqlite::memory:"); $this->dbh = new PDO("sqlite::memory:");
try { try {
if($this->table->getAttribute(Doctrine::ATTR_CREATE_TABLES) === true) if($this->session->getAttribute(Doctrine::ATTR_CREATE_TABLES) === true)
{ {
$columns = array(); $columns = array();
$columns['query_md5'] = array('string', 32, 'notnull'); $columns['query_md5'] = array('string', 32, 'notnull');
......
...@@ -131,7 +131,9 @@ class Doctrine_Lib { ...@@ -131,7 +131,9 @@ class Doctrine_Lib {
$l = str_replace("SELECT","<font color='$color'><b>SELECT</b></font><br \> ",$l); $l = str_replace("SELECT","<font color='$color'><b>SELECT</b></font><br \> ",$l);
$l = str_replace("FROM","<font color='$color'><b>FROM</b></font><br \>",$l); $l = str_replace("FROM","<font color='$color'><b>FROM</b></font><br \>",$l);
$l = str_replace("LEFT JOIN","<br \><font color='$color'><b>LEFT JOIN</b></font>",$l); $l = str_replace("LEFT JOIN","<br \><font color='$color'><b>LEFT JOIN</b></font>",$l);
$l = str_replace("WHERE","<font color='$color'><b>WHERE</b></font>",$l); $l = str_replace("WHERE","<br \><font color='$color'><b>WHERE</b></font>",$l);
$l = str_replace("GROUP BY","<br \><font color='$color'><b>GROUP BY</b></font>",$l);
$l = str_replace("HAVING","<br \><font color='$color'><b>HAVING</b></font>",$l);
$l = str_replace("AS","<font color='$color'><b>AS</b></font><br \> ",$l); $l = str_replace("AS","<font color='$color'><b>AS</b></font><br \> ",$l);
$l = str_replace("ON","<font color='$color'><b>ON</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><br \>",$l); $l = str_replace("ORDER BY","<font color='$color'><b>ORDER BY</b></font><br \>",$l);
......
...@@ -127,8 +127,9 @@ class Doctrine_Query extends Doctrine_Access { ...@@ -127,8 +127,9 @@ class Doctrine_Query extends Doctrine_Access {
$this->aggregate = false; $this->aggregate = false;
$this->data = array(); $this->data = array();
$this->collections = array(); $this->collections = array();
$this->joined = array();
$this->joins = array(); $this->joins = array();
$this->tableIndexes = array();
$this->tableAliases = array();
} }
/** /**
* loadFields * loadFields
...@@ -192,9 +193,29 @@ class Doctrine_Query extends Doctrine_Access { ...@@ -192,9 +193,29 @@ class Doctrine_Query extends Doctrine_Access {
if(isset($this->parts[$name])) { if(isset($this->parts[$name])) {
$method = "parse".ucwords($name); $method = "parse".ucwords($name);
switch($name): switch($name):
case "from":
$this->parts['from'] = array();
$this->parts['columns'] = array();
$this->parts['join'] = array();
$this->joins = array();
$this->tables = array();
$this->fetchModes = array();
$this->tableIndexes = array();
$this->tableAliases = array();
$class = "Doctrine_Query_".ucwords($name);
$parser = new $class($this);
$parser->parse($args[0]);
break;
case "where": case "where":
case "having": case "having":
$this->parts[$name] = array($this->$method($args[0])); case "orderby":
case "groupby":
$class = "Doctrine_Query_".ucwords($name);
$parser = new $class($this);
$this->parts[$name] = array($parser->parse($args[0]));
break; break;
case "limit": case "limit":
case "offset": case "offset":
...@@ -203,14 +224,6 @@ class Doctrine_Query extends Doctrine_Access { ...@@ -203,14 +224,6 @@ class Doctrine_Query extends Doctrine_Access {
$this->parts[$name] = $args[0]; $this->parts[$name] = $args[0];
break; break;
case "from":
$this->parts['columns'] = array();
$this->parts['join'] = array();
$this->joins = array();
$this->tables = array();
$this->fetchModes = array();
$this->tableIndexes = array();
$this->tableAliases = array();
default: default:
$this->parts[$name] = array(); $this->parts[$name] = array();
$this->$method($args[0]); $this->$method($args[0]);
...@@ -308,14 +321,9 @@ class Doctrine_Query extends Doctrine_Access { ...@@ -308,14 +321,9 @@ class Doctrine_Query extends Doctrine_Access {
} }
if( ! empty($this->parts["groupby"])) $q .= ( ! empty($this->parts['groupby']))?" GROUP BY ".implode(", ",$this->parts["groupby"]):'';
$q .= " GROUP BY ".implode(", ",$this->parts["groupby"]); $q .= ( ! empty($this->parts['having']))?" HAVING ".implode(" ",$this->parts["having"]):'';
$q .= ( ! empty($this->parts['orderby']))?" ORDER BY ".implode(" ",$this->parts["orderby"]):'';
if( ! empty($this->parts["having"]))
$q .= " HAVING ".implode(" ",$this->parts["having"]);
if( ! empty($this->parts["orderby"]))
$q .= " ORDER BY ".implode(", ",$this->parts["orderby"]);
if( ! empty($this->parts["limit"]) || ! empty($this->offset)) if( ! empty($this->parts["limit"]) || ! empty($this->offset))
$q = $this->session->modifyLimitQuery($q,$this->parts["limit"],$this->offset); $q = $this->session->modifyLimitQuery($q,$this->parts["limit"],$this->offset);
...@@ -362,36 +370,6 @@ class Doctrine_Query extends Doctrine_Access { ...@@ -362,36 +370,6 @@ class Doctrine_Query extends Doctrine_Access {
return $str; return $str;
} }
/**
* @param string $where
* @return boolean
*/
final public function addWhere($where) {
if(empty($where))
return false;
if($this->parts["where"]) {
$this->parts["where"][] = "AND (".$where.")";
} else {
$this->parts["where"][] = "(".$where.")";
}
return true;
}
/**
* @param string $having
* @return boolean
*/
final public function addHaving($having) {
if(empty($having))
return false;
if($this->parts["having"]) {
$this->parts["having"][] = "AND (".$having.")";
} else {
$this->parts["having"][] = "(".$having.")";
}
return true;
}
/** /**
* getData * getData
* @param $key the component name * @param $key the component name
...@@ -695,15 +673,18 @@ class Doctrine_Query extends Doctrine_Access { ...@@ -695,15 +673,18 @@ class Doctrine_Query extends Doctrine_Access {
case "where": case "where":
case "limit": case "limit":
case "offset": case "offset":
case "having":
$p = $part; $p = $part;
$parts[$part] = array(); $parts[$part] = array();
break; break;
case "order": case "order":
case "group":
$i = ($k + 1);
if(isset($e[$i]) && strtolower($e[$i]) === "by") {
$p = $part; $p = $part;
$i = $k+1;
if(isset($e[$i]) && strtolower($e[$i]) == "by") {
$parts[$part] = array(); $parts[$part] = array();
} } else
$parts[$p][] = $part;
break; break;
case "by": case "by":
continue; continue;
...@@ -719,13 +700,21 @@ class Doctrine_Query extends Doctrine_Access { ...@@ -719,13 +700,21 @@ class Doctrine_Query extends Doctrine_Access {
$this->parseSelect($part); $this->parseSelect($part);
break; break;
case "FROM": case "FROM":
$this->parseFrom($part);
break; $class = "Doctrine_Query_".ucwords(strtolower($k));
case "WHERE": $parser = new $class($this);
$this->addWhere($this->parseWhere($part)); $parser->parse($part);
break; break;
case "GROUP":
case "ORDER": case "ORDER":
$this->parseOrderBy($part); $k .= "by";
case "WHERE":
case "HAVING":
$class = "Doctrine_Query_".ucwords(strtolower($k));
$parser = new $class($this);
$name = strtolower($k);
$this->parts[$name][] = $parser->parse($part);
break; break;
case "LIMIT": case "LIMIT":
$this->parts["limit"] = trim($part); $this->parts["limit"] = trim($part);
...@@ -743,86 +732,9 @@ class Doctrine_Query extends Doctrine_Access { ...@@ -743,86 +732,9 @@ class Doctrine_Query extends Doctrine_Access {
* @param string $str * @param string $str
* @return void * @return void
*/ */
private function parseOrderBy($str) { final public function parseOrderBy($str) {
foreach(explode(",",trim($str)) as $r) { $parser = new Doctrine_Query_Part_Orderby($this);
$r = trim($r); return $parser->parse($str);
$e = explode(" ",$r);
$a = explode(".",$e[0]);
if(count($a) > 1) {
$field = array_pop($a);
$reference = implode(".",$a);
$name = end($a);
$this->load($reference, false);
$alias = $this->tableAliases[$reference];
$tname = $this->tables[$alias]->getTableName();
$r = $tname.".".$field;
if(isset($e[1]))
$r .= " ".$e[1];
}
$this->parts["orderby"][] = $r;
}
}
/**
* DQL SELECT PARSER
* parses the select part of the query string
*
* @param string $str
* @return void
*/
private function parseSelect($str) {
$this->aggregate = true;
foreach(explode(",",trim($str)) as $reference) {
$e = explode(" AS ",trim($reference));
$f = explode("(",$e[0]);
$a = explode(".",$f[1]);
$field = substr(array_pop($a),0,-1);
$reference = trim(implode(".",$a));
$objTable = $this->load($reference);
if(isset($e[1]))
$s = " AS $e[1]";
$this->parts["columns"][] = $f[0]."(".$objTable->getTableName().".$field)$s";
}
}
/**
* DQL GROUP BY PARSER
* parses the group by part of the query string
* @param string $str
* @return void
*/
private function parseGroupBy($str) {
foreach(explode(",", $str) as $reference) {
$reference = trim($reference);
$e = explode(".",$reference);
$field = array_pop($e);
$table = $this->load(implode(".",$e));
$component = $table->getComponentName();
$this->parts["groupby"][] = $this->tableAliases[$component].".".$field;
}
}
/**
* DQL FROM PARSER
* parses the from part of the query string
* @param string $str
* @return void
*/
private function parseFrom($str) {
foreach(self::bracketExplode(trim($str),",", "(",")") as $reference) {
$reference = trim($reference);
$a = explode(".",$reference);
$field = array_pop($a);
$table = $this->load($reference);
}
} }
/** /**
* returns Doctrine::FETCH_* constant * returns Doctrine::FETCH_* constant
...@@ -830,7 +742,7 @@ class Doctrine_Query extends Doctrine_Access { ...@@ -830,7 +742,7 @@ class Doctrine_Query extends Doctrine_Access {
* @param string $mode * @param string $mode
* @return integer * @return integer
*/ */
private function parseFetchMode($mode) { final public function parseFetchMode($mode) {
switch(strtolower($mode)): switch(strtolower($mode)):
case "i": case "i":
case "immediate": case "immediate":
...@@ -856,74 +768,6 @@ class Doctrine_Query extends Doctrine_Access { ...@@ -856,74 +768,6 @@ class Doctrine_Query extends Doctrine_Access {
endswitch; endswitch;
return $fetchmode; return $fetchmode;
} }
/**
* DQL CONDITION PARSER
* parses the where/having part of the query string
*
*
* @param string $str
* @return string
*/
private function parseCondition($str, $type = 'Where') {
$tmp = trim($str);
$str = self::bracketTrim($tmp,"(",")");
$brackets = false;
$loadMethod = "load".$type;
while($tmp != $str) {
$brackets = true;
$tmp = $str;
$str = self::bracketTrim($str,"(",")");
}
$parts = self::bracketExplode($str," && ","(",")");
if(count($parts) > 1) {
$ret = array();
foreach($parts as $part) {
$ret[] = $this->parseCondition($part, $type);
}
$r = implode(" AND ",$ret);
} else {
$parts = self::bracketExplode($str," || ","(",")");
if(count($parts) > 1) {
$ret = array();
foreach($parts as $part) {
$ret[] = $this->parseCondition($part, $type);
}
$r = implode(" OR ",$ret);
} else {
return $this->$loadMethod($parts[0]);
}
}
if($brackets)
return "(".$r.")";
else
return $r;
}
/**
* DQL WHERE PARSER
* parses the where part of the query string
*
*
* @param string $str
* @return string
*/
private function parseWhere($str) {
return $this->parseCondition($str,'Where');
}
/**
* DQL HAVING PARSER
* parses the having part of the query string
*
*
* @param string $str
* @return string
*/
private function parseHaving($str) {
return $this->parseCondition($str,'Having');
}
/** /**
* trims brackets * trims brackets
* *
...@@ -970,91 +814,7 @@ class Doctrine_Query extends Doctrine_Access { ...@@ -970,91 +814,7 @@ class Doctrine_Query extends Doctrine_Access {
} }
return $term; return $term;
} }
/**
* DQL Aggregate Function parser
*
* @param string $func
* @return mixed
*/
private function parseAggregateFunction($func) {
$pos = strpos($func,"(");
if($pos !== false) {
$funcs = array();
$name = substr($func, 0, $pos);
$func = substr($func, ($pos + 1), -1);
$params = self::bracketExplode($func, ",", "(", ")");
foreach($params as $k => $param) {
$params[$k] = $this->parseAggregateFunction($param);
}
$funcs = $name."(".implode(", ", $params).")";
return $funcs;
} else {
if( ! is_numeric($func)) {
$a = explode(".",$func);
$field = array_pop($a);
$reference = implode(".",$a);
$table = $this->load($reference, false);
$func = $this->tableAliases[$reference].".".$field;
return $func;
} else {
return $func;
}
}
}
/**
* loadHaving
* returns the parsed query part
*
* @param string $having
* @return string
*/
private function loadHaving($having) {
$e = self::bracketExplode($having," ","(",")");
$r = array_shift($e);
$t = explode("(",$r);
$count = count($t);
$r = $this->parseAggregateFunction($r);
$operator = array_shift($e);
$value = implode(" ",$e);
$r .= " ".$operator." ".$value;
return $r;
}
/**
* loadWhere
* returns the parsed query part
*
* @param string $where
* @return string
*/
private function loadWhere($where) {
$e = explode(" ",$where);
$r = array_shift($e);
$a = explode(".",$r);
if(count($a) > 1) {
$field = array_pop($a);
$operator = array_shift($e);
$value = implode(" ",$e);
$reference = implode(".",$a);
$count = count($a);
$table = $this->load($reference, false);
$where = $this->tableAliases[$reference].".".$field." ".$operator." ".$value;
}
return $where;
}
/** /**
* generateAlias * generateAlias
* *
......
<?php
require_once("Part.php");
abstract class Doctrine_Query_Condition extends Doctrine_Query_Part {
/**
* DQL CONDITION PARSER
* parses the where/having part of the query string
*
*
* @param string $str
* @return string
*/
final public function parse($str) {
$tmp = trim($str);
$str = Doctrine_Query::bracketTrim($tmp,"(",")");
$brackets = false;
while($tmp != $str) {
$brackets = true;
$tmp = $str;
$str = Doctrine_Query::bracketTrim($str,"(",")");
}
$parts = Doctrine_Query::bracketExplode($str," && ","(",")");
if(count($parts) > 1) {
$ret = array();
foreach($parts as $part) {
$ret[] = $this->parse($part, $type);
}
$r = implode(" AND ",$ret);
} else {
$parts = Doctrine_Query::bracketExplode($str," || ","(",")");
if(count($parts) > 1) {
$ret = array();
foreach($parts as $part) {
$ret[] = $this->parse($part);
}
$r = implode(" OR ",$ret);
} else {
return $this->load($parts[0]);
}
}
if($brackets)
return "(".$r.")";
else
return $r;
}
}
?>
<?php
require_once("Part.php");
class Doctrine_Query_From extends Doctrine_Query_Part {
/**
* DQL FROM PARSER
* parses the from part of the query string
* @param string $str
* @return void
*/
final public function parse($str) {
foreach(Doctrine_Query::bracketExplode(trim($str),",", "(",")") as $reference) {
$reference = trim($reference);
$a = explode(".",$reference);
$field = array_pop($a);
$table = $this->query->load($reference);
}
}
public function __toString() {
return ( ! empty($this->parts))?implode(", ", $this->parts):'';
}
}
?>
<?php
require_once("Part.php");
class Doctrine_Query_Groupby extends Doctrine_Query_Part {
/**
* DQL GROUP BY PARSER
* parses the group by part of the query string
* @param string $str
* @return void
*/
final public function parse($str) {
$r = array();
foreach(explode(",", $str) as $reference) {
$reference = trim($reference);
$e = explode(".",$reference);
$field = array_pop($e);
$ref = implode(".", $e);
$table = $this->query->load($ref);
$component = $table->getComponentName();
$r[] = $this->query->getTableAlias($ref).".".$field;
}
return implode(", ", $r);
}
public function __toString() {
return ( ! empty($this->parts))?implode(", ", $this->parts):'';
}
}
?>
<?php
require_once("Condition.php");
class Doctrine_Query_Having extends Doctrine_Query_Condition {
/**
* DQL Aggregate Function parser
*
* @param string $func
* @return mixed
*/
private function parseAggregateFunction($func) {
$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);
}
$funcs = $name."(".implode(", ", $params).")";
return $funcs;
} else {
if( ! is_numeric($func)) {
$a = explode(".",$func);
$field = array_pop($a);
$reference = implode(".",$a);
$table = $this->query->load($reference, false);
$func = $this->query->getTableAlias($reference).".".$field;
return $func;
} else {
return $func;
}
}
}
/**
* load
* returns the parsed query part
*
* @param string $having
* @return string
*/
final public function load($having) {
$e = Doctrine_Query::bracketExplode($having," ","(",")");
$r = array_shift($e);
$t = explode("(",$r);
$count = count($t);
$r = $this->parseAggregateFunction($r);
$operator = array_shift($e);
$value = implode(" ",$e);
$r .= " ".$operator." ".$value;
return $r;
}
/**
* __toString
*
* @return string
*/
public function __toString() {
return ( ! empty($this->parts))?implode(" AND ", $this->parts):'';
}
}
?>
<?php
require_once("Part.php");
class Doctrine_Query_Orderby extends Doctrine_Query_Part {
/**
* DQL ORDER BY PARSER
* parses the order by part of the query string
*
* @param string $str
* @return void
*/
final public function parse($str) {
$ret = array();
foreach(explode(",",trim($str)) as $r) {
$r = trim($r);
$e = explode(" ",$r);
$a = explode(".",$e[0]);
if(count($a) > 1) {
$field = array_pop($a);
$reference = implode(".",$a);
$name = end($a);
$this->query->load($reference, false);
$alias = $this->query->getTableAlias($reference);
$tname = $this->query->getTable($alias)->getTableName();
$r = $tname.".".$field;
if(isset($e[1]))
$r .= " ".$e[1];
}
$ret[] = $r;
}
return implode(", ", $ret);
}
public function __toString() {
return ( ! empty($this->parts))?implode(", ", $this->parts):'';
}
}
?>
<?php
Doctrine::autoload("Doctrine_Access");
abstract class Doctrine_Query_Part extends Doctrine_Access {
protected $query;
protected $name;
protected $parts = array();
public function __construct(Doctrine_Query $query) {
$this->query = $query;
}
public function getName() {
return $this->name;
}
public function getQuery() {
return $this->query;
}
/**
* add
*
* @param string $value
* @return void
*/
public function add($value) {
$method = "parse".$this->name;
$this->query->$method($value);
}
public function get($name) { }
public function set($name, $value) { }
}
?>
<?php
require_once("Condition.php");
class Doctrine_Query_Where extends Doctrine_Query_Condition {
/**
* loadWhere
* returns the parsed query part
*
* @param string $where
* @return string
*/
final public function load($where) {
$e = explode(" ",$where);
$r = array_shift($e);
$a = explode(".",$r);
if(count($a) > 1) {
$field = array_pop($a);
$operator = array_shift($e);
$value = implode(" ",$e);
$reference = implode(".",$a);
$count = count($a);
$table = $this->query->load($reference, false);
$where = $this->query->getTableAlias($reference).".".$field." ".$operator." ".$value;
}
return $where;
}
public function __toString() {
return ( ! empty($this->parts))?implode(" AND ", $this->parts):'';
}
}
?>
...@@ -173,7 +173,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite ...@@ -173,7 +173,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
$this->table->getAttribute(Doctrine::ATTR_LISTENER)->onLoad($this); $this->table->getAttribute(Doctrine::ATTR_LISTENER)->onLoad($this);
} }
$this->table->getRepository()->add($this); $repository = $this->table->getRepository();
$repository->add($this);
} }
} }
/** /**
......
...@@ -39,11 +39,6 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab ...@@ -39,11 +39,6 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
* @var integer $transaction_level the nesting level of transactions, used by transaction methods * @var integer $transaction_level the nesting level of transactions, used by transaction methods
*/ */
private $transaction_level = 0; private $transaction_level = 0;
/**
* @var PDO $cacheHandler cache handler
*/
private $cacheHandler;
/** /**
* @var array $tables an array containing all the initialized Doctrine_Table objects * @var array $tables an array containing all the initialized Doctrine_Table objects
* keys representing Doctrine_Table component names and values as Doctrine_Table objects * keys representing Doctrine_Table component names and values as Doctrine_Table objects
...@@ -87,23 +82,8 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab ...@@ -87,23 +82,8 @@ abstract class Doctrine_Session extends Doctrine_Configurable implements Countab
$this->dbh->setAttribute(PDO::ATTR_CASE, PDO::CASE_NATURAL); $this->dbh->setAttribute(PDO::ATTR_CASE, PDO::CASE_NATURAL);
$this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
switch($this->getAttribute(Doctrine::ATTR_CACHE)):
case Doctrine::CACHE_SQLITE:
$dir = $this->getAttribute(Doctrine::ATTR_CACHE_DIR).DIRECTORY_SEPARATOR;
$dsn = "sqlite:".$dir."data.cache";
$this->cacheHandler = Doctrine_DB::getConn($dsn);
$this->cacheHandler->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->cacheHandler->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
break;
endswitch;
$this->getAttribute(Doctrine::ATTR_LISTENER)->onOpen($this); $this->getAttribute(Doctrine::ATTR_LISTENER)->onOpen($this);
} }
public function getCacheHandler() {
return $this->cacheHandler;
}
/** /**
* returns the state of this session * returns the state of this session
* *
......
...@@ -10,7 +10,7 @@ class Doctrine_Cache_Query_SqliteTestCase extends Doctrine_UnitTestCase { ...@@ -10,7 +10,7 @@ class Doctrine_Cache_Query_SqliteTestCase extends Doctrine_UnitTestCase {
if(file_exists($dir.DIRECTORY_SEPARATOR."stats.cache")) if(file_exists($dir.DIRECTORY_SEPARATOR."stats.cache"))
unlink($dir.DIRECTORY_SEPARATOR."stats.cache"); unlink($dir.DIRECTORY_SEPARATOR."stats.cache");
$this->cache = new Doctrine_Cache_Query_Sqlite($this->objTable); $this->cache = new Doctrine_Cache_Query_Sqlite($this->session);
$this->cache->deleteAll(); $this->cache->deleteAll();
} }
public function testStore() { public function testStore() {
......
...@@ -24,6 +24,16 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase { ...@@ -24,6 +24,16 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase {
parent::prepareTables(); parent::prepareTables();
} }
/**
public function testQueryPart() {
$this->query->from[] = "User.Phonenumber";
$this->query->from[] = "User.Email";
$users = $this->query->execute();
$this->assertEqual($users->count(), 8);
}
*/
public function testSelfReferencing() { public function testSelfReferencing() {
$query = new Doctrine_Query($this->session); $query = new Doctrine_Query($this->session);
...@@ -191,8 +201,6 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase { ...@@ -191,8 +201,6 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase {
$query->having("COUNT(User.Phonenumber.phonenumber) > 2"); $query->having("COUNT(User.Phonenumber.phonenumber) > 2");
$query->groupby('User.id'); $query->groupby('User.id');
//print Doctrine_Lib::formatSql($query->getQuery());
$users = $query->execute(); $users = $query->execute();
$this->assertEqual($users->count(), 3); $this->assertEqual($users->count(), 3);
...@@ -220,6 +228,20 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase { ...@@ -220,6 +228,20 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase {
$users[2]->Phonenumber[1]; $users[2]->Phonenumber[1];
$this->assertEqual(++$count, $this->dbh->count()); $this->assertEqual(++$count, $this->dbh->count());
$this->assertEqual($users[2]->Phonenumber->count(), 3); $this->assertEqual($users[2]->Phonenumber->count(), 3);
$this->session->clear();
$query->from('User-l.Phonenumber-l');
$query->having("COUNT(User.Phonenumber.phonenumber) > 2");
$query->groupby('User.id');
$users = $this->session->query("FROM User-l.Phonenumber-l GROUP BY User.id HAVING COUNT(User.Phonenumber.phonenumber) > 2");
$this->assertEqual($users->count(), 3);
// test that users are in right order
$this->assertEqual($users[0]->id, 5);
$this->assertEqual($users[1]->id, 8);
$this->assertEqual($users[2]->id, 10);
} }
public function testManyToManyFetchingWithColumnAggregationInheritance() { public function testManyToManyFetchingWithColumnAggregationInheritance() {
...@@ -257,7 +279,7 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase { ...@@ -257,7 +279,7 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase {
$users = $query->query("FROM User-b WHERE User.Group.name = 'Action Actors'"); $users = $query->query("FROM User-b WHERE User.Group.name = 'Action Actors'");
$this->assertEqual(trim($query->getQuery()), $this->assertEqual(trim($query->getQuery()),
"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 WHERE (entity2.name = 'Action Actors') AND (entity.type = 0 AND (entity2.type = 1 OR entity2.type IS NULL))"); "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 WHERE entity2.name = 'Action Actors' AND (entity.type = 0 AND (entity2.type = 1 OR entity2.type IS NULL))");
$this->assertTrue($users instanceof Doctrine_Collection); $this->assertTrue($users instanceof Doctrine_Collection);
$this->assertEqual($users->count(),1); $this->assertEqual($users->count(),1);
...@@ -266,7 +288,7 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase { ...@@ -266,7 +288,7 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase {
$users = $query->query("FROM User-b WHERE User.Group.Phonenumber.phonenumber LIKE '123 123'"); $users = $query->query("FROM User-b WHERE User.Group.Phonenumber.phonenumber LIKE '123 123'");
$this->assertEqual(trim($query->getQuery()), $this->assertEqual(trim($query->getQuery()),
"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))"); "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))");
$this->assertTrue($users instanceof Doctrine_Collection); $this->assertTrue($users instanceof Doctrine_Collection);
$this->assertEqual($users->count(),1); $this->assertEqual($users->count(),1);
...@@ -975,7 +997,7 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase { ...@@ -975,7 +997,7 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase {
} }
public function testQuery() { public function testAlbumManager() {
$query = new Doctrine_Query($this->session); $query = new Doctrine_Query($this->session);
...@@ -1012,10 +1034,11 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase { ...@@ -1012,10 +1034,11 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase {
$this->assertEqual(count($user->Album[1]->Song), 4); $this->assertEqual(count($user->Album[1]->Song), 4);
$users = $query->query("FROM User WHERE User.Album.name like '%Damage%'"); $users = $query->query("FROM User WHERE User.Album.name like '%Damage%'");
}
function testQuery() {
// DYNAMIC COLLECTION EXPANDING // DYNAMIC COLLECTION EXPANDING
$query = new Doctrine_Query($this->session);
$user = $this->objTable->find(5); $user = $this->objTable->find(5);
$user->Group[1]->name = "Tough guys inc."; $user->Group[1]->name = "Tough guys inc.";
...@@ -1043,7 +1066,7 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase { ...@@ -1043,7 +1066,7 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase {
$users = $query->query("FROM User-b.Phonenumber-l WHERE User.Phonenumber.phonenumber LIKE '%123%'"); $users = $query->query("FROM User-b.Phonenumber-l WHERE User.Phonenumber.phonenumber LIKE '%123%'");
$this->assertEqual(trim($query->getQuery()), $this->assertEqual(trim($query->getQuery()),
"SELECT entity.id AS entity__id, phonenumber.id AS phonenumber__id FROM entity LEFT JOIN phonenumber ON entity.id = phonenumber.entity_id WHERE (phonenumber.phonenumber LIKE '%123%') AND (entity.type = 0)"); "SELECT entity.id AS entity__id, phonenumber.id AS phonenumber__id FROM entity LEFT JOIN phonenumber ON entity.id = phonenumber.entity_id WHERE phonenumber.phonenumber LIKE '%123%' AND (entity.type = 0)");
$count = $this->session->getDBH()->count(); $count = $this->session->getDBH()->count();
...@@ -1110,17 +1133,17 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase { ...@@ -1110,17 +1133,17 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase {
$users = $query->query("FROM Email-b WHERE Email.address LIKE '%@example%'"); $users = $query->query("FROM Email-b WHERE Email.address LIKE '%@example%'");
$this->assertEqual($query->getQuery(), $this->assertEqual($query->getQuery(),
"SELECT email.id AS email__id FROM email WHERE (email.address LIKE '%@example%')"); "SELECT email.id AS email__id FROM email WHERE email.address LIKE '%@example%'");
$this->assertEqual($users->count(),8); $this->assertEqual($users->count(),8);
$users = $query->query("FROM User-b WHERE User.name LIKE '%Jack%'"); $users = $query->query("FROM User-b WHERE User.name LIKE '%Jack%'");
$this->assertEqual($query->getQuery(), "SELECT entity.id AS entity__id FROM entity WHERE (entity.name LIKE '%Jack%') AND (entity.type = 0)"); $this->assertEqual($query->getQuery(), "SELECT entity.id AS entity__id FROM entity WHERE entity.name LIKE '%Jack%' AND (entity.type = 0)");
$this->assertEqual($users->count(),0); $this->assertEqual($users->count(),0);
$users = $query->query("FROM User-b WHERE User.Phonenumber.phonenumber LIKE '%123%'"); $users = $query->query("FROM User-b WHERE User.Phonenumber.phonenumber LIKE '%123%'");
$this->assertEqual(trim($query->getQuery()), $this->assertEqual(trim($query->getQuery()),
"SELECT entity.id AS entity__id FROM entity LEFT JOIN phonenumber ON entity.id = phonenumber.entity_id WHERE (phonenumber.phonenumber LIKE '%123%') AND (entity.type = 0)"); "SELECT entity.id AS entity__id FROM entity LEFT JOIN phonenumber ON entity.id = phonenumber.entity_id WHERE phonenumber.phonenumber LIKE '%123%' AND (entity.type = 0)");
$this->assertEqual($users->count(),5); $this->assertEqual($users->count(),5);
...@@ -1131,6 +1154,5 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase { ...@@ -1131,6 +1154,5 @@ class Doctrine_QueryTestCase extends Doctrine_UnitTestCase {
//$this->assertTrue(isset($values['max'])); //$this->assertTrue(isset($values['max']));
} }
} }
?> ?>
...@@ -6,6 +6,87 @@ class Doctrine_RecordTestCase extends Doctrine_UnitTestCase { ...@@ -6,6 +6,87 @@ class Doctrine_RecordTestCase extends Doctrine_UnitTestCase {
$this->tables[] = "enumTest"; $this->tables[] = "enumTest";
parent::prepareTables(); parent::prepareTables();
} }
public function testJoinTableSelfReferencing() {
$e = new Entity();
$e->name = "Entity test";
$this->assertTrue($e->Entity[0] instanceof Entity);
$this->assertTrue($e->Entity[1] instanceof Entity);
$this->assertEqual($e->Entity[0]->getState(), Doctrine_Record::STATE_TCLEAN);
$this->assertEqual($e->Entity[1]->getState(), Doctrine_Record::STATE_TCLEAN);
$e->Entity[0]->name = "Friend 1";
$e->Entity[1]->name = "Friend 2";
$e->Entity[0]->Entity[0]->name = "Friend 1 1";
$e->Entity[0]->Entity[1]->name = "Friend 1 2";
$e->Entity[1]->Entity[0]->name = "Friend 2 1";
$e->Entity[1]->Entity[1]->name = "Friend 2 2";
$this->assertEqual($e->Entity[0]->name, "Friend 1");
$this->assertEqual($e->Entity[1]->name, "Friend 2");
$this->assertEqual($e->Entity[0]->Entity[0]->name, "Friend 1 1");
$this->assertEqual($e->Entity[0]->Entity[1]->name, "Friend 1 2");
$this->assertEqual($e->Entity[1]->Entity[0]->name, "Friend 2 1");
$this->assertEqual($e->Entity[1]->Entity[1]->name, "Friend 2 2");
$this->assertEqual($e->Entity[0]->getState(), Doctrine_Record::STATE_TDIRTY);
$this->assertEqual($e->Entity[1]->getState(), Doctrine_Record::STATE_TDIRTY);
$e->save();
$this->assertTrue($e->Entity[0] instanceof Entity);
$this->assertTrue($e->Entity[1] instanceof Entity);
$this->assertEqual($e->Entity[0]->name, "Friend 1");
$this->assertEqual($e->Entity[1]->name, "Friend 2");
$this->assertEqual($e->Entity[0]->Entity[0]->name, "Friend 1 1");
$this->assertEqual($e->Entity[0]->Entity[1]->name, "Friend 1 2");
$this->assertEqual($e->Entity[1]->Entity[0]->name, "Friend 2 1");
$this->assertEqual($e->Entity[1]->Entity[1]->name, "Friend 2 2");
$this->assertEqual($e->Entity[0]->getState(), Doctrine_Record::STATE_CLEAN);
$this->assertEqual($e->Entity[1]->getState(), Doctrine_Record::STATE_CLEAN);
$e = $e->getTable()->find($e->getID());
$this->assertTrue($e->Entity[0] instanceof Entity);
$this->assertTrue($e->Entity[1] instanceof Entity);
$this->assertEqual($e->Entity[0]->name, "Friend 1");
$this->assertEqual($e->Entity[1]->name, "Friend 2");
$this->assertEqual($e->Entity[0]->Entity[0]->name, "Friend 1 1");
$this->assertEqual($e->Entity[0]->Entity[1]->name, "Friend 1 2");
$this->assertEqual($e->Entity[1]->Entity[0]->name, "Friend 2 1");
$this->assertEqual($e->Entity[1]->Entity[1]->name, "Friend 2 2");
$this->assertEqual($e->Entity[0]->getState(), Doctrine_Record::STATE_CLEAN);
$this->assertEqual($e->Entity[1]->getState(), Doctrine_Record::STATE_CLEAN);
$coll = $this->session->query("FROM Entity WHERE Entity.name = 'Friend 1'");
$this->assertEqual($coll->count(), 1);
$this->assertEqual($coll[0]->getState(), Doctrine_Record::STATE_CLEAN);
$this->assertEqual($coll[0]->name, "Friend 1");
$query = new Doctrine_Query($this->session);
$query->from("Entity.Entity")->where("Entity.Entity.name = 'Friend 1 1'");
$coll = $query->execute();
$this->assertEqual($coll->count(), 1);
}
public function testEnumType() { public function testEnumType() {
$enum = new EnumTest(); $enum = new EnumTest();
$enum->status = "open"; $enum->status = "open";
...@@ -44,52 +125,7 @@ class Doctrine_RecordTestCase extends Doctrine_UnitTestCase { ...@@ -44,52 +125,7 @@ class Doctrine_RecordTestCase extends Doctrine_UnitTestCase {
$this->assertEqual($user->name, 'z'); $this->assertEqual($user->name, 'z');
} }
public function testJoinTableSelfReferencing() {
$e = new Entity();
$e->name = "Entity test";
$this->assertTrue($e->Entity[0] instanceof Entity);
$this->assertTrue($e->Entity[1] instanceof Entity);
$this->assertEqual($e->Entity[0]->getState(), Doctrine_Record::STATE_TCLEAN);
$this->assertEqual($e->Entity[1]->getState(), Doctrine_Record::STATE_TCLEAN);
$e->Entity[0]->name = "Subentity 1";
$e->Entity[1]->name = "Subentity 2";
$this->assertEqual($e->Entity[0]->name, "Subentity 1");
$this->assertEqual($e->Entity[1]->name, "Subentity 2");
$this->assertEqual($e->Entity[0]->getState(), Doctrine_Record::STATE_TDIRTY);
$this->assertEqual($e->Entity[1]->getState(), Doctrine_Record::STATE_TDIRTY);
$e->save();
$this->assertTrue($e->Entity[0] instanceof Entity);
$this->assertTrue($e->Entity[1] instanceof Entity);
$this->assertEqual($e->Entity[0]->name, "Subentity 1");
$this->assertEqual($e->Entity[1]->name, "Subentity 2");
$this->assertEqual($e->Entity[0]->getState(), Doctrine_Record::STATE_CLEAN);
$this->assertEqual($e->Entity[1]->getState(), Doctrine_Record::STATE_CLEAN);
$e = $e->getTable()->find($e->getID());
$this->assertTrue($e->Entity[0] instanceof Entity);
$this->assertTrue($e->Entity[1] instanceof Entity);
$this->assertEqual($e->Entity[0]->name, "Subentity 1");
$this->assertEqual($e->Entity[1]->name, "Subentity 2");
$this->assertEqual($e->Entity[0]->getState(), Doctrine_Record::STATE_CLEAN);
$this->assertEqual($e->Entity[1]->getState(), Doctrine_Record::STATE_CLEAN);
$coll = $this->session->query("FROM Entity WHERE Entity.name = 'Subentity 1'");
$this->assertEqual($coll->count(), 1);
$this->assertEqual($coll[0]->getState(), Doctrine_Record::STATE_CLEAN);
$this->assertEqual($coll[0]->name, "Subentity 1");
}
public function testCompositePK() { public function testCompositePK() {
$record = new EntityReference(); $record = new EntityReference();
......
...@@ -61,16 +61,18 @@ $test->addTestCase(new Doctrine_QueryTestCase()); ...@@ -61,16 +61,18 @@ $test->addTestCase(new Doctrine_QueryTestCase());
print "<pre>"; print "<pre>";
$test->run(new HtmlReporter()); $test->run(new HtmlReporter());
/**
$cache = Doctrine_Manager::getInstance()->getCurrentSession()->getCacheHandler(); $cache = Doctrine_Manager::getInstance()->getCurrentSession()->getCacheHandler();
if(isset($cache)) { if(isset($cache)) {
$a = $cache->getQueries(); $a = $cache->getQueries();
print "Executed cache queries: ".count($a)."\n"; print "Executed cache queries: ".count($a)."\n";
/**
foreach($a as $query) { foreach($a as $query) {
print $query."\n"; print $query."\n";
} }
*/
} }
*/
$dbh = Doctrine_Manager::getInstance()->getCurrentSession()->getDBH(); $dbh = Doctrine_Manager::getInstance()->getCurrentSession()->getDBH();
$a = $dbh->getQueries(); $a = $dbh->getQueries();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment