Пример #1
0
 /**
  * Select
  *
  * @param  string	$expression	Expression which creates a resulting element
  * @return mixed
  */
 public function select($expression = null)
 {
     // Return value
     $returnValue = array();
     // Zend_Db_Select expression
     $zendDbSelect = null;
     // Expression set?
     if (is_null($expression) || $expression == '') {
         $expression = $this->_from . ' => ' . $this->_from;
     }
     // Data source
     $dataSourceInfo = $this->_data->info();
     $dataSource = $this->_data->select()->from(array($this->_from => $dataSourceInfo['name']), $this->_columns);
     // Create selector expression
     $selector = new PHPLinq_Expression($expression, $this->_from);
     // Build Zend_Db_Select chain
     $zendDbSelect = $dataSource;
     // Distinct set?
     if (!is_null($this->_distinct)) {
         $zendDbSelect = $zendDbSelect->distinct();
     }
     // Join set?
     if (count($this->_childProviders) > 0) {
         // Check if the child providers can be supported
         foreach ($this->_childProviders as $provider) {
             if (get_class($provider) != __CLASS__) {
                 throw new PHPLinq_Exception('Joins of ' . get_class($provider) . ' on ' . __CLASS__ . ' are not supported.');
             } else {
                 // Supported! Add join
                 $joinInfo = $provider->getSource()->info();
                 $dataSource = $dataSource->join(array($provider->getFromName() => $joinInfo['name']), $this->_convertToSql($provider->getJoinCondition()->getFunction()->getFunctionCode()));
             }
         }
     }
     // Where expresion set? Evaluate it!
     if (!is_null($this->_where)) {
         $functionCode = $this->_convertToSql($this->_where->getFunction()->getFunctionCode(), $dataSource->getAdapter()->getQuoteIdentifierSymbol());
         $zendDbSelect = $zendDbSelect->where($functionCode);
     }
     // OrderBy set?
     if (is_array($this->_orderBy) && count($this->_orderBy) > 0) {
         $orderBy = array();
         foreach ($this->_orderBy as $orderByExpression) {
             $orderBy[] = new Zend_Db_Expr($this->_convertToSql($orderByExpression->getExpression()->getFunction()->getFunctionCode()) . ($orderByExpression->isDescending() ? ' DESC' : ' ASC'));
         }
         $zendDbSelect = $zendDbSelect->order($orderBy);
     }
     // Take / skip
     $zendDbSelect->limit($this->_take, $this->_skip);
     // No integrity check needed, joins can be free format
     $zendDbSelect->setIntegrityCheck(false);
     // Log query string
     if (!is_null(self::$_queryCallback)) {
         if (!is_array(self::$_queryCallback) && in_array(self::$_queryCallback, self::$_internalFunctions)) {
             self::$_queryCallback = create_function('$query', self::$_queryCallback . '($query);');
         }
         call_user_func(self::$_queryCallback, $zendDbSelect->__toString());
     }
     // Query
     $results = null;
     if (count($this->_childProviders) == 0) {
         // No join, easy!
         $results = $zendDbSelect->query(Zend_Db::FETCH_OBJ)->fetchAll();
         // Row class set? If so, convert all data!
         if ($this->_data->getRowClass() != 'Zend_Db_Table_Row') {
             $rowClass = $this->_data->getRowClass();
             $tempResults = array();
             foreach ($results as $result) {
                 $tempResult = call_user_func(array($rowClass, 'fromArray'), (array) $result);
                 $tempResults[] = $tempResult;
             }
             $results = $tempResults;
         }
     } else {
         // Get data in mode FETCH_NAMED
         $tempResults = $zendDbSelect->query(Zend_Db::FETCH_NAMED)->fetchAll();
         // Fetch info
         $info = array($this->_data->info());
         foreach ($this->_childProviders as $provider) {
             $info[] = $provider->getSource()->info();
         }
         // Build proper resultset
         $results = array();
         $currentResult = null;
         $currentObject = null;
         foreach ($tempResults as $tempResult) {
             $currentResult = array();
             // For each table, add a new object with values
             for ($i = 0; $i < count($info); $i++) {
                 // Fill object data
                 $currentObject = array();
                 foreach ($info[$i]['cols'] as $column) {
                     if (!is_array($tempResult[$column])) {
                         // Regular column
                         $currentObject[$column] = $tempResult[$column];
                     } else {
                         // Some searching to do...
                         for ($j = $i; $j >= 0; $j--) {
                             if (isset($tempResult[$column][$j])) {
                                 $currentObject[$column] = $tempResult[$column][$j];
                                 $j = -1;
                             }
                         }
                     }
                 }
                 // Add object to result table.
                 // Row class set? If so, convert all data!
                 if ($i == 0 && $this->_data->getRowClass() != 'Zend_Db_Table_Row' || $this->_childProviders[$i - 1]->getSource()->getRowClass() != 'Zend_Db_Table_Row') {
                     $rowClass = $i == 0 ? $this->_data->getRowClass() : $this->_childProviders[$i - 1]->getSource()->getRowClass();
                     $currentResult[] = call_user_func(array($rowClass, 'fromArray'), (array) $currentObject);
                 } else {
                     $currentResult[] = (object) $currentObject;
                 }
             }
             $results[] = $currentResult;
         }
     }
     // Loop trough data source
     foreach ($results as $value) {
         // Is it a valid element?
         $isValid = true;
         // OfType expresion set? Evaluate it!
         if ($isValid && !is_null($this->_ofType)) {
             $isValid = $this->_ofType->execute($value);
         }
         // The element is valid, check if it is our selection range
         if ($isValid) {
             // Skip element?
             if (!is_null($this->_skipWhile) && $this->_skipWhile->execute($value)) {
                 $isValid = false;
             }
             // Take element?
             if (!is_null($this->_takeWhile) && !$this->_takeWhile->execute($value)) {
                 $isValid = false;
                 break;
             }
             // Add the element to the return value if it is a valid element
             if ($isValid) {
                 $returnValue[] = $selector->execute($value);
             }
         }
     }
     // TODO:
     // - join
     // - aggregates
     // - translate more SQL!
     // Return value
     return $returnValue;
 }