DboSource::fields PHP Method

fields() public method

Generates the fields list of an SQL query.
public fields ( Model $Model, string $alias = null, mixed $fields = [], boolean $quote = true ) : array
$Model Model The model to get fields for.
$alias string Alias table name
$fields mixed The provided list of fields.
$quote boolean If false, returns fields array unquoted
return array
    public function fields(Model $Model, $alias = null, $fields = array(), $quote = true)
    {
        if (empty($alias)) {
            $alias = $Model->alias;
        }
        $virtualFields = $Model->getVirtualField();
        $cacheKey = array($alias, get_class($Model), $Model->alias, $virtualFields, $fields, $quote, ConnectionManager::getSourceName($this), $Model->schemaName, $Model->table);
        $cacheKey = md5(serialize($cacheKey));
        if ($return = $this->cacheMethod(__FUNCTION__, $cacheKey)) {
            return $return;
        }
        $allFields = empty($fields);
        if ($allFields) {
            $fields = array_keys($Model->schema());
        } elseif (!is_array($fields)) {
            $fields = CakeText::tokenize($fields);
        }
        $fields = array_values(array_filter($fields));
        $allFields = $allFields || in_array('*', $fields) || in_array($Model->alias . '.*', $fields);
        $virtual = array();
        if (!empty($virtualFields)) {
            $virtualKeys = array_keys($virtualFields);
            foreach ($virtualKeys as $field) {
                $virtualKeys[] = $Model->alias . '.' . $field;
            }
            $virtual = $allFields ? $virtualKeys : array_intersect($virtualKeys, $fields);
            foreach ($virtual as $i => $field) {
                if (strpos($field, '.') !== false) {
                    $virtual[$i] = str_replace($Model->alias . '.', '', $field);
                }
                $fields = array_diff($fields, array($field));
            }
            $fields = array_values($fields);
        }
        if (!$quote) {
            if (!empty($virtual)) {
                $fields = array_merge($fields, $this->_constructVirtualFields($Model, $alias, $virtual));
            }
            return $fields;
        }
        $count = count($fields);
        if ($count >= 1 && !in_array($fields[0], array('*', 'COUNT(*)'))) {
            for ($i = 0; $i < $count; $i++) {
                if (is_string($fields[$i]) && in_array($fields[$i], $virtual)) {
                    unset($fields[$i]);
                    continue;
                }
                if (is_object($fields[$i]) && isset($fields[$i]->type) && $fields[$i]->type === 'expression') {
                    $fields[$i] = $fields[$i]->value;
                } elseif (preg_match('/^\\(.*\\)\\s' . $this->alias . '.*/i', $fields[$i])) {
                    continue;
                } elseif (!preg_match('/^.+\\(.*\\)/', $fields[$i])) {
                    $prepend = '';
                    if (strpos($fields[$i], 'DISTINCT') !== false) {
                        $prepend = 'DISTINCT ';
                        $fields[$i] = trim(str_replace('DISTINCT', '', $fields[$i]));
                    }
                    $dot = strpos($fields[$i], '.');
                    if ($dot === false) {
                        $prefix = !(strpos($fields[$i], ' ') !== false || strpos($fields[$i], '(') !== false);
                        $fields[$i] = $this->name(($prefix ? $alias . '.' : '') . $fields[$i]);
                    } else {
                        if (strpos($fields[$i], ',') === false) {
                            $build = explode('.', $fields[$i]);
                            if (!Hash::numeric($build)) {
                                $fields[$i] = $this->name(implode('.', $build));
                            }
                        }
                    }
                    $fields[$i] = $prepend . $fields[$i];
                } elseif (preg_match('/\\(([\\.\\w]+)\\)/', $fields[$i], $field)) {
                    if (isset($field[1])) {
                        if (strpos($field[1], '.') === false) {
                            $field[1] = $this->name($alias . '.' . $field[1]);
                        } else {
                            $field[0] = explode('.', $field[1]);
                            if (!Hash::numeric($field[0])) {
                                $field[0] = implode('.', array_map(array(&$this, 'name'), $field[0]));
                                $fields[$i] = preg_replace('/\\(' . $field[1] . '\\)/', '(' . $field[0] . ')', $fields[$i], 1);
                            }
                        }
                    }
                }
            }
        }
        if (!empty($virtual)) {
            $fields = array_merge($fields, $this->_constructVirtualFields($Model, $alias, $virtual));
        }
        return $this->cacheMethod(__FUNCTION__, $cacheKey, array_unique($fields));
    }

