mirror of
https://github.com/Lastorder-DC/rhymix.git
synced 2026-05-08 19:42:15 +09:00
Finish the SELECT query generator
This commit is contained in:
parent
bc287b0e0f
commit
6d251dfbe1
2 changed files with 135 additions and 12 deletions
|
|
@ -26,7 +26,6 @@ class Query extends VariableBase
|
||||||
protected $_args = array();
|
protected $_args = array();
|
||||||
protected $_column_list = array();
|
protected $_column_list = array();
|
||||||
protected $_params = array();
|
protected $_params = array();
|
||||||
protected $_temp_num = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate the query string for this query.
|
* Generate the query string for this query.
|
||||||
|
|
@ -34,24 +33,32 @@ class Query extends VariableBase
|
||||||
* @param string $prefix
|
* @param string $prefix
|
||||||
* @param array $args
|
* @param array $args
|
||||||
* @param array $column_list
|
* @param array $column_list
|
||||||
|
* @param bool $count_only
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getQueryString(string $prefix = '', array $args, array $column_list = []): string
|
public function getQueryString(string $prefix = '', array $args, array $column_list = [], bool $count_only = false): string
|
||||||
{
|
{
|
||||||
// Save the query information.
|
// Save the query information.
|
||||||
$this->_prefix = $prefix;
|
$this->_prefix = $prefix;
|
||||||
$this->_args = $args;
|
$this->_args = $args;
|
||||||
$this->_column_list = $column_list;
|
$this->_column_list = $column_list;
|
||||||
$this->_temp_num = 0;
|
$this->_params = array();
|
||||||
|
|
||||||
// Call different internal methods depending on the query type.
|
// Call different internal methods depending on the query type.
|
||||||
switch ($this->type)
|
switch ($this->type)
|
||||||
{
|
{
|
||||||
case 'SELECT':
|
case 'SELECT':
|
||||||
return $this->_getSelectQueryString();
|
$result = $this->_getSelectQueryString($count_only);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return '';
|
$result = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset state and return the result.
|
||||||
|
$this->_prefix = '';
|
||||||
|
$this->_args = array();
|
||||||
|
$this->_column_list = array();
|
||||||
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -67,16 +74,21 @@ class Query extends VariableBase
|
||||||
/**
|
/**
|
||||||
* Generate a SELECT query string.
|
* Generate a SELECT query string.
|
||||||
*
|
*
|
||||||
|
* @param bool $count_only
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function _getSelectQueryString(): string
|
protected function _getSelectQueryString(bool $count_only = false): string
|
||||||
{
|
{
|
||||||
// Initialize the query string.
|
// Initialize the query string.
|
||||||
$result = 'SELECT ';
|
$result = 'SELECT ';
|
||||||
|
|
||||||
// Compose the column list.
|
// Compose the column list.
|
||||||
$columns = array();
|
$columns = array();
|
||||||
if ($this->_column_list)
|
if ($count_only)
|
||||||
|
{
|
||||||
|
$result .= 'COUNT(*) AS `count`';
|
||||||
|
}
|
||||||
|
elseif ($this->_column_list)
|
||||||
{
|
{
|
||||||
$result .= implode(', ', array_map(function($str) {
|
$result .= implode(', ', array_map(function($str) {
|
||||||
return '`' . $str . '`';
|
return '`' . $str . '`';
|
||||||
|
|
@ -140,7 +152,7 @@ class Query extends VariableBase
|
||||||
}
|
}
|
||||||
$result .= ' FROM ' . implode('', $tables);
|
$result .= ' FROM ' . implode('', $tables);
|
||||||
|
|
||||||
// Compose the conditions.
|
// Compose the WHERE clause.
|
||||||
if (count($this->conditions))
|
if (count($this->conditions))
|
||||||
{
|
{
|
||||||
$where = $this->_arrangeConditions($this->conditions);
|
$where = $this->_arrangeConditions($this->conditions);
|
||||||
|
|
@ -156,7 +168,7 @@ class Query extends VariableBase
|
||||||
$columns = array();
|
$columns = array();
|
||||||
foreach ($this->groupby->columns as $column_name)
|
foreach ($this->groupby->columns as $column_name)
|
||||||
{
|
{
|
||||||
if (preg_match('/^[a-z0-9_]+(?:\.[a-z0-9_]+)*$/', $column_name))
|
if (self::isValidColumnName($column_name))
|
||||||
{
|
{
|
||||||
$columns[] = self::quoteName($column_name);
|
$columns[] = self::quoteName($column_name);
|
||||||
}
|
}
|
||||||
|
|
@ -176,7 +188,58 @@ class Query extends VariableBase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compose the ORDER BY clause.
|
||||||
|
if ($this->navigation && count($this->navigation->orderby) && !$count_only)
|
||||||
|
{
|
||||||
|
$orderby_list = array();
|
||||||
|
foreach ($this->navigation->orderby as $orderby)
|
||||||
|
{
|
||||||
|
$column_name = '';
|
||||||
|
list($is_expression, $column_name) = $orderby->getValue($this->_args);
|
||||||
|
if (!$column_name)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!$is_expression && self::isValidColumnName($column_name))
|
||||||
|
{
|
||||||
|
$column_name = self::quoteName($column_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($this->_args[$orderby->order_var]))
|
||||||
|
{
|
||||||
|
$column_order = preg_replace('/[^A-Z]/', '', strtoupper($this->_args[$orderby->order_var]));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$column_order = preg_replace('/[^A-Z]/', '', strtoupper($orderby->order_default));
|
||||||
|
}
|
||||||
|
|
||||||
|
$orderby_list[] = $column_name . ' ' . $column_order;
|
||||||
|
}
|
||||||
|
$result .= ' ORDER BY ' . implode(', ', $orderby_list);
|
||||||
|
}
|
||||||
|
|
||||||
// Compose the LIMIT clause.
|
// Compose the LIMIT clause.
|
||||||
|
if ($this->navigation && $this->navigation->list_count && !$count_only)
|
||||||
|
{
|
||||||
|
list($is_expression, $list_count) = $this->navigation->list_count->getValue($this->_args);
|
||||||
|
if ($list_count > 0)
|
||||||
|
{
|
||||||
|
if ($this->navigation->page)
|
||||||
|
{
|
||||||
|
list($is_expression, $page) = $this->navigation->page->getValue($this->_args);
|
||||||
|
}
|
||||||
|
if ($this->navigation->offset)
|
||||||
|
{
|
||||||
|
list($is_expression, $offset) = $this->navigation->offset->getValue($this->_args);
|
||||||
|
}
|
||||||
|
if ($page > 0)
|
||||||
|
{
|
||||||
|
$offset = $list_count * ($page - 1);
|
||||||
|
}
|
||||||
|
$result .= ' LIMIT ' . ($offset > 0 ? (intval($offset) . ', ') : '') . intval($list_count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Return the final query string.
|
// Return the final query string.
|
||||||
return $result;
|
return $result;
|
||||||
|
|
@ -249,8 +312,11 @@ class Query extends VariableBase
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Quote a column name.
|
* Quote a column name.
|
||||||
|
*
|
||||||
|
* @param string $column_name
|
||||||
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function quoteName($column_name): string
|
public static function quoteName(string $column_name): string
|
||||||
{
|
{
|
||||||
$columns = explode('.', $column_name);
|
$columns = explode('.', $column_name);
|
||||||
$columns = array_map(function($str) {
|
$columns = array_map(function($str) {
|
||||||
|
|
@ -258,4 +324,40 @@ class Query extends VariableBase
|
||||||
}, $columns);
|
}, $columns);
|
||||||
return implode('.', $columns);
|
return implode('.', $columns);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a column name is valid.
|
||||||
|
*
|
||||||
|
* @param string $column_name
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function isValidColumnName(string $column_name): bool
|
||||||
|
{
|
||||||
|
return preg_match('/^[a-z][a-z0-9_]*(?:\.[a-z][a-z0-9_]*)*$/i', $column_name) ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a variable is considered valid for XE compatibility.
|
||||||
|
*
|
||||||
|
* @param mixed $var
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function isValidVariable($var): bool
|
||||||
|
{
|
||||||
|
if ($var === null || $var === '')
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_array($var))
|
||||||
|
{
|
||||||
|
$count = count($var);
|
||||||
|
if ($count === 0 || ($count === 1 && reset($var) === ''))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ class VariableBase
|
||||||
$params = array();
|
$params = array();
|
||||||
|
|
||||||
// Process the variable or default value.
|
// Process the variable or default value.
|
||||||
if ($this->var && isset($args[$this->var]) && (!is_array($args[$this->var]) || count($args[$this->var]) > 1 || $args[$this->var] !== ['']))
|
if ($this->var && Query::isValidVariable($args[$this->var]))
|
||||||
{
|
{
|
||||||
$this->filterValue($args[$this->var]);
|
$this->filterValue($args[$this->var]);
|
||||||
$is_expression = false;
|
$is_expression = false;
|
||||||
|
|
@ -223,6 +223,27 @@ class VariableBase
|
||||||
return [$where, $params];
|
return [$where, $params];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current value, falling back to the default value if necessary.
|
||||||
|
*
|
||||||
|
* @param array $args
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getValue(array $args)
|
||||||
|
{
|
||||||
|
if ($this->var && Query::isValidVariable($args[$this->var]))
|
||||||
|
{
|
||||||
|
$is_expression = false;
|
||||||
|
$value = $args[$this->var];
|
||||||
|
}
|
||||||
|
elseif ($this->default !== null)
|
||||||
|
{
|
||||||
|
list($is_expression, $value) = $this->getDefaultValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
return [$is_expression, $value];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the default value of this variable.
|
* Get the default value of this variable.
|
||||||
*
|
*
|
||||||
|
|
@ -231,7 +252,7 @@ class VariableBase
|
||||||
public function getDefaultValue()
|
public function getDefaultValue()
|
||||||
{
|
{
|
||||||
// If the default value is a column name, escape it.
|
// If the default value is a column name, escape it.
|
||||||
if (preg_match('/^[a-z0-9_]+(?:\.[a-z0-9_]+)+$/', $this->default))
|
if (strpos($this->default, '.') !== false && Query::isValidColumnName($this->default))
|
||||||
{
|
{
|
||||||
return [true, Query::quoteName($this->default)];
|
return [true, Query::quoteName($this->default)];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue