mirror of
https://github.com/Lastorder-DC/rhymix.git
synced 2026-05-03 01:03:28 +09:00
More work on the query parser
This commit is contained in:
parent
92ff69591f
commit
6eca8736c1
6 changed files with 422 additions and 76 deletions
|
|
@ -18,4 +18,215 @@ class Query
|
|||
public $conditions = array();
|
||||
public $groupby = null;
|
||||
public $navigation = null;
|
||||
|
||||
/**
|
||||
* Attributes for query generation.
|
||||
*/
|
||||
protected $_prefix = '';
|
||||
protected $_args = array();
|
||||
protected $_column_list = array();
|
||||
protected $_params = array();
|
||||
protected $_temp_num = 0;
|
||||
|
||||
/**
|
||||
* Generate the query string for this query.
|
||||
*
|
||||
* @param string $prefix
|
||||
* @param array $args
|
||||
* @param array $column_list
|
||||
* @return string
|
||||
*/
|
||||
public function getQueryString(string $prefix = '', array $args, array $column_list = []): string
|
||||
{
|
||||
// Save the query information.
|
||||
$this->_prefix = $prefix;
|
||||
$this->_args = $args;
|
||||
$this->_column_list = $column_list;
|
||||
$this->_temp_num = 0;
|
||||
|
||||
// Call different internal methods depending on the query type.
|
||||
switch ($this->type)
|
||||
{
|
||||
case 'SELECT':
|
||||
return $this->_getSelectQueryString();
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the query parameters to use with the query string generated above.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getQueryParams()
|
||||
{
|
||||
return $this->_params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a SELECT query string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function _getSelectQueryString(): string
|
||||
{
|
||||
// Initialize the query string.
|
||||
$result = 'SELECT ';
|
||||
|
||||
// Compose the column list.
|
||||
$columns = array();
|
||||
if ($this->_column_list)
|
||||
{
|
||||
$result .= implode(', ', array_map(function($str) {
|
||||
return '`' . $str . '`';
|
||||
}, $this->_column_list));
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($this->columns as $column)
|
||||
{
|
||||
if ($column instanceof self)
|
||||
{
|
||||
$subquery = $column->getQueryString($this->_prefix, $this->_args);
|
||||
foreach ($column->getQueryParams() as $key => $val)
|
||||
{
|
||||
$this->_params[$key] = $val;
|
||||
}
|
||||
$columns[] = sprintf('(%s) AS %s', $subquery, self::quoteName($column->alias));
|
||||
}
|
||||
elseif ($column->is_expression && !$column->is_wildcard)
|
||||
{
|
||||
$columns[] = $column->name . ($column->alias ? (' AS ' . self::quoteName($column->alias)) : '');
|
||||
}
|
||||
else
|
||||
{
|
||||
$columns[] = self::quoteName($column->name) . ($column->alias ? (' AS ' . self::quoteName($column->alias)) : '');
|
||||
}
|
||||
}
|
||||
$result .= implode(', ', $columns);
|
||||
}
|
||||
|
||||
// Compose the table list.
|
||||
$tables = array();
|
||||
foreach ($this->tables as $table)
|
||||
{
|
||||
if ($table instanceof self)
|
||||
{
|
||||
$subquery = $table->getQueryString($this->_prefix, $this->_args);
|
||||
foreach ($table->getQueryParams() as $key => $val)
|
||||
{
|
||||
$this->_params[$key] = $val;
|
||||
}
|
||||
$tables[] = sprintf('(%s) AS `%s`', $subquery, $table->alias);
|
||||
}
|
||||
else
|
||||
{
|
||||
$tabledef = self::quoteName($table->name) . ($table->alias ? (' AS `' . $table->alias . '`') : '');
|
||||
if ($table->join_type)
|
||||
{
|
||||
$tabledef = $table->join_type . ' ' . $tabledef;
|
||||
$join_where = $this->_arrangeConditions($table->join_conditions);
|
||||
if ($join_where !== '')
|
||||
{
|
||||
$tabledef = $tabledef . ' ON ' . $join_where;
|
||||
}
|
||||
}
|
||||
$tables[] = $tabledef;
|
||||
}
|
||||
}
|
||||
$result .= ' FROM ' . implode(', ', $tables);
|
||||
|
||||
// Compose the conditions.
|
||||
if (count($this->conditions))
|
||||
{
|
||||
$where = $this->_arrangeConditions($this->conditions);
|
||||
if ($where !== '')
|
||||
{
|
||||
$result .= ' WHERE ' . $where;
|
||||
}
|
||||
}
|
||||
|
||||
// Compose the GROUP BY clause.
|
||||
|
||||
// Compose the LIMIT clause.
|
||||
|
||||
// Return the final query string.
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a WHERE clause from a list of conditions.
|
||||
*
|
||||
* @param array $conditions
|
||||
* @return string
|
||||
*/
|
||||
protected function _arrangeConditions(array $conditions): string
|
||||
{
|
||||
// Initialize the result.
|
||||
$result = '';
|
||||
|
||||
// Process each condition.
|
||||
foreach ($conditions as $condition)
|
||||
{
|
||||
// Subquery
|
||||
if ($condition instanceof self)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// Condition group
|
||||
elseif ($condition instanceof ConditionGroup)
|
||||
{
|
||||
$condition_string = $this->_arrangeConditions($condition->conditions);
|
||||
if ($condition_string === '')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
$result .= ($result === '' ? '' : (' ' . $condition->pipe . ' ')) . '(' . $condition_string . ')';
|
||||
}
|
||||
|
||||
// Simple condition
|
||||
else
|
||||
{
|
||||
$condition_string = $this->_parseCondition($condition);
|
||||
if ($condition_string === '')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
$result .= ($result === '' ? '' : (' ' . $condition->pipe . ' ')) . $condition_string;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the WHERE clause.
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate each condition in a WHERE clause.
|
||||
*
|
||||
* @param object $condition
|
||||
* @return string
|
||||
*/
|
||||
protected function _parseCondition(Condition $condition): string
|
||||
{
|
||||
list($where, $params) = $condition->getQueryStringAndParams($this->_args);
|
||||
foreach ($params as $key => $val)
|
||||
{
|
||||
$this->_params[$key] = $val;
|
||||
}
|
||||
return $where;
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote a column name.
|
||||
*/
|
||||
public static function quoteName($column_name): string
|
||||
{
|
||||
$columns = explode('.', $column_name);
|
||||
$columns = array_map(function($str) {
|
||||
return $str === '*' ? $str : ('`' . $str . '`');
|
||||
}, $columns);
|
||||
return implode('.', $columns);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue