You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
123 lines
3.4 KiB
123 lines
3.4 KiB
<?php |
|
/** |
|
* @link http://www.yiiframework.com/ |
|
* @copyright Copyright (c) 2008 Yii Software LLC |
|
* @license http://www.yiiframework.com/license/ |
|
*/ |
|
|
|
namespace yii\sphinx; |
|
use yii\db\Expression; |
|
|
|
/** |
|
* Class QueryBuilder |
|
* |
|
* @author Paul Klimov <klimov.paul@gmail.com> |
|
* @since 2.0 |
|
*/ |
|
class QueryBuilder extends \yii\db\mysql\QueryBuilder |
|
{ |
|
/** |
|
* Generates a SELECT SQL statement from a [[Query]] object. |
|
* @param Query $query the [[Query]] object from which the SQL statement will be generated |
|
* @return array the generated SQL statement (the first array element) and the corresponding |
|
* parameters to be bound to the SQL statement (the second array element). |
|
*/ |
|
public function build($query) |
|
{ |
|
$params = $query->params; |
|
$clauses = [ |
|
$this->buildSelect($query->select, $query->distinct, $query->selectOption), |
|
$this->buildFrom($query->from), |
|
$this->buildWhere($query->where, $params), |
|
$this->buildGroupBy($query->groupBy), |
|
$this->buildWithin($query->within), |
|
$this->buildOrderBy($query->orderBy), |
|
$this->buildLimit($query->limit, $query->offset), |
|
$this->buildOption($query->options), |
|
]; |
|
return [implode($this->separator, array_filter($clauses)), $params]; |
|
} |
|
|
|
/** |
|
* @param array $columns |
|
* @return string the ORDER BY clause built from [[query]]. |
|
*/ |
|
public function buildWithin($columns) |
|
{ |
|
if (empty($columns)) { |
|
return ''; |
|
} |
|
$orders = []; |
|
foreach ($columns as $name => $direction) { |
|
if (is_object($direction)) { |
|
$orders[] = (string)$direction; |
|
} else { |
|
$orders[] = $this->db->quoteColumnName($name) . ($direction === Query::SORT_DESC ? ' DESC' : ''); |
|
} |
|
} |
|
return 'WITHIN GROUP ORDER BY ' . implode(', ', $orders); |
|
} |
|
|
|
/** |
|
* @param array $options |
|
* @return string the OPTION clause build from [[query]] |
|
*/ |
|
public function buildOption(array $options) |
|
{ |
|
if (empty($options)) { |
|
return ''; |
|
} |
|
$optionLines = []; |
|
foreach ($options as $name => $value) { |
|
$optionLines[] = $name . ' = ' . $value; |
|
} |
|
return 'OPTION ' . implode(', ', $optionLines); |
|
} |
|
|
|
/** |
|
* Creates an INSERT SQL statement. |
|
* For example, |
|
* |
|
* ~~~ |
|
* $sql = $queryBuilder->insert('tbl_user', [ |
|
* 'name' => 'Sam', |
|
* 'age' => 30, |
|
* ], $params); |
|
* ~~~ |
|
* |
|
* The method will properly escape the table and column names. |
|
* |
|
* @param string $table the table that new rows will be inserted into. |
|
* @param array $columns the column data (name => value) to be inserted into the table. |
|
* @param array $params the binding parameters that will be generated by this method. |
|
* They should be bound to the DB command later. |
|
* @return string the INSERT SQL |
|
*/ |
|
public function insert($table, $columns, &$params) |
|
{ |
|
if (($tableSchema = $this->db->getTableSchema($table)) !== null) { |
|
$columnSchemas = $tableSchema->columns; |
|
} else { |
|
$columnSchemas = []; |
|
} |
|
$names = []; |
|
$placeholders = []; |
|
foreach ($columns as $name => $value) { |
|
$names[] = $this->db->quoteColumnName($name); |
|
if ($value instanceof Expression) { |
|
$placeholders[] = $value->expression; |
|
foreach ($value->params as $n => $v) { |
|
$params[$n] = $v; |
|
} |
|
} else { |
|
$phName = self::PARAM_PREFIX . count($params); |
|
$placeholders[] = $phName; |
|
$params[$phName] = !is_array($value) && isset($columnSchemas[$name]) ? $columnSchemas[$name]->typecast($value) : $value; |
|
} |
|
} |
|
|
|
return 'INSERT INTO ' . $this->db->quoteTableName($table) |
|
. ' (' . implode(', ', $names) . ') VALUES (' |
|
. implode(', ', $placeholders) . ')'; |
|
} |
|
} |