Add 'ifvar' attribute to most query elements

XML 쿼리에서 'ifvar' 속성을 사용하여, 특정 변수가 있을 때만 유효한 테이블이나
컬럼, 인덱스 힌트 등을 지정할 수 있도록 합니다. 어떤 변수를 넣는지에 따라
<condition> 뿐 아니라 <table>, <column>, <index_hint? 등의 적용 여부도
XML 쿼리 수정 없이 자유롭게 컨트롤할 수 있게 됩니다.
This commit is contained in:
Kijin Sung 2021-02-09 21:58:07 +09:00
parent 1289776c97
commit 6b7486e74f
12 changed files with 88 additions and 11 deletions

View file

@ -9,6 +9,7 @@ class ColumnRead
{
public $name;
public $alias;
public $ifvar;
public $is_expression = false;
public $is_wildcard = false;
}

View file

@ -10,6 +10,7 @@ class ColumnWrite extends VariableBase
public $name;
public $operation = 'equal';
public $var;
public $ifvar;
public $default;
public $not_null;
public $filter;

View file

@ -10,6 +10,7 @@ class Condition extends VariableBase
public $operation;
public $column;
public $var;
public $ifvar;
public $default;
public $not_null;
public $filter;

View file

@ -9,4 +9,5 @@ class ConditionGroup
{
public $conditions = array();
public $pipe = 'AND';
public $ifvar;
}

View file

@ -9,4 +9,5 @@ class GroupBy
{
public $columns = array();
public $having = array();
public $ifvar;
}

View file

@ -12,4 +12,5 @@ class IndexHint
public $index_name = '';
public $table_name = '';
public $var;
public $ifvar;
}

View file

