Beispiel #1
0
 /**
  * parseClause
  *
  * @param string $alias     component alias
  * @param string $field     the field name
  * @param mixed $value      the value of the field
  * @return void
  */
 public function parseClause($alias, $field, $value)
 {
     $parts = Doctrine_Tokenizer::quoteExplode($value, ' AND ');
     if (count($parts) > 1) {
         $ret = array();
         foreach ($parts as $part) {
             $ret[] = $this->parseSingle($alias, $field, $part);
         }
         $r = implode(' AND ', $ret);
     } else {
         $parts = Doctrine_Tokenizer::quoteExplode($value, ' OR ');
         if (count($parts) > 1) {
             $ret = array();
             foreach ($parts as $part) {
                 $ret[] = $this->parseClause($alias, $field, $part);
             }
             $r = implode(' OR ', $ret);
         } else {
             $ret = $this->parseSingle($alias, $field, $parts[0]);
             return $ret;
         }
     }
     return '(' . $r . ')';
 }
Beispiel #2
0
 /**
  * getLimitSubquery
  * this is method is used by the record limit algorithm
  *
  * when fetching one-to-many, many-to-many associated data with LIMIT clause
  * an additional subquery is needed for limiting the number of returned records instead
  * of limiting the number of sql result set rows
  *
  * @return string       the limit subquery
  */
 public function getLimitSubquery()
 {
     $map = reset($this->_aliasMap);
     $table = $map['table'];
     $componentAlias = key($this->_aliasMap);
     // get short alias
     $alias = $this->getTableAlias($componentAlias);
     $primaryKey = $alias . '.' . $table->getIdentifier();
     // initialize the base of the subquery
     $subquery = 'SELECT DISTINCT ' . $this->_conn->quoteIdentifier($primaryKey);
     $driverName = $this->_conn->getAttribute(Doctrine::ATTR_DRIVER_NAME);
     // pgsql needs the order by fields to be preserved in select clause
     if ($driverName == 'pgsql') {
         foreach ($this->parts['orderby'] as $part) {
             $part = trim($part);
             $e = Doctrine_Tokenizer::bracketExplode($part, ' ');
             $part = trim($e[0]);
             if (strpos($part, '.') === false) {
                 continue;
             }
             // don't add functions
             if (strpos($part, '(') !== false) {
                 continue;
             }
             // don't add primarykey column (its already in the select clause)
             if ($part !== $primaryKey) {
                 $subquery .= ', ' . $part;
             }
         }
     }
     if ($driverName == 'mysql' || $driverName == 'pgsql') {
         foreach ($this->_expressionMap as $dqlAlias => $expr) {
             if (isset($expr[1])) {
                 $subquery .= ', ' . $expr[0] . ' AS ' . $this->aggregateMap[$dqlAlias];
             }
         }
     }
     $subquery .= ' FROM';
     foreach ($this->parts['from'] as $part) {
         // preserve LEFT JOINs only if needed
         if (substr($part, 0, 9) === 'LEFT JOIN') {
             $e = explode(' ', $part);
             if (empty($this->parts['orderby']) && empty($this->parts['where'])) {
                 continue;
             }
         }
         $subquery .= ' ' . $part;
     }
     // all conditions must be preserved in subquery
     $subquery .= !empty($this->parts['where']) ? ' WHERE ' . implode(' AND ', $this->parts['where']) : '';
     $subquery .= !empty($this->parts['groupby']) ? ' GROUP BY ' . implode(', ', $this->parts['groupby']) : '';
     $subquery .= !empty($this->parts['having']) ? ' HAVING ' . implode(' AND ', $this->parts['having']) : '';
     $subquery .= !empty($this->parts['orderby']) ? ' ORDER BY ' . implode(', ', $this->parts['orderby']) : '';
     // add driver specific limit clause
     $subquery = $this->_conn->modifyLimitQuery($subquery, $this->parts['limit'], $this->parts['offset']);
     $parts = Doctrine_Tokenizer::quoteExplode($subquery, ' ', "'", "'");
     foreach ($parts as $k => $part) {
         if (strpos($part, ' ') !== false) {
             continue;
         }
         $part = trim($part, "\"'`");
         if ($this->hasTableAlias($part)) {
             $parts[$k] = $this->_conn->quoteIdentifier($this->generateNewTableAlias($part));
             continue;
         }
         if (strpos($part, '.') === false) {
             continue;
         }
         preg_match_all("/[a-zA-Z0-9_]+\\.[a-z0-9_]+/i", $part, $m);
         foreach ($m[0] as $match) {
             $e = explode('.', $match);
             $e[0] = $this->generateNewTableAlias($e[0]);
             $parts[$k] = str_replace($match, implode('.', $e), $parts[$k]);
         }
     }
     if ($driverName == 'mysql' || $driverName == 'pgsql') {
         foreach ($parts as $k => $part) {
             if (strpos($part, "'") !== false) {
                 continue;
             }
             if (strpos($part, '__') == false) {
                 continue;
             }
             preg_match_all("/[a-zA-Z0-9_]+\\_\\_[a-z0-9_]+/i", $part, $m);
             foreach ($m[0] as $match) {
                 $e = explode('__', $match);
                 $e[0] = $this->generateNewTableAlias($e[0]);
                 $parts[$k] = str_replace($match, implode('__', $e), $parts[$k]);
             }
         }
     }
     $subquery = implode(' ', $parts);
     return $subquery;
 }