Exemple #1
0
 /**
  * Return result rowset.
  *
  * @param string $type Return result as: all, first, last, one, count
  * @param array $cond Conditions
  *  - count (int): Count of rows in result set
  *  - page (int): Current page number (start from 1)
  *  - columns (array): Column names
  *  - where (array): Pairs `column=>$value` or `column_with_value`
  *  - group (array): Group by columns
  *  - order (array): Sorting by columns
  * @return Days_Db_Rowset|Days_Db_Row|int|null
  */
 public function find($type = 'last', array $cond = array())
 {
     // check parameters
     if (!isset($cond['page']) or !is_numeric($cond['page']) or $cond['page'] < 1) {
         $cond['page'] = 1;
     }
     // check columns
     if (!isset($cond['columns'])) {
         $cond['columns'] = '*';
     }
     // get select object
     $select = $this->_select->from($this->_name, $cond['columns']);
     // join with tables
     foreach (array_unique($this->_join) as $joinTable) {
         $currentTable = $this->name();
         $joinId = "_{$joinTable}_id";
         $currentId = "_{$currentTable}_id";
         // 1x1
         if (is_array($this->info($joinId))) {
             $select->join($joinTable, "{$this->_quote($currentTable)}.{$this->_quote($joinId)}={$this->_quote($joinTable)}.{$this->_quote($joinId)}", array());
         } elseif (is_array($this->info($currentId, $joinTable))) {
             $select->join($joinTable, "{$this->_quote($currentTable)}.{$this->_quote($currentId)}={$this->_quote($joinTable)}.{$this->_quote($currentId)}", array());
         } else {
             // table name (or equivalent table view)
             $centerTable = "_{$joinTable}-{$currentTable}";
             $select->join($centerTable, "{$this->_quote($currentTable)}.{$this->_quote($currentId)}={$this->_quote($centerTable)}.{$this->_quote($currentId)}", array());
             $select->join($joinTable, "{$this->_quote($centerTable)}.{$this->_quote($joinId)}={$this->_quote($joinTable)}.{$this->_quote($joinId)}", array());
         }
     }
     // set limit
     if (isset($cond['count']) and is_numeric($cond['count']) and $cond['count'] > 0) {
         $select->limitPage($cond['page'], $cond['count']);
     }
     // set where conditions
     if (isset($cond['where'])) {
         if (!is_array($cond['where'])) {
             $cond['where'] = array($cond['where']);
         }
         foreach ($cond['where'] as $name => $value) {
             // set condition with inserted value
             if (is_numeric($name)) {
                 $select->where($value);
             } else {
                 // replace magic column names
                 preg_match('`([a-z0-9_.]+) *(<|>|<=|>=|<>|!=|=|IN|NOT IN)?`i', $name, $mathes);
                 // real column name (from magic column name)
                 $column = $this->column($mathes[1]);
                 $sign = isset($mathes[2]) ? strtoupper($mathes[2]) : '=';
                 // many values in one position
                 if (is_array($value) and count($value) > 1 and 'NOT IN' != $sign) {
                     $sign = 'IN';
                 }
                 $question = ('IN' == $sign or 'NOT IN' == $sign) ? '(?)' : '?';
                 $name = "{$column} {$sign} {$question}";
                 $select->where($name, $value);
             }
         }
     }
     // set group by
     if (isset($cond['group'])) {
         $select->group($cond['group']);
     }
     // set sorting order
     if (isset($cond['order'])) {
         $select->order($cond['order']);
     }
     // profile SQL query
     Days_Log::profile((string) $select, 'Db_Table', Days_Log::PROFILE);
     // fetch result
     $rowset = new Days_Db_Rowset($this);
     switch ($type) {
         case 'all':
             $results = $select->query();
             while ($row = $results->fetch(Zend_Db::FETCH_ASSOC)) {
                 if (is_array($row)) {
                     $rowset[] = new Days_Db_Row($row, $this, $rowset);
                 }
             }
             break;
         case 'last':
             $results = $select->order("{$this->_order} DESC")->query();
             while ($row = $results->fetch(Zend_Db::FETCH_ASSOC)) {
                 if (is_array($row)) {
                     $rowset[] = new Days_Db_Row($row, $this, $rowset);
                 }
             }
             break;
         case 'first':
             $results = $select->order("{$this->_order} ASC")->query();
             while ($row = $results->fetch(Zend_Db::FETCH_ASSOC)) {
                 if (is_array($row)) {
                     $rowset[] = new Days_Db_Row($row, $this, $rowset);
                 }
             }
             break;
         case 'one':
             $row = $select->limit(1)->query()->fetch(Zend_Db::FETCH_ASSOC);
             $rowset = is_array($row) ? new Days_Db_Row($row, $this, $rowset) : null;
             break;
         case 'count':
             $rowset = $select->reset(Zend_Db_Select::FROM)->reset(Zend_Db_Select::COLUMNS)->from($this->_name, array('sum' => 'COUNT(*)'))->query()->fetch(Zend_Db::FETCH_COLUMN);
             break;
         default:
             throw new Days_Exception("Passed incorrect result type '{$type}' in find() method");
     }
     // reset table object for new query
     $select->reset();
     $this->_join = array();
     // return result rowset
     return $rowset;
 }