@ -131,7 +131,11 @@ class Query extends VariableBase
$columns = array();
foreach ($this->columns as $column)
{
if ($column instanceof self)
if ($column->ifvar && !isset($this->_args[$column->ifvar]))
{
continue;
}
elseif ($column instanceof self)
{
$has_subquery_columns = true;
$subquery_count_only = $count_only ? $count_only + 1 : 0;
@ -206,7 +210,7 @@ class Query extends VariableBase
}
// Compose the GROUP BY clause.
if ($this->groupby && count($this->groupby->columns))
if ($this->groupby && count($this->groupby->columns) && (!$this->groupby->ifvar || isset($this->_args[$this->groupby->ifvar])))
{
$columns = array();
foreach ($this->groupby->columns as $column_name)
@ -222,7 +226,7 @@ class Query extends VariableBase
}
$result .= ' GROUP BY ' . implode(', ', $columns);
}
if ($this->groupby && count($this->groupby->having))
if ($this->groupby && count($this->groupby->having) && (!$this->groupby->ifvar || isset($this->_args[$this->groupby->ifvar])))
{
$having = $this->_arrangeConditions($this->groupby->having);
if ($having !== '')
@ -277,6 +281,11 @@ class Query extends VariableBase
$columns = array();
foreach ($this->columns as $column)
{
if ($column->ifvar && !isset($this->_args[$column->ifvar]))
{
continue;
}
$setval_string = $this->_parseCondition($column);
if ($setval_string !== '')
{
@ -324,6 +333,11 @@ class Query extends VariableBase
$columns = array();
foreach ($this->columns as $column)
{
if ($column->ifvar && !isset($this->_args[$column->ifvar]))
{
continue;
}
$setval_string = $this->_parseCondition($column);
if ($setval_string !== '')
{
@ -407,6 +421,12 @@ class Query extends VariableBase
// Process each table definition.
foreach ($tables as $table)
{
// Skip
if ($table->ifvar && !isset($this->_args[$table->ifvar]))
{
continue;
}
// Subquery
if ($table instanceof self)
{
@ -465,6 +485,12 @@ class Query extends VariableBase
// Group each index hint by type.
foreach ($index_hints as $index_hint)
{
// Skip
if ($index_hint->ifvar && !isset($this->_args[$index_hint->ifvar]))
{
continue;
}
if (!count($index_hint->target_db) || isset($index_hint->target_db['mysql']))
{
$key = $index_hint->hint_type ?: 'USE';
@ -506,6 +532,12 @@ class Query extends VariableBase
// Process each condition.
foreach ($conditions as $condition)
{
// Skip
if ($condition->ifvar && !isset($this->_args[$condition->ifvar]))
{
continue;
}
// Subquery
if ($condition instanceof self)
{

View file

@ -9,6 +9,7 @@ class Table
{
public $name;
public $alias;
public $ifvar;
public $join_type;
public $join_conditions = array();
}

View file

@ -11,6 +11,7 @@ class VariableBase
* Instance properties.
*/
public $var;
public $ifvar;
public $default;
/**
@ -33,7 +34,11 @@ class VariableBase
$params = array();
// Process the variable or default value.
if ($this instanceof Query)
if ($this->ifvar && !isset($args[$this->ifvar]))
{
return [$where, $params];
}
elseif ($this instanceof Query)
{
$is_expression = true;
$value = '(' . $this->getQueryString($prefix, $args) . ')';

View file

@ -66,6 +66,7 @@ class DBQueryParser extends BaseParser
$table = new DBQuery\Table;
$table->name = trim($tag['name']);
$table->alias = trim($tag['alias']) ?: $table->name;
$table->ifvar = trim($tag['if']) ?: null;
}
$table_type = trim($tag['type']);
@ -101,6 +102,7 @@ class DBQueryParser extends BaseParser
$index_hint->hint_type = strtoupper(trim($tag['type'])) ?: 'USE';
$index_hint->index_name = trim($tag['name']) ?: '';
$index_hint->table_name = trim($tag['table']) ?: '';
$index_hint->ifvar = trim($tag['if']) ?: null;
if (isset($tag['var']) && trim($tag['var']))
{
$index_hint->var = trim($tag['var']);
@ -129,6 +131,7 @@ class DBQueryParser extends BaseParser
$column = new DBQuery\ColumnRead;
$column->name = trim($tag['name']);
$column->alias = trim($tag['alias']) ?: null;
$column->ifvar = trim($tag['if']) ?: null;
if ($column->name === '*' || preg_match('/\.\*$/', $column->name))
{
$column->is_wildcard = true;
@ -146,6 +149,7 @@ class DBQueryParser extends BaseParser
$column->name = $attribs['name'];
$column->operation = ($attribs['operation'] ?? null) ?: 'equal';
$column->var = $attribs['var'] ?? null;
$column->ifvar = $attribs['if'] ?? null;
$column->default = $attribs['default'] ?? null;
$column->not_null = ($attribs['notnull'] ?? false) ? true : false;
$column->filter = $attribs['filter'] ?? null;
@ -165,6 +169,7 @@ class DBQueryParser extends BaseParser
if ($xml->groups)
{
$query->groupby = new DBQuery\GroupBy;
$query->groupby->ifvar = trim($xml->groups['if']) ?: null;
foreach ($xml->groups->children() as $tag)
{
$name = $tag->getName();
@ -261,6 +266,7 @@ class DBQueryParser extends BaseParser
$cond->var = $attribs['var'] ?? null;
$cond->default = $attribs['default'] ?? null;
}
$cond->ifvar = $attribs['if'] ?? null;
$cond->not_null = ($attribs['notnull'] ?? false) ? true : false;
$cond->filter = $attribs['filter'] ?? null;
$cond->minlength = intval($attribs['minlength'] ?? 0, 10);
@ -273,6 +279,7 @@ class DBQueryParser extends BaseParser
$group = new DBQuery\ConditionGroup;
$group->conditions = self::_parseConditions($tag);
$group->pipe = strtoupper($attribs['pipe'] ?? null) ?: 'AND';
$group->ifvar = $attribs['if'] ?? null;
$result[] = $group;
}
elseif ($name === 'query')