mirror of
https://github.com/Lastorder-DC/rhymix.git
synced 2026-01-04 17:21:39 +09:00
More work on the query parser
This commit is contained in:
parent
20025077f7
commit
b912c623e2
8 changed files with 183 additions and 34 deletions
|
|
@ -5,12 +5,15 @@ namespace Rhymix\Framework\Parsers\DBQuery;
|
|||
/**
|
||||
* Condition class.
|
||||
*/
|
||||
class Condition extends GenericVar
|
||||
class Condition extends VariableBase
|
||||
{
|
||||
public $operation;
|
||||
public $column;
|
||||
public $var;
|
||||
public $default;
|
||||
public $not_null;
|
||||
public $operator = 'AND';
|
||||
public $filter;
|
||||
public $minlength = 0;
|
||||
public $maxlength = 0;
|
||||
public $pipe = 'AND';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,5 +8,5 @@ namespace Rhymix\Framework\Parsers\DBQuery;
|
|||
class ConditionGroup
|
||||
{
|
||||
public $conditions = array();
|
||||
public $operator = 'AND';
|
||||
public $pipe = 'AND';
|
||||
}
|
||||
|
|
|
|||
49
common/framework/parsers/dbquery/expression.php
Normal file
49
common/framework/parsers/dbquery/expression.php
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
namespace Rhymix\Framework\Parsers\DBQuery;
|
||||
|
||||
/**
|
||||
* Expression class.
|
||||
*/
|
||||
class Expression
|
||||
{
|
||||
/**
|
||||
* Instance properties.
|
||||
*/
|
||||
public $type;
|
||||
public $value;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $type
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function __construct(string $type, $value = null)
|
||||
{
|
||||
$this->type = $type;
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the string representation of this expression.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
switch ($this->type)
|
||||
{
|
||||
case 'var':
|
||||
return ':' . $this->value;
|
||||
case 'null':
|
||||
return 'NULL';
|
||||
case 'string':
|
||||
return;
|
||||
case 'int':
|
||||
return $this->value;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rhymix\Framework\Parsers\DBQuery;
|
||||
|
||||
/**
|
||||
* GenericVar class.
|
||||
*/
|
||||
class GenericVar
|
||||
{
|
||||
public $var;
|
||||
public $default;
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@ namespace Rhymix\Framework\Parsers\DBQuery;
|
|||
/**
|
||||
* OrderBy class.
|
||||
*/
|
||||
class OrderBy extends GenericVar
|
||||
class OrderBy extends VariableBase
|
||||
{
|
||||
public $var;
|
||||
public $default;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,9 @@ class Query
|
|||
public $name;
|
||||
public $alias;
|
||||
public $type;
|
||||
public $operation;
|
||||
public $column;
|
||||
public $pipe;
|
||||
public $tables = array();
|
||||
public $columns = array();
|
||||
public $conditions = array();
|
||||
|
|
|
|||
76
common/framework/parsers/dbquery/variablebase.php
Normal file
76
common/framework/parsers/dbquery/variablebase.php
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
|
||||
namespace Rhymix\Framework\Parsers\DBQuery;
|
||||
|
||||
/**
|
||||
* VariableBase class.
|
||||
*/
|
||||
class VariableBase
|
||||
{
|
||||
/**
|
||||
* Instance properties.
|
||||
*/
|
||||
public $var;
|
||||
public $default;
|
||||
|
||||
/**
|
||||
* Get the value of this variable.
|
||||
*
|
||||
* @return Expression
|
||||
*/
|
||||
public function getValue(): Expression
|
||||
{
|
||||
if ($this->var)
|
||||
{
|
||||
return new Expression('var', $this->var);
|
||||
}
|
||||
else
|
||||
{
|
||||
return $this->getDefaultValue();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default value of this variable.
|
||||
*
|
||||
* @return Expression
|
||||
*/
|
||||
public function getDefaultValue(): Expression
|
||||
{
|
||||
// If the default value is not set, return null.
|
||||
$val = $this->default;
|
||||
if ($val === null)
|
||||
{
|
||||
return new Expression('null');
|
||||
}
|
||||
|
||||
// If the default value is a function shortcut, return an appropriate value.
|
||||
switch ($val)
|
||||
{
|
||||
case 'ipaddress()':
|
||||
return new Expression('string', \RX_CLIENT_IP);
|
||||
case 'unixtime()':
|
||||
return new Expression('string', time());
|
||||
case 'curdate()':
|
||||
case 'date()':
|
||||
return new Expression('string', date('YmdHis'));
|
||||
case 'sequence()':
|
||||
return new Expression('int', getNextSequence());
|
||||
}
|
||||
|
||||
// If the default value is a calculation based on the current value, return a query string.
|
||||
if (isset($this->column) && preg_match('/^(plus|minus|multiply)\(([0-9]+)\)$/', $val, $matches))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// If the default value is a column name, return the column name.20
|
||||
if (\Rhymix\Framework\Parsers\DBQueryParser::isValidColumnName($val))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Otherwise, return the literal value.
|
||||
return new Expression('string', $val);
|
||||
}
|
||||
}
|
||||
|
|
@ -25,7 +25,6 @@ class DBQueryParser
|
|||
// Parse the query.
|
||||
$query_name = preg_replace('/\.xml$/', '', basename($filename));
|
||||
$query = self::_parseQuery($xml, $query_name);
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
|
|
@ -46,15 +45,20 @@ class DBQueryParser
|
|||
{
|
||||
$query->name = $query->alias;
|
||||
}
|
||||
$query->type = trim($xml['action']);
|
||||
$query->type = strtoupper($xml['action']) ?: null;
|
||||
|
||||
// Load attributes that only apply to subqueries in the <conditions> block.
|
||||
$query->operation = trim($xml['operation']) ?: null;
|
||||
$query->column = trim($xml['column']) ?: null;
|
||||
$query->pipe = strtoupper($xml['pipe']) ?: 'AND';
|
||||
|
||||
// Load tables.
|
||||
foreach ($xml->tables->table as $tag)
|
||||
{
|
||||
if (trim($tag['query']) === 'true')
|
||||
{
|
||||
$table = self::_parseQuery($tag);
|
||||
$query->tables[$table->alias] = $table;
|
||||
$subquery = self::_parseQuery($tag);
|
||||
$query->tables[$subquery->alias] = $subquery;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -77,18 +81,26 @@ class DBQueryParser
|
|||
// Load columns.
|
||||
foreach ($xml->columns->column as $tag)
|
||||
{
|
||||
$column = new DBQuery\Column;
|
||||
$column->name = trim($tag['name']);
|
||||
$column->alias = trim($tag['alias']) ?: null;
|
||||
if ($column->name === '*' || preg_match('/\.\*$/', $column->name))
|
||||
if ($tag->getName() === 'query')
|
||||
{
|
||||
$column->is_wildcard = true;
|
||||
$subquery = self::_parseQuery($tag, trim($tag['id']));
|
||||
$query->columns[] = $subquery;
|
||||
}
|
||||
if (!self::_isValidColumnName($column->name))
|
||||
else
|
||||
{
|
||||
$column->is_expression = true;
|
||||
$column = new DBQuery\Column;
|
||||
$column->name = trim($tag['name']);
|
||||
$column->alias = trim($tag['alias']) ?: null;
|
||||
if ($column->name === '*' || preg_match('/\.\*$/', $column->name))
|
||||
{
|
||||
$column->is_wildcard = true;
|
||||
}
|
||||
if (!self::isValidColumnName($column->name))
|
||||
{
|
||||
$column->is_expression = true;
|
||||
}
|
||||
$query->columns[] = $column;
|
||||
}
|
||||
$query->columns[] = $column;
|
||||
}
|
||||
|
||||
// Load conditions.
|
||||
|
|
@ -131,13 +143,23 @@ class DBQueryParser
|
|||
{
|
||||
if ($tag = $xml->navigation->{$key})
|
||||
{
|
||||
$query->navigation->{$key} = new DBQuery\GenericVar;
|
||||
$query->navigation->{$key} = new DBQuery\VariableBase;
|
||||
$query->navigation->{$key}->var = trim($tag['var']) ?: null;
|
||||
$query->navigation->{$key}->default = trim($tag['default']) ?: null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If a SELECT query has no columns, use * by default.
|
||||
if ($query->type === 'SELECT' && !count($query->columns))
|
||||
{
|
||||
$column = new DBQuery\Column;
|
||||
$column->name = '*';
|
||||
$column->is_wildcard = true;
|
||||
$column->is_expression = true;
|
||||
$query->columns[] = $column;
|
||||
}
|
||||
|
||||
// Return the complete query definition.
|
||||
return $query;
|
||||
}
|
||||
|
|
@ -159,19 +181,27 @@ class DBQueryParser
|
|||
$cond = new DBQuery\Condition;
|
||||
$cond->operation = trim($tag['operation']);
|
||||
$cond->column = trim($tag['column']);
|
||||
$cond->var = trim($tag['var']);
|
||||
$cond->default = trim($tag['default']);
|
||||
$cond->var = trim($tag['var']) ?: null;
|
||||
$cond->default = trim($tag['default']) ?: null;
|
||||
$cond->not_null = trim($tag['notnull'] ?: $tag['not-null']) !== '' ? true : false;
|
||||
$cond->operator = strtoupper($tag['pipe']) ?: 'AND';
|
||||
$cond->filter = trim($tag['filter']) ?: null;
|
||||
$cond->minlength = intval(trim($tag['minlength']), 10);
|
||||
$cond->maxlength = intval(trim($tag['maxlength']), 10);
|
||||
$cond->pipe = strtoupper($tag['pipe']) ?: 'AND';
|
||||
$result[] = $cond;
|
||||
}
|
||||
elseif ($name === 'group')
|
||||
{
|
||||
$group = new DBQuery\ConditionGroup;
|
||||
$group->conditions = self::_parseConditions($tag);
|
||||
$group->operator = strtoupper($tag['pipe']) ?: 'AND';
|
||||
$group->pipe = strtoupper($tag['pipe']) ?: 'AND';
|
||||
$result[] = $group;
|
||||
}
|
||||
elseif ($name === 'query')
|
||||
{
|
||||
$subquery = self::_parseQuery($tag);
|
||||
$result[] = $subquery;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
|
@ -183,7 +213,7 @@ class DBQueryParser
|
|||
* @param string $column_name
|
||||
* @return bool
|
||||
*/
|
||||
protected static function _isValidColumnName(string $column_name): bool
|
||||
public static function isValidColumnName(string $column_name): bool
|
||||
{
|
||||
if (preg_match('/^[a-z0-9_]+(?:\.[a-z0-9_]+)*$/', $column_name))
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue