From 7f6e020d97ff84bc07899424ea4c3e1c770f89f8 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Tue, 25 Jan 2022 14:54:17 +0900 Subject: [PATCH] PROPERLY fix null value handling in both read and write queries --- .../parsers/dbquery/variablebase.php | 11 ++ tests/_data/dbquery/emptyStringTest1.xml | 11 ++ tests/_data/dbquery/emptyStringTest2.xml | 12 +++ tests/_data/dbquery/nullValueTest1.xml | 12 +++ tests/_data/dbquery/nullValueTest2.xml | 12 +++ .../framework/parsers/DBQueryParserTest.php | 100 ++++++++++++++++++ 6 files changed, 158 insertions(+) create mode 100644 tests/_data/dbquery/emptyStringTest1.xml create mode 100644 tests/_data/dbquery/emptyStringTest2.xml create mode 100644 tests/_data/dbquery/nullValueTest1.xml create mode 100644 tests/_data/dbquery/nullValueTest2.xml diff --git a/common/framework/parsers/dbquery/variablebase.php b/common/framework/parsers/dbquery/variablebase.php index 3ae58f96a..e183d8cd0 100644 --- a/common/framework/parsers/dbquery/variablebase.php +++ b/common/framework/parsers/dbquery/variablebase.php @@ -51,6 +51,17 @@ class VariableBase $this->filterValue(''); $value = strval($args[$this->var]); $is_expression = true; + if ($args[$this->var] instanceof NullValue) + { + if ($this->not_null) + { + throw new \Rhymix\Framework\Exceptions\QueryError('Variable ' . $this->var . ' for column ' . $this->column . ' must not be null'); + } + if ($this instanceof Condition && in_array($this->operation, ['equal', 'notequal', 'not_equal'])) + { + $this->operation = ($this->operation === 'equal') ? 'null' : 'notnull'; + } + } } elseif ($args[$this->var] === '') { diff --git a/tests/_data/dbquery/emptyStringTest1.xml b/tests/_data/dbquery/emptyStringTest1.xml new file mode 100644 index 000000000..4c14ba12f --- /dev/null +++ b/tests/_data/dbquery/emptyStringTest1.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/tests/_data/dbquery/emptyStringTest2.xml b/tests/_data/dbquery/emptyStringTest2.xml new file mode 100644 index 000000000..8b1637ecb --- /dev/null +++ b/tests/_data/dbquery/emptyStringTest2.xml @@ -0,0 +1,12 @@ + + +
+ + + + + + + + + diff --git a/tests/_data/dbquery/nullValueTest1.xml b/tests/_data/dbquery/nullValueTest1.xml new file mode 100644 index 000000000..c3141e963 --- /dev/null +++ b/tests/_data/dbquery/nullValueTest1.xml @@ -0,0 +1,12 @@ + + +
+ + + + + + + + + diff --git a/tests/_data/dbquery/nullValueTest2.xml b/tests/_data/dbquery/nullValueTest2.xml new file mode 100644 index 000000000..9c5ac6edc --- /dev/null +++ b/tests/_data/dbquery/nullValueTest2.xml @@ -0,0 +1,12 @@ + + +
+ + + + + + + + + diff --git a/tests/unit/framework/parsers/DBQueryParserTest.php b/tests/unit/framework/parsers/DBQueryParserTest.php index 85278c078..47170e5f6 100644 --- a/tests/unit/framework/parsers/DBQueryParserTest.php +++ b/tests/unit/framework/parsers/DBQueryParserTest.php @@ -446,4 +446,104 @@ class DBQueryParserTest extends \Codeception\TestCase\Test $this->assertEquals('DELETE FROM `rx_documents` WHERE `document_srl` IN (?, ?, ?)', $sql); $this->assertEquals(['12', '34', '56'], $params); } + + public function testEmptyString() + { + $query = Rhymix\Framework\Parsers\DBQueryParser::loadXML(\RX_BASEDIR . 'tests/_data/dbquery/emptyStringTest1.xml'); + + $sql = $query->getQueryString('rx_', array( + 'nick_name' => '', + 'document_srl' => 1234, + )); + $this->assertEquals('UPDATE `rx_documents` SET `nick_name` = ? WHERE `document_srl` = ?', $sql); + $this->assertEquals(['', 1234], $query->getQueryParams()); + + $sql = $query->getQueryString('rx_', array( + 'nick_name' => new \Rhymix\Framework\Parsers\DBQuery\EmptyString, + 'document_srl' => 1234, + )); + $this->assertEquals('UPDATE `rx_documents` SET `nick_name` = \'\' WHERE `document_srl` = ?', $sql); + $this->assertEquals([1234], $query->getQueryParams()); + + $sql = $query->getQueryString('rx_', array( + 'nick_name' => new \Rhymix\Framework\Parsers\DBQuery\EmptyString, + 'document_srl' => '', + )); + $this->assertEquals('UPDATE `rx_documents` SET `nick_name` = \'\'', $sql); + $this->assertEquals([], $query->getQueryParams()); + + $sql = $query->getQueryString('rx_', array( + 'nick_name' => new \Rhymix\Framework\Parsers\DBQuery\EmptyString, + 'document_srl' => new \Rhymix\Framework\Parsers\DBQuery\EmptyString, + )); + $this->assertEquals('UPDATE `rx_documents` SET `nick_name` = \'\' WHERE `document_srl` = \'\'', $sql); + $this->assertEquals([], $query->getQueryParams()); + + $query = Rhymix\Framework\Parsers\DBQueryParser::loadXML(\RX_BASEDIR . 'tests/_data/dbquery/emptyStringTest2.xml'); + + $sql = $query->getQueryString('rx_', array( + 'category_srl' => 77, + 'nick_name' => '', + )); + $this->assertEquals('SELECT * FROM `rx_documents` AS `documents` WHERE `category_srl` = ?', $sql); + $this->assertEquals([77], $query->getQueryParams()); + + $sql = $query->getQueryString('rx_', array( + 'category_srl' => 88, + 'nick_name' => new \Rhymix\Framework\Parsers\DBQuery\EmptyString, + )); + $this->assertEquals('SELECT * FROM `rx_documents` AS `documents` WHERE `category_srl` = ? AND `nick_name` = \'\'', $sql); + $this->assertEquals([88], $query->getQueryParams()); + } + + public function testNullValue() + { + $query = Rhymix\Framework\Parsers\DBQueryParser::loadXML(\RX_BASEDIR . 'tests/_data/dbquery/nullValueTest1.xml'); + + $sql = $query->getQueryString('rx_', array( + 'user_name' => null, + 'nick_name' => 'TEST', + 'document_srl' => 1234, + )); + $this->assertEquals('UPDATE `rx_documents` SET `nick_name` = ? WHERE `document_srl` = ?', $sql); + $this->assertEquals(['TEST', 1234], $query->getQueryParams()); + + $sql = $query->getQueryString('rx_', array( + 'user_name' => new \Rhymix\Framework\Parsers\DBQuery\NullValue, + 'nick_name' => 'TEST', + 'document_srl' => 1234, + )); + $this->assertEquals('UPDATE `rx_documents` SET `user_name` = NULL, `nick_name` = ? WHERE `document_srl` = ?', $sql); + $this->assertEquals(['TEST', 1234], $query->getQueryParams()); + + $this->tester->expectThrowable(\Rhymix\Framework\Exceptions\QueryError::class, function() use($query) { + $query->getQueryString('rx_', array( + 'nick_name' => new \Rhymix\Framework\Parsers\DBQuery\NullValue, + 'document_srl' => 1234, + )); + }); + + $this->tester->expectThrowable(\Rhymix\Framework\Exceptions\QueryError::class, function() use($query) { + $query->getQueryString('rx_', array( + 'nick_name' => null, + 'document_srl' => 1234, + )); + }); + + $query = Rhymix\Framework\Parsers\DBQueryParser::loadXML(\RX_BASEDIR . 'tests/_data/dbquery/nullValueTest2.xml'); + + $sql = $query->getQueryString('rx_', array( + 'member_srl' => null, + 'module_srl' => 456, + )); + $this->assertEquals('SELECT * FROM `rx_documents` AS `documents` WHERE `module_srl` = ?', $sql); + $this->assertEquals([456], $query->getQueryParams()); + + $sql = $query->getQueryString('rx_', array( + 'member_srl' => new \Rhymix\Framework\Parsers\DBQuery\NullValue, + 'module_srl' => new \Rhymix\Framework\Parsers\DBQuery\NullValue, + )); + $this->assertEquals('SELECT * FROM `rx_documents` AS `documents` WHERE `module_srl` IS NULL AND `member_srl` IS NOT NULL', $sql); + $this->assertEquals([], $query->getQueryParams()); + } }