📄 dbo_source.php
字号:
* @return boolean Success */ function update(&$model, $fields = array(), $values = null, $conditions = null) { if ($values == null) { $combined = $fields; } else { $combined = array_combine($fields, $values); } $fields = join(', ', $this->_prepareUpdateFields($model, $combined, empty($conditions))); $alias = $joins = null; $table = $this->fullTableName($model); $conditions = $this->_matchRecords($model, $conditions); if ($conditions === false) { return false; } if (!$this->execute($this->renderStatement('update', compact('table', 'alias', 'joins', 'fields', 'conditions')))) { $model->onError(); return false; } return true; }/** * Quotes and prepares fields and values for an SQL UPDATE statement * * @param Model $model * @param array $fields * @param boolean $quoteValues If values should be quoted, or treated as SQL snippets * @param boolean $alias Include the model alias in the field name * @return array Fields and values, quoted and preparted * @access protected */ function _prepareUpdateFields(&$model, $fields, $quoteValues = true, $alias = false) { $quotedAlias = $this->startQuote . $model->alias . $this->startQuote; foreach ($fields as $field => $value) { if ($alias && strpos($field, '.') === false) { $quoted = $model->escapeField($field); } elseif (!$alias && strpos($field, '.') !== false) { $quoted = $this->name(str_replace($quotedAlias . '.', '', str_replace( $model->alias . '.', '', $field ))); } else { $quoted = $this->name($field); } if ($value === null) { $updates[] = $quoted . ' = NULL'; } else { $update = $quoted . ' = '; if ($quoteValues) { $update .= $this->value($value, $model->getColumnType($field)); } elseif (!$alias) { $update .= str_replace($quotedAlias . '.', '', str_replace( $model->alias . '.', '', $value )); } else { $update .= $value; } $updates[] = $update; } } return $updates; }/** * Generates and executes an SQL DELETE statement. * For databases that do not support aliases in UPDATE queries. * * @param Model $model * @param mixed $conditions * @return boolean Success */ function delete(&$model, $conditions = null) { $alias = $joins = null; $table = $this->fullTableName($model); $conditions = $this->_matchRecords($model, $conditions); if ($conditions === false) { return false; } if ($this->execute($this->renderStatement('delete', compact('alias', 'table', 'joins', 'conditions'))) === false) { $model->onError(); return false; } return true; }/** * Gets a list of record IDs for the given conditions. Used for multi-record updates and deletes * in databases that do not support aliases in UPDATE/DELETE queries. * * @param Model $model * @param mixed $conditions * @return array List of record IDs * @access protected */ function _matchRecords(&$model, $conditions = null) { if ($conditions === true) { $conditions = $this->conditions(true); } elseif ($conditions === null) { $conditions = $this->conditions($this->defaultConditions($model, $conditions, false), true, true, $model); } else { $idList = $model->find('all', array( 'fields' => "{$model->alias}.{$model->primaryKey}", 'conditions' => $conditions )); if (empty($idList)) { return false; } $conditions = $this->conditions(array( $model->primaryKey => Set::extract($idList, "{n}.{$model->alias}.{$model->primaryKey}") )); } return $conditions; }/** * Returns an array of SQL JOIN fragments from a model's associations * * @param object $model * @return array */ function _getJoins($model) { $join = array(); $joins = array_merge($model->getAssociated('hasOne'), $model->getAssociated('belongsTo')); foreach ($joins as $assoc) { if (isset($model->{$assoc}) && $model->useDbConfig == $model->{$assoc}->useDbConfig) { $assocData = $model->getAssociated($assoc); $join[] = $this->buildJoinStatement(array( 'table' => $this->fullTableName($model->{$assoc}), 'alias' => $assoc, 'type' => isset($assocData['type']) ? $assocData['type'] : 'LEFT', 'conditions' => trim($this->conditions( $this->getConstraint($assocData['association'], $model, $model->{$assoc}, $assoc, $assocData), true, false, $model )) )); } } return $join; }/** * Returns the an SQL calculation, i.e. COUNT() or MAX() * * @param model $model * @param string $func Lowercase name of SQL function, i.e. 'count' or 'max' * @param array $params Function parameters (any values must be quoted manually) * @return string An SQL calculation function * @access public */ function calculate(&$model, $func, $params = array()) { $params = (array)$params; switch (strtolower($func)) { case 'count': if (!isset($params[0])) { $params[0] = '*'; } if (!isset($params[1])) { $params[1] = 'count'; } return 'COUNT(' . $this->name($params[0]) . ') AS ' . $this->name($params[1]); case 'max': case 'min': if (!isset($params[1])) { $params[1] = $params[0]; } return strtoupper($func) . '(' . $this->name($params[0]) . ') AS ' . $this->name($params[1]); break; } }/** * Deletes all the records in a table and resets the count of the auto-incrementing * primary key, where applicable. * * @param mixed $table A string or model class representing the table to be truncated * @return boolean SQL TRUNCATE TABLE statement, false if not applicable. * @access public */ function truncate($table) { return $this->execute('TRUNCATE TABLE ' . $this->fullTableName($table)); }/** * Begin a transaction * * @param model $model * @return boolean True on success, false on fail * (i.e. if the database/model does not support transactions, * or a transaction has not started). */ function begin(&$model) { if (parent::begin($model) && $this->execute($this->_commands['begin'])) { $this->_transactionStarted = true; return true; } return false; }/** * Commit a transaction * * @param model $model * @return boolean True on success, false on fail * (i.e. if the database/model does not support transactions, * or a transaction has not started). */ function commit(&$model) { if (parent::commit($model) && $this->execute($this->_commands['commit'])) { $this->_transactionStarted = false; return true; } return false; }/** * Rollback a transaction * * @param model $model * @return boolean True on success, false on fail * (i.e. if the database/model does not support transactions, * or a transaction has not started). */ function rollback(&$model) { if (parent::rollback($model) && $this->execute($this->_commands['rollback'])) { $this->_transactionStarted = false; return true; } return false; }/** * Creates a default set of conditions from the model if $conditions is null/empty. * * @param object $model * @param mixed $conditions * @param boolean $useAlias Use model aliases rather than table names when generating conditions * @return mixed */ function defaultConditions(&$model, $conditions, $useAlias = true) { if (!empty($conditions)) { return $conditions; } if (!$model->exists()) { return false; } $alias = $model->alias; if (!$useAlias) { $alias = $this->fullTableName($model, false); } return array("{$alias}.{$model->primaryKey}" => $model->getID()); }/** * Returns a key formatted like a string Model.fieldname(i.e. Post.title, or Country.name) * * @param unknown_type $model * @param unknown_type $key * @param unknown_type $assoc * @return string */ function resolveKey($model, $key, $assoc = null) { if (empty($assoc)) { $assoc = $model->alias; } if (!strpos('.', $key)) { return $this->name($model->alias) . '.' . $this->name($key); } return $key; }/** * Private helper method to remove query metadata in given data array. * * @param array $data * @return array */ function __scrubQueryData($data) { foreach (array('conditions', 'fields', 'joins', 'order', 'limit', 'offset', 'group') as $key) { if (!isset($data[$key]) || empty($data[$key])) { $data[$key] = array(); } } return $data; }/** * Generates the fields list of an SQL query. * * @param Model $model * @param string $alias Alias tablename * @param mixed $fields * @param boolean $quote If false, returns fields array unquoted * @return array */ function fields(&$model, $alias = null, $fields = array(), $quote = true) { if (empty($alias)) { $alias = $model->alias; } if (empty($fields)) { $fields = array_keys($model->schema()); } elseif (!is_array($fields)) { $fields = String::tokenize($fields); } $fields = array_values(array_filter($fields)); if (!$quote) { return $fields; } $count = count($fields); if ($count >= 1 && !in_array($fields[0], array('*', 'COUNT(*)'))) { for ($i = 0; $i < $count; $i++) { if (!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) { $fields[$i] = $this->name($alias . '.' . $fields[$i]); } else { $value = array(); $comma = strpos($fields[$i], ','); if ($comma === false) { $build = explode('.', $fields[$i]); if (!Set::numeric($build)) { $fields[$i] = $this->name($build[0] . '.' . $build[1]); } $comma = String::tokenize($fields[$i]); foreach ($comma as $string) { if (preg_match('/^[0-9]+\.[0-9]+$/', $string)) { $value[] = $string; } else { $build = explode('.', $string); $value[] = $this->name(trim($build[0]) . '.' . trim($build[1])); } } $fields[$i] = implode(', ', $value); } } $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 (!Set::numeric($field[0])) { $field[0] = join('.', array_map(array($this, 'name'), $field[0])); $fields[$i] = preg_replace('/\(' . $field[1] . '\)/', '(' . $field[0] . ')', $fields[$i], 1); } } } } } } return array_unique($fields); }/** * Creates a WHERE clause by parsing given conditions data. * * @param mixed $conditions Array or string of conditions * @param boolean $quoteValues If true, values should be quoted * @param boolean $where If true, "WHERE " will be prepended to the return value * @param Model $model A reference to the Model instance making the query * @return string SQL fragment */ function conditions($conditions, $quoteValues = true, $where = true, $model = null) { $clause = $out = ''; if (is_string($conditions) || empty($conditions) || $conditions === true) { if (empty($conditions) || trim($conditions) == '' || $conditions === true) { if ($where) { return ' WHERE 1 = 1'; } return '1 = 1'; } if (!preg_match('/^WHERE\\x20|^GROUP\\x20BY\\x20|^HAVING\\x20|^ORDER\\x20BY\\x20/i', $conditions, $match)) { if ($where) { $clause = ' WHERE '; } } if (trim($conditions) == '') { $conditions = ' 1 = 1'; } else { $conditions = $this->__quoteFields($conditions); } return $clause . $conditions; } else { if ($where) { $clause = ' WHERE '; } if (!empty($conditions)) { $out = $this->conditionKeysToString($conditions, $quoteValues, $model); } if (empty($out) || empty($conditions)) { return $clause . ' 1 = 1'; } return $clause . join(' AND ', $out); } }/** * Creates a WHERE clause by parsing given conditions array. Used by DboSource::conditions(). * * @param array $conditions Array or string of conditions * @param boolean $quoteValues If true, values should be quoted * @param Model $model A reference to the Model instance making the query * @return string SQL fragment */ function conditionKeysToString($conditions, $quoteValues = true, $model = null) { $c = 0; $out = array(); $data = $columnType = null; $bool = array('and', 'or', 'not', 'and not', 'or not', 'xor', '||', '&&'); foreach ($conditions as $key => $value) { $join = ' AND '; $not = null; if (is_array($value)) { $valueInsert = ( !empty($value) && (substr_count($key, '?') == count($value) || substr_count($key, ':') == count($value)) ); } if (is_numeric($key) && empty($value)) { continue; } elseif (is_numeric($key) && is_string($value)) { $out[] = $not . $this->__quoteFields($value); } elseif ((is_numeric($key) && is_array($value)) || in_array(strtolower(trim($key)), $bool)) { if (in_array(strtolower(trim($key)), $bool)) { $join = ' ' . strtoupper($key) . ' '; } else { $key = $join; } $value = $this->conditionKeysToString($value, $quoteValues, $model); if (strpos($join, 'NOT') !== false) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -