From 6b7486e74f63e1470faac636d896ad6dd318f06f Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Tue, 9 Feb 2021 21:58:07 +0900 Subject: [PATCH] Add 'ifvar' attribute to most query elements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit XML 쿼리에서 'ifvar' 속성을 사용하여, 특정 변수가 있을 때만 유효한 테이블이나 컬럼, 인덱스 힌트 등을 지정할 수 있도록 합니다. 어떤 변수를 넣는지에 따라 뿐 아니라 , , 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) { diff --git a/common/framework/parsers/dbquery/table.php b/common/framework/parsers/dbquery/table.php index 9e5544219..a5984afaf 100644 --- a/common/framework/parsers/dbquery/table.php +++ b/common/framework/parsers/dbquery/table.php @@ -9,6 +9,7 @@ class Table { public $name; public $alias; + public $ifvar; public $join_type; public $join_conditions = array(); } diff --git a/common/framework/parsers/dbquery/variablebase.php b/common/framework/parsers/dbquery/variablebase.php index 897c9fbe6..e62e006b3 100644 --- a/common/framework/parsers/dbquery/variablebase.php +++ b/common/framework/parsers/dbquery/variablebase.php @@ -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) . ')'; diff --git a/common/framework/parsers/dbqueryparser.php b/common/framework/parsers/dbqueryparser.php index 47837275f..f7da28608 100644 --- a/common/framework/parsers/dbqueryparser.php +++ b/common/framework/parsers/dbqueryparser.php @@ -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') diff --git a/tests/_data/dbquery/selectJoinTest1.xml b/tests/_data/dbquery/selectJoinTest1.xml index a62262c65..29296c688 100644 --- a/tests/_data/dbquery/selectJoinTest1.xml +++ b/tests/_data/dbquery/selectJoinTest1.xml @@ -1,18 +1,19 @@
-
+
- + - - + + + - + diff --git a/tests/unit/framework/parsers/DBQueryParserTest.php b/tests/unit/framework/parsers/DBQueryParserTest.php index dd65173f4..bf9d4b388 100644 --- a/tests/unit/framework/parsers/DBQueryParserTest.php +++ b/tests/unit/framework/parsers/DBQueryParserTest.php @@ -137,7 +137,7 @@ class DBQueryParserTest extends \Codeception\TestCase\Test $this->assertTrue($query->columns[1]->is_expression); $this->assertFalse($query->columns[1]->is_wildcard); - $this->assertEquals(3, count($query->conditions)); + $this->assertEquals(4, count($query->conditions)); $this->assertEquals('documents.member_srl', $query->conditions[0]->column); $this->assertEquals('member.member_srl', $query->conditions[0]->default); $this->assertNull($query->conditions[0]->var); @@ -153,7 +153,10 @@ class DBQueryParserTest extends \Codeception\TestCase\Test $this->assertEquals('member.member_srl', $query->groupby->having[0]->column); $this->assertEquals('notequal', $query->groupby->having[0]->operation); - $args = array('document_srl_list' => [12, 34, 56], 'exclude_member_srl' => 4); + $args = array( + 'document_srl_list' => [12, 34, 56], 'exclude_member_srl' => 4, + 'if_table' => true, 'if_column' => true, 'if_condition1' => true, 'if_groupby' => true, + ); $sql = $query->getQueryString('rx_', $args); $params = $query->getQueryParams(); @@ -161,6 +164,28 @@ class DBQueryParserTest extends \Codeception\TestCase\Test 'WHERE `documents`.`member_srl` = `member`.`member_srl` AND `documents`.`member_srl` = `member`.`member_srl` ' . 'AND `documents`.`document_srl` IN (?, ?, ?) GROUP BY `member`.`member_srl` HAVING `member`.`member_srl` != ?', $sql); $this->assertEquals(['12', '34', '56', '4'], $params); + + $args = array( + 'document_srl_list' => [12, 34, 56], 'exclude_member_srl' => 4, 'exclude_document_srl_list' => '78,90', + 'if_table' => true, 'if_column' => true, 'if_condition2' => true, + ); + $sql = $query->getQueryString('rx_', $args); + $params = $query->getQueryParams(); + + $this->assertEquals('SELECT `member`.`member_srl`, COUNT(*) AS `count` FROM `rx_documents` AS `documents`, `rx_member` AS `member` ' . + 'WHERE `documents`.`member_srl` = `member`.`member_srl` AND `documents`.`document_srl` IN (?, ?, ?) ' . + 'AND `documents`.`document_srl` NOT IN (?, ?)', $sql); + $this->assertEquals(['12', '34', '56', '78', '90'], $params); + + $args = array( + 'document_srl_list' => [12, 34, 56], 'exclude_member_srl' => 4, + ); + $sql = $query->getQueryString('rx_', $args); + $params = $query->getQueryParams(); + + $this->assertEquals('SELECT `member`.`member_srl` FROM `rx_documents` AS `documents` ' . + 'WHERE `documents`.`member_srl` = `member`.`member_srl` AND `documents`.`document_srl` IN (?, ?, ?)', $sql); + $this->assertEquals(['12', '34', '56'], $params); } public function testJoin2()