1
0
mirror of synced 2024-12-13 22:56:04 +03:00
doctrine2/Doctrine/RawSql.php

227 lines
7.1 KiB
PHP
Raw Normal View History

2006-07-22 03:22:15 +04:00
<?php
/*
* $Id$
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.com>.
*/
/**
* Doctrine_RawSql
*
* @package Doctrine ORM
* @url www.phpdoctrine.com
* @license LGPL
*/
2006-07-22 03:22:15 +04:00
class Doctrine_RawSql extends Doctrine_Hydrate {
/**
* @var array $fields
*/
private $fields;
/**
* __call
* method overloader
*
* @param string $name
* @param array $args
* @return Doctrine_RawSql
*/
public function __call($name, $args) {
if( ! isset($this->parts[$name]))
2006-07-22 03:22:15 +04:00
throw new Doctrine_Exception("Unknown overload method");
if($name == 'select') {
preg_match_all('/{([^}{]*)}/U', $args[0], $m);
$this->fields = $m[1];
$this->parts["select"] = array();
} else
2006-07-22 03:22:15 +04:00
$this->parts[$name][] = $args[0];
return $this;
}
2006-08-20 23:21:52 +04:00
/**
* get
*/
public function get($name) {
if( ! isset($this->parts[$name]))
throw new Doctrine_Exception('Unknown query part '.$name);
return $this->parts[$name];
}
2006-07-22 03:22:15 +04:00
/**
* parseQuery
*
* @param string $query
2006-07-22 03:44:07 +04:00
* @return Doctrine_RawSql
2006-07-22 03:22:15 +04:00
*/
public function parseQuery($query) {
preg_match_all('/{([^}{]*)}/U', $query, $m);
2006-07-22 03:22:15 +04:00
$this->fields = $m[1];
$this->clear();
$e = Doctrine_Query::sqlExplode($query,' ');
2006-07-22 03:22:15 +04:00
foreach($e as $k => $part):
$low = strtolower($part);
switch(strtolower($part)):
case "select":
case "from":
case "where":
case "limit":
case "offset":
case "having":
$p = $low;
2006-08-20 23:21:52 +04:00
if( ! isset($parts[$low]))
$parts[$low] = array();
2006-08-20 23:25:04 +04:00
2006-07-22 03:22:15 +04:00
break;
case "order":
case "group":
$i = ($k + 1);
if(isset($e[$i]) && strtolower($e[$i]) === "by") {
2006-08-22 23:34:40 +04:00
$p = $low;
$p .= "by";
$parts[$low."by"] = array();
2006-07-22 03:22:15 +04:00
} else
$parts[$p][] = $part;
break;
case "by":
continue;
default:
2006-08-20 23:21:52 +04:00
if( ! isset($parts[$p][0]))
$parts[$p][0] = $part;
else
$parts[$p][0] .= ' '.$part;
2006-07-22 03:22:15 +04:00
endswitch;
endforeach;
$this->parts = $parts;
$this->parts["select"] = array();
2006-07-22 03:44:07 +04:00
return $this;
2006-07-22 03:22:15 +04:00
}
/**
* getQuery
*
*
2006-07-22 03:22:15 +04:00
* @return string
*/
public function getQuery() {
foreach($this->fields as $field) {
$e = explode(".", $field);
if( ! isset($e[1]))
throw new Doctrine_Exception("All selected fields in Sql query must be in format tableAlias.fieldName");
2006-07-22 03:22:15 +04:00
if( ! isset($this->tables[$e[0]])) {
try {
$this->addComponent($e[0], ucwords($e[0]));
} catch(Doctrine_Exception $exception) {
throw new Doctrine_Exception("The associated component for table alias $e[0] couldn't be found.");
2006-07-22 03:22:15 +04:00
}
}
if($e[1] == '*') {
foreach($this->tables[$e[0]]->getColumnNames() as $name) {
$field = $e[0].".".$name;
$this->parts["select"][$field] = $field." AS ".$e[0]."__".$name;
}
} else {
$field = $e[0].".".$e[1];
$this->parts["select"][$field] = $field." AS ".$e[0]."__".$e[1];
}
}
2006-07-22 03:22:15 +04:00
// force-add all primary key fields
foreach($this->tableAliases as $alias) {
foreach($this->tables[$alias]->getPrimaryKeys() as $key) {
$field = $alias.".".$key;
if( ! isset($this->parts["select"][$field]))
$this->parts["select"][$field] = $field." AS ".$alias."__".$key;
}
}
2006-08-22 23:34:40 +04:00
$q = "SELECT ".implode(', ', $this->parts['select']);
2006-07-22 03:22:15 +04:00
$string = $this->applyInheritance();
if( ! empty($string))
$this->parts["where"][] = $string;
$copy = $this->parts;
unset($copy['select']);
2006-08-22 23:34:40 +04:00
$q .= ( ! empty($this->parts['from']))?" FROM ".implode(" ",$this->parts["from"]):'';
$q .= ( ! empty($this->parts['where']))?" WHERE ".implode(" AND ",$this->parts["where"]):'';
$q .= ( ! empty($this->parts['groupby']))?" 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($string))
array_pop($this->parts['where']);
return $q;
2006-07-22 03:22:15 +04:00
}
/**
* getFields
*
* @return array
*/
public function getFields() {
return $this->fields;
}
/**
* addComponent
*
* @param string $tableAlias
* @param string $componentName
2006-07-22 03:44:07 +04:00
* @return Doctrine_RawSql
2006-07-22 03:22:15 +04:00
*/
public function addComponent($tableAlias, $componentName) {
$e = explode(".", $componentName);
2006-07-22 03:22:15 +04:00
$currPath = '';
foreach($e as $k => $component) {
$currPath .= '.'.$component;
if($k == 0)
2006-07-22 03:22:15 +04:00
$currPath = substr($currPath,1);
if(isset($this->tableAliases[$currPath]))
$alias = $this->tableAliases[$currPath];
else
$alias = $tableAlias;
2006-08-22 03:19:15 +04:00
$table = $this->connection->getTable($component);
2006-07-22 03:22:15 +04:00
$this->tables[$alias] = $table;
$this->fetchModes[$alias] = Doctrine::FETCH_IMMEDIATE;
$this->tableAliases[$currPath] = $alias;
if($k !== 0)
$this->joins[$alias] = $prevAlias;
$prevAlias = $alias;
$prevPath = $currPath;
}
2006-07-22 03:44:07 +04:00
return $this;
2006-07-22 03:22:15 +04:00
}
}