diff --git a/common/framework/parsers/dbquery/condition.php b/common/framework/parsers/dbquery/condition.php index b386fb894..cb5ecf690 100644 --- a/common/framework/parsers/dbquery/condition.php +++ b/common/framework/parsers/dbquery/condition.php @@ -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'; } diff --git a/common/framework/parsers/dbquery/conditiongroup.php b/common/framework/parsers/dbquery/conditiongroup.php index caee07f1d..a5e67ce4d 100644 --- a/common/framework/parsers/dbquery/conditiongroup.php +++ b/common/framework/parsers/dbquery/conditiongroup.php @@ -8,5 +8,5 @@ namespace Rhymix\Framework\Parsers\DBQuery; class ConditionGroup { public $conditions = array(); - public $operator = 'AND'; + public $pipe = 'AND'; } diff --git a/common/framework/parsers/dbquery/expression.php b/common/framework/parsers/dbquery/expression.php new file mode 100644 index 000000000..5ad98717c --- /dev/null +++ b/common/framework/parsers/dbquery/expression.php @@ -0,0 +1,49 @@ +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; + + + } + } +} diff --git a/common/framework/parsers/dbquery/genericvar.php b/common/framework/parsers/dbquery/genericvar.php deleted file mode 100644 index ca6064a13..000000000 --- a/common/framework/parsers/dbquery/genericvar.php +++ /dev/null @@ -1,12 +0,0 @@ -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); + } +} diff --git a/common/framework/parsers/dbqueryparser.php b/common/framework/parsers/dbqueryparser.php index a0fa28e08..d4cd3a28f 100644 --- a/common/framework/parsers/dbqueryparser.php +++ b/common/framework/parsers/dbqueryparser.php @@ -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 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)) {