diff --git a/classes/db/queryparts/Query.class.php b/classes/db/queryparts/Query.class.php index 7dad0735e..7e1d366a8 100644 --- a/classes/db/queryparts/Query.class.php +++ b/classes/db/queryparts/Query.class.php @@ -93,6 +93,10 @@ $this->tables = $tables; } + + function setSubquery($subquery){ + $this->subquery = $subquery; + } function setConditions($conditions){ $this->conditions = array(); @@ -186,6 +190,20 @@ function getInsertString($with_values = true){ $columnsList = ''; + if($this->subquery){ // means we have insert-select + + foreach($this->columns as $column){ + $columnsList .= $column->getColumnName() . ', '; + } + $columnsList = substr($columnsList, 0, -2); + + $selectStatement = $this->subquery->toString($with_values); + $selectStatement = substr($selectStatement, 1, -1); + + return "($columnsList) \n $selectStatement"; + } + + $valuesList = ''; foreach($this->columns as $column){ if($column->show()){ diff --git a/classes/xml/XmlQueryParser.150.class.php b/classes/xml/XmlQueryParser.150.class.php index ba4dd7d0a..63a861aec 100644 --- a/classes/xml/XmlQueryParser.150.class.php +++ b/classes/xml/XmlQueryParser.150.class.php @@ -21,6 +21,7 @@ require(_XE_PATH_.'classes/xml/xmlquery/tags/column/ColumnTag.class.php'); require(_XE_PATH_.'classes/xml/xmlquery/tags/column/SelectColumnTag.class.php'); require(_XE_PATH_.'classes/xml/xmlquery/tags/column/InsertColumnTag.class.php'); + require(_XE_PATH_.'classes/xml/xmlquery/tags/column/InsertColumnTagWithoutArgument.class.php'); require(_XE_PATH_.'classes/xml/xmlquery/tags/column/UpdateColumnTag.class.php'); require(_XE_PATH_.'classes/xml/xmlquery/tags/column/SelectColumnsTag.class.php'); require(_XE_PATH_.'classes/xml/xmlquery/tags/column/InsertColumnsTag.class.php'); diff --git a/classes/xml/xmlquery/tags/column/InsertColumnTagWithoutArgument.class.php b/classes/xml/xmlquery/tags/column/InsertColumnTagWithoutArgument.class.php new file mode 100644 index 000000000..39ee5ceb4 --- /dev/null +++ b/classes/xml/xmlquery/tags/column/InsertColumnTagWithoutArgument.class.php @@ -0,0 +1,27 @@ + tag inside an XML Query file whose action is 'insert-select' + * + **/ + + class InsertColumnTagWithoutArgument extends ColumnTag { + + function InsertColumnTagWithoutArgument($column) { + parent::ColumnTag($column->attrs->name); + $dbParser = DB::getParser(); + $this->name = $dbParser->parseColumnName($this->name); + } + + function getExpressionString(){ + var_dump($this->name); + return sprintf('new Expression(\'%s\')', $this->name); + } + + function getArgument(){ + return null; + } + + } +?> \ No newline at end of file diff --git a/classes/xml/xmlquery/tags/column/InsertColumnsTag.class.php b/classes/xml/xmlquery/tags/column/InsertColumnsTag.class.php index 88ed19ccb..d849952db 100644 --- a/classes/xml/xmlquery/tags/column/InsertColumnsTag.class.php +++ b/classes/xml/xmlquery/tags/column/InsertColumnsTag.class.php @@ -19,6 +19,7 @@ foreach($xml_columns as $column){ if($column->name === 'query') $this->columns[] = new QueryTag($column, true); + else if(!isset($column->attrs->var) && !isset($column->attrs->default)) $this->columns[] = new InsertColumnTagWithoutArgument($column); else $this->columns[] = new InsertColumnTag($column); } } diff --git a/classes/xml/xmlquery/tags/query/QueryTag.class.php b/classes/xml/xmlquery/tags/query/QueryTag.class.php index 20bf79f1a..f93c8059a 100644 --- a/classes/xml/xmlquery/tags/query/QueryTag.class.php +++ b/classes/xml/xmlquery/tags/query/QueryTag.class.php @@ -10,6 +10,7 @@ class QueryTag { //xml tags var $columns; var $tables; + var $subquery; var $conditions; var $groups; var $navigation; @@ -37,9 +38,12 @@ class QueryTag { $this->getColumns(); $tables = $this->getTables(); $this->setTableColumnTypes($tables); + $this->getSubquery(); // Used for insert-select $this->getConditions(); $this->getGroups(); $this->getNavigation(); + + $this->getPrebuff(); $this->getBuff(); } @@ -77,19 +81,20 @@ class QueryTag { } } - function getColumns() { - if ($this->action == 'select') { - return $this->columns = new SelectColumnsTag($this->query->columns); - } else if ($this->action == 'insert') { - return $this->columns = new InsertColumnsTag($this->query->columns->column); - } else if ($this->action == 'update') { - return $this->columns = new UpdateColumnsTag($this->query->columns->column); - } else if ($this->action == 'delete') { - return $this->columns = null; + function getColumns(){ + if($this->action == 'select'){ + return $this->columns = new SelectColumnsTag($this->query->columns); + }else if($this->action == 'insert' || $this->action == 'insert-select'){ + return $this->columns = new InsertColumnsTag($this->query->columns->column); + }else if($this->action == 'update') { + return $this->columns = new UpdateColumnsTag($this->query->columns->column); + }else if($this->action == 'delete') { + return $this->columns = null; } } function getPrebuff() { + if($this->isSubQuery) return; // TODO Check if this work with arguments in join clause $arguments = $this->getArguments(); @@ -159,11 +164,13 @@ class QueryTag { if ($this->columns) $buff .= '$query->setColumns(' . $this->columns->toString() . ');' . PHP_EOL; - $buff .= '$query->setTables(' . $this->tables->toString() . ');' . PHP_EOL; - $buff .= '$query->setConditions(' . $this->conditions->toString() . ');' . PHP_EOL; - $buff .= '$query->setGroups(' . $this->groups->toString() . ');' . PHP_EOL; - $buff .= '$query->setOrder(' . $this->navigation->getOrderByString() . ');' . PHP_EOL; - $buff .= '$query->setLimit(' . $this->navigation->getLimitString() . ');' . PHP_EOL; + $buff .= '$query->setTables(' . $this->tables->toString() .');'.PHP_EOL; + if($this->action == 'insert-select') + $buff .= '$query->setSubquery(' . $this->subquery->toString() .');'.PHP_EOL; + $buff .= '$query->setConditions('.$this->conditions->toString() .');'.PHP_EOL; + $buff .= '$query->setGroups(' . $this->groups->toString() . ');'.PHP_EOL; + $buff .= '$query->setOrder(' . $this->navigation->getOrderByString() .');'.PHP_EOL; + $buff .= '$query->setLimit(' . $this->navigation->getLimitString() .');'.PHP_EOL; $this->buff = $buff; return $this->buff; @@ -176,7 +183,13 @@ class QueryTag { return $this->tables = new TablesTag($this->query->tables); } - function getConditions() { + function getSubquery(){ + if($this->query->query){ + $this->subquery = new QueryTag($this->query->query, true); + } + } + + function getConditions(){ return $this->conditions = new ConditionsTag($this->query->conditions); } @@ -207,11 +220,13 @@ class QueryTag { return $this->buff; } - function getArguments() { + function getArguments(){ $arguments = array(); if ($this->columns) $arguments = array_merge($arguments, $this->columns->getArguments()); - $arguments = array_merge($arguments, $this->tables->getArguments()); + if($this->action =='insert-select') + $arguments = array_merge($arguments, $this->subquery->getArguments()); + $arguments = array_merge($arguments, $this->tables->getArguments()); $arguments = array_merge($arguments, $this->conditions->getArguments()); $arguments = array_merge($arguments, $this->navigation->getArguments()); return $arguments; diff --git a/tests/classes/db/db/xml_query/mysql/MysqlInsertTest.php b/tests/classes/db/db/xml_query/mysql/MysqlInsertTest.php index 99dfd7950..6640531df 100644 --- a/tests/classes/db/db/xml_query/mysql/MysqlInsertTest.php +++ b/tests/classes/db/db/xml_query/mysql/MysqlInsertTest.php @@ -21,18 +21,23 @@ class MysqlInsertTest extends MysqlTest { $this->_testQuery($xml_file, $argsString, $expected, 'getInsertSql', $columnList); } - - function testInsertIntoNumericColumnConvertsValue() + + /** + * @brief testInsertSelectStatement - checks that when query action is 'insert-selct' an 'INSERT INTO .. SELECT ...' statement is properly generated + * @developer Corina Udrescu (xe_dev@arnia.ro) + * @access public + * @return void + */ + function testInsertSelectStatement() { - $xml_file = _TEST_PATH_ . "db/xml_query/mysql/data/member_insert_injection.xml"; - $argsString = '$args->member_srl = 7; - $args->find_account_question = "1\'"; - '; - $expected = 'insert into `xe_member` (`member_srl`, `find_account_question`) values (7, 1)'; + $xml_file = _TEST_PATH_ . "db/xml_query/mysql/data/insert_select.xml"; + $argsString = '$args->condition_value = 7;'; + $expected = 'insert into `xe_table1` (`column1`, `column2`, `column3`) + select `column4`, `column5`, `column6` + from `xe_table2` as `table2` + where `column4` >= 7'; $this->_test($xml_file, $argsString, $expected); } - - } /* End of file MysqlInsertTest.php */ diff --git a/tests/classes/db/db/xml_query/mysql/data/insert_select.xml b/tests/classes/db/db/xml_query/mysql/data/insert_select.xml new file mode 100644 index 000000000..4abfd3754 --- /dev/null +++ b/tests/classes/db/db/xml_query/mysql/data/insert_select.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + +
+ + + + + + + + + + + \ No newline at end of file