Usage Example

Example #1
0
 /**
  * sql insert statement
  *
  * @param $datasource
  * @param $tablename
  * @param $exclude_missing_tables
  * @param $return if want return sql string, set true.
  * @return string
  */
 function getInsertSql($datasource, $tablename, $exclude_missing_tables = false, $return = false)
 {
     if (!$this->_checkCurrentDatasource($datasource)) {
         $this->_setupDataSource();
     }
     if (!$return && (empty($this->File) || !$this->File->writable())) {
         return false;
     }
     $tables = $this->_getProcessTables($tablename, $exclude_missing_tables);
     $insert_sql = '';
     foreach ($tables as $table => $fields) {
         /* @var $model AppModel */
         $model = ClassRegistry::init(array('class' => Inflector::classify($table), 'table' => $table));
         $field_names = array_keys($this->DataSource->describe($model));
         $full_tablename = $this->DataSource->fullTableName($model);
         $all_fields = implode(', ', array_map(array($this->DataSource, 'name'), $field_names));
         $count_query = array('table' => $full_tablename, 'fields' => 'count(*) ' . $this->DataSource->alias . 'count', 'alias' => $this->DataSource->alias . $this->DataSource->name($model->alias), 'joins' => '', 'conditions' => 'WHERE 1=1', 'group' => '', 'order' => '', 'limit' => '');
         $count_sql = $this->DataSource->renderStatement('select', $count_query);
         $total = $this->DataSource->fetchRow($count_sql);
         if (is_array($total)) {
             $total = $total[0]['count'];
         }
         $query = array('table' => $full_tablename, 'fields' => implode(', ', $this->DataSource->fields($model)), 'alias' => $this->DataSource->alias . $this->DataSource->name($model->alias), 'joins' => '', 'conditions' => '', 'group' => '', 'order' => '', 'limit' => '');
         $limit = 100;
         $record = array();
         for ($offset = 0; $offset < $total; $offset += $limit) {
             $query['limit'] = $this->DataSource->limit($limit, $offset);
             $select_sql = $this->DataSource->renderStatement('select', $query);
             $datas = $this->DataSource->fetchAll($select_sql, false);
             foreach ($datas as $record) {
                 $insert_query = array('table' => $full_tablename, 'fields' => $all_fields, 'values' => implode(', ', array_map(array($this->DataSource, 'value'), array_values($record[$model->alias]))));
                 $_sql = $this->out($this->DataSource->renderStatement('create', $insert_query) . ';');
                 if ($return) {
                     $insert_sql .= $_sql;
                 }
             }
         }
         // -- sequence update section for postgres
         // NOTE: only primary key sequence..
         if (method_exists($this->DataSource, 'getSequence')) {
             foreach ($fields as $field => $column) {
                 if ($field == 'indexes' || empty($record)) {
                     continue;
                 }
                 if ($column['type'] == 'integer' && isset($column['key']) && $column['key'] == 'primary') {
                     // only primary key
                     $sequence_name = $this->DataSource->getSequence($this->DataSource->fullTableName($model, false), $field);
                     $_sql = $this->out(sprintf('SELECT setval(%s, %s);', $this->DataSource->value($sequence_name), $record[$model->alias][$field]));
                     if ($return) {
                         $insert_sql .= $_sql;
                     }
                 }
             }
         }
     }
     return $insert_sql;
 }
All Usage Examples Of DboSource::fields
DboSource