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

243 lines
8.0 KiB
PHP
Raw Normal View History

2006-07-22 03:22:15 +04:00
<?php
2006-12-29 17:01:31 +03:00
/*
* $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::autoload('Doctrine_Hydrate');
/**
* Doctrine_RawSql
*
* @package Doctrine
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @category Object Relational Mapping
* @link www.phpdoctrine.com
* @since 1.0
* @version $Revision$
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
*/
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) {
2006-12-29 17:01:31 +03:00
if ( ! isset($this->parts[$name])) {
throw new Doctrine_RawSql_Exception("Unknown overload method $name. Availible overload methods are ".implode(" ",array_keys($this->parts)));
2006-12-29 17:01:31 +03:00
}
if ($name == 'select') {
2006-07-22 03:22:15 +04:00
preg_match_all('/{([^}{]*)}/U', $args[0], $m);
$this->fields = $m[1];
$this->parts["select"] = array();
2006-12-29 17:01:31 +03:00
} else {
2006-07-22 03:22:15 +04:00
$this->parts[$name][] = $args[0];
2006-12-29 17:01:31 +03:00
}
2006-07-22 03:22:15 +04:00
return $this;
}
2006-08-20 23:21:52 +04:00
/**
* get
*/
public function get($name) {
2006-12-29 17:01:31 +03:00
if ( ! isset($this->parts[$name])) {
throw new Doctrine_RawSql_Exception('Unknown query part '.$name);
2006-12-29 17:01:31 +03:00
}
2006-08-20 23:21:52 +04:00
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
2006-12-29 17:01:31 +03:00
foreach ($e as $k => $part) {
2006-07-22 03:22:15 +04:00
$low = strtolower($part);
2006-12-29 17:01:31 +03:00
switch (strtolower($part)) {
case "select":
case "from":
case "where":
case "limit":
case "offset":
case "having":
$p = $low;
if ( ! isset($parts[$low])) {
$parts[$low] = array();
}
break;
case "order":
case "group":
$i = ($k + 1);
if (isset($e[$i]) && strtolower($e[$i]) === "by") {
2006-07-22 03:22:15 +04:00
$p = $low;
2006-12-29 17:01:31 +03:00
$p .= "by";
$parts[$low."by"] = array();
2006-08-20 23:25:04 +04:00
2006-12-29 17:01:31 +03:00
} else {
$parts[$p][] = $part;
}
2006-07-22 03:22:15 +04:00
break;
2006-12-29 17:01:31 +03:00
case "by":
continue;
default:
if ( ! isset($parts[$p][0])) {
$parts[$p][0] = $part;
} else {
$parts[$p][0] .= ' '.$part;
}
};
};
2006-07-22 03:22:15 +04:00
$this->parts = $parts;
$this->parts["select"] = array();
2006-12-29 17:01:31 +03:00
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() {
2006-12-29 17:01:31 +03:00
foreach ($this->fields as $field) {
2006-07-22 03:22:15 +04:00
$e = explode(".", $field);
2006-12-29 17:01:31 +03:00
if ( ! isset($e[1])) {
throw new Doctrine_RawSql_Exception("All selected fields in Sql query must be in format tableAlias.fieldName");
2006-12-29 17:01:31 +03:00
}
if ( ! isset($this->tables[$e[0]])) {
2006-07-22 03:22:15 +04:00
try {
$this->addComponent($e[0], ucwords($e[0]));
} catch(Doctrine_Exception $exception) {
throw new Doctrine_RawSql_Exception("The associated component for table alias $e[0] couldn't be found.");
2006-07-22 03:22:15 +04:00
}
}
2006-12-29 17:01:31 +03:00
if ($e[1] == '*') {
foreach ($this->tables[$e[0]]->getColumnNames() as $name) {
2006-07-22 03:22:15 +04:00
$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
2006-12-29 17:01:31 +03:00
foreach ($this->tableAliases as $alias) {
foreach ($this->tables[$alias]->getPrimaryKeys() as $key) {
2006-12-28 03:55:48 +03:00
$field = $alias . '.' . $key;
2006-12-29 17:01:31 +03:00
if ( ! isset($this->parts["select"][$field])) {
2006-07-22 03:22:15 +04:00
$this->parts["select"][$field] = $field." AS ".$alias."__".$key;
2006-12-29 17:01:31 +03:00
}
2006-07-22 03:22:15 +04:00
}
}
$q = 'SELECT '.implode(', ', $this->parts['select']);
2006-07-22 03:22:15 +04:00
$string = $this->applyInheritance();
2006-12-29 17:01:31 +03:00
if ( ! empty($string)) {
$this->parts['where'][] = $string;
2006-12-29 17:01:31 +03:00
}
2006-07-22 03:22:15 +04:00
$copy = $this->parts;
unset($copy['select']);
$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']) : '';
2006-12-28 03:55:48 +03:00
$q .= ( ! empty($this->parts['limit']))? ' LIMIT ' . implode(' ', $this->parts['limit']) : '';
$q .= ( ! empty($this->parts['offset']))? ' OFFSET ' . implode(' ', $this->parts['offset']) : '';
2006-08-22 23:34:40 +04:00
2006-12-29 17:01:31 +03:00
if ( ! empty($string)) {
2006-08-22 23:34:40 +04:00
array_pop($this->parts['where']);
2006-12-29 17:01:31 +03:00
}
2006-08-22 23:34:40 +04:00
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) {
2006-11-11 22:51:51 +03:00
$e = explode('.', $componentName);
2006-07-22 03:22:15 +04:00
$currPath = '';
2006-11-10 21:24:57 +03:00
$table = null;
2006-07-22 03:22:15 +04:00
2006-12-29 17:01:31 +03:00
foreach ($e as $k => $component) {
2006-11-11 22:51:51 +03:00
$currPath .= '.' . $component;
2006-12-29 17:01:31 +03:00
if ($k == 0)
2006-07-22 03:22:15 +04:00
$currPath = substr($currPath,1);
2006-12-29 17:01:31 +03:00
if (isset($this->tableAliases[$currPath])) {
2006-07-22 03:22:15 +04:00
$alias = $this->tableAliases[$currPath];
2006-12-29 17:01:31 +03:00
} else {
2006-07-22 03:22:15 +04:00
$alias = $tableAlias;
2006-12-29 17:01:31 +03:00
}
2006-07-22 03:22:15 +04:00
2006-12-29 17:01:31 +03:00
if ($table) {
2006-11-11 22:51:51 +03:00
$tableName = $table->getAliasName($component);
$table = $this->conn->getTable($tableName);
2006-11-10 21:24:57 +03:00
} else {
$table = $this->conn->getTable($component);
2006-11-10 21:24:57 +03:00
}
2006-07-22 03:22:15 +04:00
$this->tables[$alias] = $table;
$this->fetchModes[$alias] = Doctrine::FETCH_IMMEDIATE;
$this->tableAliases[$currPath] = $alias;
2006-12-29 17:01:31 +03:00
if ($k !== 0) {
2006-07-22 03:22:15 +04:00
$this->joins[$alias] = $prevAlias;
2006-12-29 17:01:31 +03:00
}
2006-07-22 03:22:15 +04:00
$prevAlias = $alias;
$prevPath = $currPath;
}
2006-12-29 17:01:31 +03:00
2006-07-22 03:44:07 +04:00
return $this;
2006-07-22 03:22:15 +04:00
}
}