3
* $Id: Where.php 5501 2009-02-16 20:35:26Z jwage $
5
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
6
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
7
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
8
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
9
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
10
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
11
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
12
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
13
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
14
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
15
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17
* This software consists of voluntary contributions made by many individuals
18
* and is licensed under the LGPL. For more information, see
19
* <http://www.phpdoctrine.org>.
23
* Doctrine_Query_Where
27
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
28
* @link www.phpdoctrine.org
30
* @version $Revision: 5501 $
31
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
33
class Doctrine_Query_Where extends Doctrine_Query_Condition
35
public function load($where)
37
$where = $this->_tokenizer->bracketTrim(trim($where));
38
$conn = $this->query->getConnection();
39
$terms = $this->_tokenizer->sqlExplode($where);
41
if (count($terms) > 1) {
42
if (substr($where, 0, 6) == 'EXISTS') {
43
return $this->parseExists($where, true);
44
} elseif (substr($where, 0, 10) == 'NOT EXISTS') {
45
return $this->parseExists($where, false);
49
if (count($terms) < 3) {
50
$terms = $this->_tokenizer->sqlExplode($where, array('=', '<', '<>', '>', '!='));
53
if (count($terms) > 1) {
54
$first = array_shift($terms);
55
$value = array_pop($terms);
56
$operator = trim(substr($where, strlen($first), -strlen($value)));
60
if (strpos($first, "'") === false && strpos($first, '(') === false) {
61
// normal field reference found
62
$a = explode('.', $first);
64
$field = array_pop($a);
65
$reference = implode('.', $a);
67
if (empty($reference)) {
68
$map = $this->query->getRootDeclaration();
70
$alias = $this->query->getTableAlias($this->query->getRootAlias());
71
$table = $map['table'];
73
$map = $this->query->load($reference, false);
75
$alias = $this->query->getTableAlias($reference);
76
$table = $map['table'];
79
$first = $this->query->parseClause($first);
81
$sql = $first . ' ' . $operator . ' ' . $this->parseValue($value, $table, $field);
89
public function parseValue($value, Doctrine_Table $table = null, $field = null)
91
$conn = $this->query->getConnection();
93
// If value is contained in paranthesis
94
if (substr($value, 0, 1) == '(') {
96
$trimmed = $this->_tokenizer->bracketTrim($value);
98
// If subquery found which begins with FROM and SELECT
99
// FROM User u WHERE u.id IN(SELECT u.id FROM User u WHERE u.id = 1)
100
if (substr($trimmed, 0, 4) == 'FROM' ||
101
substr($trimmed, 0, 6) == 'SELECT') {
104
$q = $this->query->createSubquery()->parseQuery($trimmed, false);
106
$value = '(' . $sql . ')';
108
// If custom sql for custom subquery
109
// You can specify SQL: followed by any valid sql expression
110
// FROM User u WHERE u.id = SQL:(select id from user where id = 1)
111
} elseif (substr($trimmed, 0, 4) == 'SQL:') {
112
$value = '(' . substr($trimmed, 4) . ')';
113
// simple in expression found
115
$e = $this->_tokenizer->sqlExplode($trimmed, ',');
121
foreach ($e as $part) {
122
$value[] = $this->parseLiteralValue($part);
125
$value = '(' . implode(', ', $value) . ')';
128
$value = $this->parseLiteralValue($value);
134
* parses an EXISTS expression
136
* @param string $where query where part to be parsed
137
* @param boolean $negation whether or not to use the NOT keyword
140
public function parseExists($where, $negation)
142
$operator = ($negation) ? 'EXISTS' : 'NOT EXISTS';
144
$pos = strpos($where, '(');
147
throw new Doctrine_Query_Exception('Unknown expression, expected a subquery with () -marks');
150
$sub = $this->_tokenizer->bracketTrim(substr($where, $pos));
152
$q = $this->query->createSubquery()->parseQuery($sub, false);
155
return $operator . ' (' . $sql . ')';