diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..82082eb
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,14 @@
+language: php
+php:
+ - '7.1'
+ - '7.2'
+before_script:
+ - travis_retry composer self-update
+ - travis_retry composer install --no-interaction --prefer-source --dev
+
+script:
+ - vendor/bin/phpunit --coverage-clover=coverage.xml
+ - vendor/bin/phpcs -p --standard=PSR2 src/
+
+after_success:
+ - travis_retry bash <(curl -s https://codecov.io/bash)
diff --git a/README.md b/README.md
index 900722b..4a4b36e 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,15 @@
Presto Query Builder
===================
+This package provides a set of classes and methods that is able to programmatically build presto queries.
+
+[![Latest Stable Version](https://poser.pugx.org/moitran/package-presto-query-builder-php/v/stable)](https://packagist.org/packages/moitran/package-presto-query-builder-php)
+[![Latest Unstable Version](https://poser.pugx.org/moitran/package-presto-query-builder-php/v/unstable)](https://packagist.org/packages/moitran/package-presto-query-builder-php)
+[![Build Status](https://travis-ci.org/moitran/package-presto-query-builder-php.svg?branch=master)](https://travis-ci.org/moitran/package-presto-query-builder-php)
+[![codecov](https://codecov.io/gh/moitran/package-presto-query-builder-php/branch/master/graphs/badge.svg)](https://codecov.io/gh/moitran/package-presto-query-builder-php)
+[![License](https://poser.pugx.org/moitran/package-presto-query-builder-php/license)](https://packagist.org/packages/moitran/package-presto-query-builder-php)
+[![composer.lock](https://poser.pugx.org/moitran/package-presto-query-builder-php/composerlock)](https://packagist.org/packages/moitran/package-presto-query-builder-php)
+
- [Installation](#installation)
- [Usage](#usage)
- [Testing](#testing)
@@ -137,4 +146,4 @@ Contributing
License
-------
-[MIT](https://github.com/moitran/package-presto-query-builder-php/blob/master/LICENSE)
\ No newline at end of file
+This package is under [MIT License](https://github.com/moitran/package-presto-query-builder-php/blob/master/LICENSE)
\ No newline at end of file
diff --git a/composer.json b/composer.json
index 638c3c2..0124cee 100644
--- a/composer.json
+++ b/composer.json
@@ -1,6 +1,7 @@
{
"name": "moitran/package-presto-query-builder-php",
"description": "Build presto query string",
+ "type": "package",
"license": "MIT",
"authors": [
{
@@ -12,7 +13,10 @@
"php": "^7.1"
},
"require-dev": {
- "phpunit/phpunit": "^7.3"
+ "phpunit/phpunit": "^7.3",
+ "symfony/var-dumper": "^4.2",
+ "phpmd/phpmd": "^2.6",
+ "squizlabs/php_codesniffer": "^3.3"
},
"autoload": {
"psr-4": {
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 1414e67..1de3be7 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -5,12 +5,12 @@
verbose="true">
- tests
+ ./tests
- src
+ ./src/
-
\ No newline at end of file
+
diff --git a/src/Base.php b/src/Base.php
index 82ca915..f1bc37f 100644
--- a/src/Base.php
+++ b/src/Base.php
@@ -59,7 +59,7 @@ private function removeSpecialCharsFromStr($str)
$str = str_replace(
['\\', "\0", "\n", "\r", "'", '"', "\x1a"],
- ['\\\\', '\\0', '\\n', '\\r', "\\'", '\\"', '\\Z'],
+ ['\\\\', '\\0', '\\n', '\\r', "''", '\\"', '\\Z'],
$str
);
diff --git a/src/Query.php b/src/Query.php
index fdd03ee..15e42ca 100644
--- a/src/Query.php
+++ b/src/Query.php
@@ -22,6 +22,10 @@ class Query extends Base
* @var bool
*/
private $isFirstUnionAll = true;
+ /**
+ * @var bool
+ */
+ private $isFirstHaving = true;
const SORT_DESC = 'DESC';
const SORT_ASC = 'ASC';
@@ -195,8 +199,12 @@ public function whereAndGroup(WhereGroup $whereGroup)
{
$whereStr = $whereGroup->getWhereConditions();
+ if ($whereStr == '') {
+ return $this;
+ }
+
if ($this->isFirstWhere) {
- $whereStr = sprintf(' WHERE AND (%s)', $whereStr);
+ $whereStr = sprintf(' WHERE (%s)', $whereStr);
$this->isFirstWhere = false;
} else {
$whereStr = sprintf(' AND (%s)', $whereStr);
@@ -216,8 +224,12 @@ public function whereOrGroup(WhereGroup $whereGroup)
{
$whereStr = $whereGroup->getWhereConditions();
+ if ($whereStr == '') {
+ return $this;
+ }
+
if ($this->isFirstWhere) {
- $whereStr = sprintf(' WHERE OR (%s)', $whereStr);
+ $whereStr = sprintf(' WHERE (%s)', $whereStr);
$this->isFirstWhere = false;
} else {
$whereStr = sprintf(' OR (%s)', $whereStr);
@@ -228,6 +240,32 @@ public function whereOrGroup(WhereGroup $whereGroup)
return $this;
}
+ /**
+ * @param $column
+ * @param $condition
+ * @param $value
+ *
+ * @return $this
+ * @throws InvalidArgumentException
+ */
+ public function andHaving($column, $condition, $value)
+ {
+ return $this->having($column, $condition, $this->removeSpecialChars($value), 'AND');
+ }
+
+ /**
+ * @param $column
+ * @param $condition
+ * @param $value
+ *
+ * @return $this
+ * @throws InvalidArgumentException
+ */
+ public function orHaving($column, $condition, $value)
+ {
+ return $this->having($column, $condition, $this->removeSpecialChars($value), 'OR');
+ }
+
/**
* @param Query $query
*
@@ -349,6 +387,44 @@ private function where($column, $condition, $value, $whereType)
return $this;
}
+ /**
+ * @param $column
+ * @param $condition
+ * @param $value
+ * @param $havingType
+ *
+ * @return $this
+ * @throws InvalidArgumentException
+ */
+ private function having($column, $condition, $value, $havingType)
+ {
+ if (!is_string($column) || !is_string($condition)) {
+ throw new InvalidArgumentException('$column and $condition argument must be a string');
+ }
+
+ if (!(is_string($value) || is_array($value) || is_null($value) || is_numeric($value))) {
+ throw new InvalidArgumentException('$value argument must be a string, a numeric or an array');
+ }
+
+ if (is_null($value)) {
+ $valueStr = 'NULL';
+ } elseif (is_numeric($value)) {
+ $valueStr = $value;
+ } else {
+ $valueStr = is_string($value) ? sprintf("'%s'", $value) : sprintf("('%s')", implode("', '", $value));
+ }
+
+ if ($this->isFirstHaving) {
+ $havingType = 'HAVING';
+ $this->isFirstHaving = false;
+ }
+
+ $havingStr = sprintf(" %s %s %s %s", $havingType, $column, $condition, $valueStr);
+ $this->combineQueryStr($havingStr);
+
+ return $this;
+ }
+
/**
* @param $table
* @param $alias
diff --git a/src/Where.php b/src/Where.php
index 9917e65..30d77ab 100644
--- a/src/Where.php
+++ b/src/Where.php
@@ -66,7 +66,7 @@ private function where($column, $condition, $value, $whereType)
} elseif (is_numeric($value)) {
$valueStr = $value;
} else {
- $valueStr = is_string($value) ? sprintf("'%s'", $value) : sprintf("('%s')", implode("','", $value));
+ $valueStr = is_string($value) ? sprintf("'%s'", $value) : sprintf("('%s')", implode("', '", $value));
}
$whereStr = sprintf(" %s %s %s %s", $whereType, $column, $condition, $valueStr);
diff --git a/src/WhereGroup.php b/src/WhereGroup.php
index 2513633..7524270 100644
--- a/src/WhereGroup.php
+++ b/src/WhereGroup.php
@@ -75,6 +75,10 @@ public function whereAndGroup(WhereGroup $whereGroup)
{
$whereStr = $whereGroup->getWhereConditions();
+ if ($whereStr == '') {
+ return $this;
+ }
+
$whereStr = sprintf(' AND (%s)', $whereStr);
if ($this->isFirstCondition) {
@@ -96,6 +100,10 @@ public function whereOrGroup(WhereGroup $whereGroup)
{
$whereStr = $whereGroup->getWhereConditions();
+ if ($whereStr == '') {
+ return $this;
+ }
+
$whereStr = sprintf(' OR (%s)', $whereStr);
if ($this->isFirstCondition) {
diff --git a/tests/BaseTest.php b/tests/BaseTest.php
index 1dc4c94..f4c61a3 100644
--- a/tests/BaseTest.php
+++ b/tests/BaseTest.php
@@ -3,6 +3,7 @@
namespace MoiTran\PrestoQueryBuilder\Tests;
use MoiTran\PrestoQueryBuilder\Base;
+use MoiTran\PrestoQueryBuilder\Tests\Provider\BaseTestProvider;
/**
* Class BaseTest
@@ -10,34 +11,7 @@
*/
class BaseTest extends TestCases
{
- /**
- * @return array
- */
- public function providerRemoveSpecialChars()
- {
- return [
- 'numeric' => [
- 'input' => 111,
- 'expected' => 111,
- ],
- 'special-char' => [
- 'input' => '"test"',
- 'expected' => '\"test\"',
- ],
- 'percent-char' => [
- 'input' => '%test%',
- 'expected' => '%test%',
- ],
- 'array-value' => [
- 'input' => [1, '"test"', "\n", "\r", "%test"],
- 'expected' => ['1', '\"test\"', '\\n', '\\r', '%test'],
- ],
- 'not-accept-value-type' => [
- 'input' => new \stdClass(),
- 'expected' => new \stdClass(),
- ],
- ];
- }
+ use BaseTestProvider;
/**
* @param $input
diff --git a/tests/Provider/BaseTestProvider.php b/tests/Provider/BaseTestProvider.php
new file mode 100644
index 0000000..0826225
--- /dev/null
+++ b/tests/Provider/BaseTestProvider.php
@@ -0,0 +1,39 @@
+ [
+ 'input' => 111,
+ 'expected' => 111,
+ ],
+ 'special-char' => [
+ 'input' => '"test"',
+ 'expected' => '\"test\"',
+ ],
+ 'percent-char' => [
+ 'input' => '%test%',
+ 'expected' => '%test%',
+ ],
+ 'array-value' => [
+ 'input' => [1, '"test"', "\n", "\r", "%test"],
+ 'expected' => ['1', '\"test\"', '\\n', '\\r', '%test'],
+ ],
+ 'not-accept-value-type' => [
+ 'input' => new \stdClass(),
+ 'expected' => new \stdClass(),
+ ],
+ ];
+ }
+}
diff --git a/tests/Provider/QueryTestProvider.php b/tests/Provider/QueryTestProvider.php
new file mode 100644
index 0000000..b4d7cf5
--- /dev/null
+++ b/tests/Provider/QueryTestProvider.php
@@ -0,0 +1,402 @@
+ [
+ 'select' => new \stdClass(),
+ 'expected' => '$select argument must be a string or an array',
+ ],
+ 'select-all' => [
+ 'select' => '*',
+ 'expected' => 'SELECT *',
+ ],
+ 'select-columns' => [
+ 'select' => ['query', 'page', 'country', 'device'],
+ 'expected' => "SELECT query, page, country, device",
+ ],
+ 'select-columns-with-alias' => [
+ 'select' => [
+ 'SUM(clicks)' => 'sumCLicks',
+ 'SUM(impressions)' => 'sumImpressions',
+ ],
+ 'expected' => "SELECT SUM(clicks) as sumCLicks, SUM(impressions) as sumImpressions",
+ ],
+ ];
+ }
+
+ /**
+ * @return array
+ */
+ public function providerFrom()
+ {
+ return [
+ 'in-valid-from' => [
+ 'from' => new \stdClass(),
+ 'alias' => '',
+ 'expected' => '$from and $alias argument must be a string',
+ ],
+ 'in-valid-alias' => [
+ 'from' => 'table1',
+ 'alias' => new \stdClass(),
+ 'expected' => '$from and $alias argument must be a string',
+ ],
+ 'no-alias' => [
+ 'from' => 'table1',
+ 'alias' => '',
+ 'expected' => ' FROM (table1)',
+ ],
+ 'with-alias' => [
+ 'from' => 'SELECT * FROM B',
+ 'alias' => 'a',
+ 'expected' => ' FROM (SELECT * FROM B) AS a',
+ ],
+ ];
+ }
+
+ /**
+ * @return array
+ */
+ public function providerLeftJoin()
+ {
+ return [
+ 'invalid-table' => [
+ 'table' => ['table1'],
+ 'alias' => '',
+ 'expected' => '$table and $alias argument must be a string',
+ ],
+ 'invalid-alias' => [
+ 'table' => 'table1',
+ 'alias' => ['a'],
+ 'expected' => '$table and $alias argument must be a string',
+ ],
+ 'no-alias' => [
+ 'table' => 'table1',
+ 'alias' => '',
+ 'expected' => ' LEFT JOIN (table1)',
+ ],
+ 'with-alias' => [
+ 'table' => 'SELECT * FROM B',
+ 'alias' => 'b',
+ 'expected' => ' LEFT JOIN (SELECT * FROM B) AS b',
+ ],
+ ];
+ }
+
+ /**
+ * @return array
+ */
+ public function providerRightJoin()
+ {
+ return [
+ 'invalid-table' => [
+ 'table' => ['table1'],
+ 'alias' => '',
+ 'expected' => '$table and $alias argument must be a string',
+ ],
+ 'invalid-alias' => [
+ 'table' => 'table1',
+ 'alias' => ['a'],
+ 'expected' => '$table and $alias argument must be a string',
+ ],
+ 'no-alias' => [
+ 'table' => 'table1',
+ 'alias' => '',
+ 'expected' => ' RIGHT JOIN (table1)',
+ ],
+ 'with-alias' => [
+ 'table' => 'SELECT * FROM B',
+ 'alias' => 'b',
+ 'expected' => ' RIGHT JOIN (SELECT * FROM B) AS b',
+ ],
+ ];
+ }
+
+ /**
+ * @return array
+ */
+ public function providerInnerJoin()
+ {
+ return [
+ 'invalid-table' => [
+ 'table' => ['table1'],
+ 'alias' => '',
+ 'expected' => '$table and $alias argument must be a string',
+ ],
+ 'invalid-alias' => [
+ 'table' => 'table1',
+ 'alias' => ['a'],
+ 'expected' => '$table and $alias argument must be a string',
+ ],
+ 'no-alias' => [
+ 'table' => 'table1',
+ 'alias' => '',
+ 'expected' => ' INNER JOIN (table1)',
+ ],
+ 'with-alias' => [
+ 'table' => 'SELECT * FROM B',
+ 'alias' => 'b',
+ 'expected' => ' INNER JOIN (SELECT * FROM B) AS b',
+ ],
+ ];
+ }
+
+ /**
+ * @return array
+ */
+ public function providerFullJoin()
+ {
+ return [
+ 'invalid-table' => [
+ 'table' => ['table1'],
+ 'alias' => '',
+ 'expected' => '$table and $alias argument must be a string',
+ ],
+ 'invalid-alias' => [
+ 'table' => 'table1',
+ 'alias' => ['a'],
+ 'expected' => '$table and $alias argument must be a string',
+ ],
+ 'no-alias' => [
+ 'table' => 'table1',
+ 'alias' => '',
+ 'expected' => ' FULL JOIN (table1)',
+ ],
+ 'with-alias' => [
+ 'table' => 'SELECT * FROM B',
+ 'alias' => 'b',
+ 'expected' => ' FULL JOIN (SELECT * FROM B) AS b',
+ ],
+ ];
+ }
+
+ /**
+ * @return array
+ */
+ public function providerOn()
+ {
+ return [
+ 'invalid-leftCol' => [
+ 'leftCol' => ['table1'],
+ 'condition' => '=',
+ 'rightCol' => 'id',
+ 'expected' => '$leftCol, $condition and $rightCol argument must be a string',
+ ],
+ 'invalid-condition' => [
+ 'leftCol' => 'id',
+ 'condition' => ['='],
+ 'rightCol' => 'id',
+ 'expected' => '$leftCol, $condition and $rightCol argument must be a string',
+ ],
+ 'invalid-rightCol' => [
+ 'leftCol' => 'id',
+ 'condition' => '=',
+ 'rightCol' => ['id'],
+ 'expected' => '$leftCol, $condition and $rightCol argument must be a string',
+ ],
+ 'success' => [
+ 'leftCol' => 'a.id',
+ 'condition' => '=',
+ 'rightCol' => 'b.id',
+ 'expected' => ' ON a.id = b.id',
+ ],
+ ];
+ }
+
+ /**
+ * @return array
+ */
+ public function providerGroupBy()
+ {
+ return [
+ 'invalid-columns' => [
+ 'columns' => new \stdClass(),
+ 'expected' => '$columns argument must be an array or a string',
+ ],
+ 'string-column' => [
+ 'columns' => 'id',
+ 'expected' => ' GROUP BY id',
+ ],
+ 'array-column' => [
+ 'columns' => ['id', 'name'],
+ 'expected' => ' GROUP BY id, name',
+ ],
+ ];
+ }
+
+ /**
+ * @return array
+ */
+ public function providerOrderBy()
+ {
+ return [
+ 'invalid-column' => [
+ 'columns' => new \stdClass(),
+ 'sortType' => '',
+ 'expected' => '$column and $sortType argument must be a string',
+ ],
+ 'invalid-sortType' => [
+ 'columns' => 'id',
+ 'sortType' => [''],
+ 'expected' => '$column and $sortType argument must be a string',
+ ],
+ 'success' => [
+ 'columns' => 'id',
+ 'sortType' => 'DESC',
+ 'expected' => ' ORDER BY id DESC, id DESC',
+ ],
+ ];
+ }
+
+ /**
+ * @return array
+ */
+ public function providerLimit()
+ {
+ return [
+ 'invalid-limit-object' => [
+ 'limit' => new \stdClass(),
+ 'expected' => '$limit argument must be an integer',
+ ],
+ 'invalid-limit-string' => [
+ 'limit' => 'limit',
+ 'expected' => '$limit argument must be an integer',
+ ],
+ 'invalid-limit-array' => [
+ 'limit' => [1],
+ 'expected' => '$limit argument must be an integer',
+ ],
+ 'success' => [
+ 'limit' => 10,
+ 'expected' => ' LIMIT 10',
+ ],
+ ];
+ }
+
+ /**
+ * @return array
+ */
+ public function providerAndHaving()
+ {
+ return [
+ 'column-type-invalid' => [
+ 'column' => ['col1'],
+ 'condition' => '>',
+ 'value' => 1,
+ 'firstHaving' => true,
+ 'expected' => '$column and $condition argument must be a string',
+ ],
+ 'condition-type-invalid' => [
+ 'column' => 'col1',
+ 'condition' => ['>'],
+ 'value' => 1,
+ 'firstHaving' => true,
+ 'expected' => '$column and $condition argument must be a string',
+ ],
+ 'value-type-invalid' => [
+ 'column' => 'col1',
+ 'condition' => '>',
+ 'value' => new \stdClass(),
+ 'firstHaving' => true,
+ 'expected' => '$value argument must be a string, a numeric or an array',
+ ],
+ 'null-value' => [
+ 'column' => 'col1',
+ 'condition' => '=',
+ 'value' => NULL,
+ 'firstHaving' => true,
+ 'expected' => ' HAVING col1 = NULL',
+ ],
+ 'int-value' => [
+ 'column' => 'col1',
+ 'condition' => '>',
+ 'value' => 10,
+ 'firstHaving' => true,
+ 'expected' => ' HAVING col1 > 10',
+ ],
+ 'string-value' => [
+ 'column' => 'col1',
+ 'condition' => '!=',
+ 'value' => 'str',
+ 'firstHaving' => true,
+ 'expected' => " HAVING col1 != 'str'",
+ ],
+ 'array-value' => [
+ 'column' => 'col1',
+ 'condition' => 'IN',
+ 'value' => [1, 2, 3],
+ 'firstHaving' => false,
+ 'expected' => " AND col1 IN ('1', '2', '3')",
+ ],
+ ];
+ }
+
+ /**
+ * @return array
+ */
+ public function providerOrHaving()
+ {
+ return [
+ 'column-type-invalid' => [
+ 'column' => ['col1'],
+ 'condition' => '>',
+ 'value' => 1,
+ 'firstHaving' => true,
+ 'expected' => '$column and $condition argument must be a string',
+ ],
+ 'condition-type-invalid' => [
+ 'column' => 'col1',
+ 'condition' => ['>'],
+ 'value' => 1,
+ 'firstHaving' => true,
+ 'expected' => '$column and $condition argument must be a string',
+ ],
+ 'value-type-invalid' => [
+ 'column' => 'col1',
+ 'condition' => '>',
+ 'value' => new \stdClass(),
+ 'firstHaving' => true,
+ 'expected' => '$value argument must be a string, a numeric or an array',
+ ],
+ 'null-value' => [
+ 'column' => 'col1',
+ 'condition' => '=',
+ 'value' => NULL,
+ 'firstHaving' => true,
+ 'expected' => ' HAVING col1 = NULL',
+ ],
+ 'int-value' => [
+ 'column' => 'col1',
+ 'condition' => '>',
+ 'value' => 10,
+ 'firstHaving' => true,
+ 'expected' => ' HAVING col1 > 10',
+ ],
+ 'string-value' => [
+ 'column' => 'col1',
+ 'condition' => '!=',
+ 'value' => 'str',
+ 'firstHaving' => true,
+ 'expected' => " HAVING col1 != 'str'",
+ ],
+ 'array-value' => [
+ 'column' => 'col1',
+ 'condition' => 'IN',
+ 'value' => [1, 2, 3],
+ 'firstHaving' => false,
+ 'expected' => " OR col1 IN ('1', '2', '3')",
+ ],
+ ];
+ }
+}
diff --git a/tests/Provider/WhereTestProvider.php b/tests/Provider/WhereTestProvider.php
new file mode 100644
index 0000000..935ac11
--- /dev/null
+++ b/tests/Provider/WhereTestProvider.php
@@ -0,0 +1,125 @@
+ [
+ 'column' => ['err'],
+ 'condition' => '=',
+ 'value' => 1,
+ 'expected' => '$column and $condition argument must be a string',
+ ],
+ 'condition-invalid' => [
+ 'column' => 'a',
+ 'condition' => ['test'],
+ 'value' => 1,
+ 'expected' => '$column and $condition argument must be a string',
+ ],
+ 'value-invalid' => [
+ 'column' => 'a',
+ 'condition' => '=',
+ 'value' => new \stdClass(),
+ 'expected' => '$value argument must be a string, a numeric or an array',
+ ],
+ ];
+ }
+
+ /**
+ * @return array
+ */
+ public function providerGetWhereAndStr()
+ {
+ return [
+ 'is-first-where' => [
+ 'column' => 'col',
+ 'condition' => '=',
+ 'value' => 1,
+ 'isFirstWhere' => true,
+ 'expected' => ' WHERE col = 1',
+ ],
+ 'null-value' => [
+ 'column' => 'col',
+ 'condition' => 'IS',
+ 'value' => null,
+ 'isFirstWhere' => false,
+ 'expected' => " AND col IS NULL",
+ ],
+ 'numeric-value' => [
+ 'column' => 'col',
+ 'condition' => '>',
+ 'value' => 1.5,
+ 'isFirstWhere' => false,
+ 'expected' => " AND col > 1.5",
+ ],
+ 'string-value' => [
+ 'column' => 'col',
+ 'condition' => '=',
+ 'value' => 'test',
+ 'isFirstWhere' => false,
+ 'expected' => " AND col = 'test'",
+ ],
+ 'array-value' => [
+ 'column' => 'col',
+ 'condition' => 'IN',
+ 'value' => [1, 2, 3],
+ 'isFirstWhere' => false,
+ 'expected' => " AND col IN ('1', '2', '3')",
+ ],
+ ];
+ }
+
+ /**
+ * @return array
+ */
+ public function providerGetWhereOrStr()
+ {
+ return [
+ 'is-first-where' => [
+ 'column' => 'col',
+ 'condition' => '=',
+ 'value' => 1,
+ 'isFirstWhere' => true,
+ 'expected' => ' WHERE col = 1',
+ ],
+ 'null-value' => [
+ 'column' => 'col',
+ 'condition' => 'IS',
+ 'value' => null,
+ 'isFirstWhere' => false,
+ 'expected' => " OR col IS NULL",
+ ],
+ 'numeric-value' => [
+ 'column' => 'col',
+ 'condition' => '>',
+ 'value' => 1.5,
+ 'isFirstWhere' => false,
+ 'expected' => " OR col > 1.5",
+ ],
+ 'string-value' => [
+ 'column' => 'col',
+ 'condition' => '=',
+ 'value' => 'test',
+ 'isFirstWhere' => false,
+ 'expected' => " OR col = 'test'",
+ ],
+ 'array-value' => [
+ 'column' => 'col',
+ 'condition' => 'IN',
+ 'value' => [1, 2, 3],
+ 'isFirstWhere' => false,
+ 'expected' => " OR col IN ('1', '2', '3')",
+ ],
+ ];
+ }
+}
diff --git a/tests/QueryTest.php b/tests/QueryTest.php
index b0791e0..0a2ecb0 100644
--- a/tests/QueryTest.php
+++ b/tests/QueryTest.php
@@ -5,6 +5,7 @@
use MoiTran\PrestoQueryBuilder\Exception\InvalidArgumentException;
use MoiTran\PrestoQueryBuilder\Query;
use MoiTran\PrestoQueryBuilder\WhereGroup;
+use MoiTran\PrestoQueryBuilder\Tests\Provider\QueryTestProvider;
/**
* Class QueryTest
@@ -12,33 +13,7 @@
*/
class QueryTest extends TestCases
{
- /**
- * @return array
- */
- public function providerSelect()
- {
- return [
- 'in-valid' => [
- 'select' => new \stdClass(),
- 'expected' => '$select argument must be a string or an array',
- ],
- 'select-all' => [
- 'select' => '*',
- 'expected' => 'SELECT *',
- ],
- 'select-columns' => [
- 'select' => ['query', 'page', 'country', 'device'],
- 'expected' => "SELECT query, page, country, device",
- ],
- 'select-columns-with-alias' => [
- 'select' => [
- 'SUM(clicks)' => 'sumCLicks',
- 'SUM(impressions)' => 'sumImpressions',
- ],
- 'expected' => "SELECT SUM(clicks) as sumCLicks, SUM(impressions) as sumImpressions",
- ],
- ];
- }
+ use QueryTestProvider;
/**
* @param $select
@@ -58,35 +33,6 @@ public function testSelect($select, $expected)
}
}
- /**
- * @return array
- */
- public function providerFrom()
- {
- return [
- 'in-valid-from' => [
- 'from' => new \stdClass(),
- 'alias' => '',
- 'expected' => '$from and $alias argument must be a string',
- ],
- 'in-valid-alias' => [
- 'from' => 'table1',
- 'alias' => new \stdClass(),
- 'expected' => '$from and $alias argument must be a string',
- ],
- 'no-alias' => [
- 'from' => 'table1',
- 'alias' => '',
- 'expected' => ' FROM (table1)',
- ],
- 'with-alias' => [
- 'from' => 'SELECT * FROM B',
- 'alias' => 'a',
- 'expected' => ' FROM (SELECT * FROM B) AS a',
- ],
- ];
- }
-
/**
* @param $from
* @param @alias
@@ -106,35 +52,6 @@ public function testFrom($from, $alias, $expected)
}
}
- /**
- * @return array
- */
- public function providerLeftJoin()
- {
- return [
- 'invalid-table' => [
- 'table' => ['table1'],
- 'alias' => '',
- 'expected' => '$table and $alias argument must be a string',
- ],
- 'invalid-alias' => [
- 'table' => 'table1',
- 'alias' => ['a'],
- 'expected' => '$table and $alias argument must be a string',
- ],
- 'no-alias' => [
- 'table' => 'table1',
- 'alias' => '',
- 'expected' => ' LEFT JOIN (table1)',
- ],
- 'with-alias' => [
- 'table' => 'SELECT * FROM B',
- 'alias' => 'b',
- 'expected' => ' LEFT JOIN (SELECT * FROM B) AS b',
- ],
- ];
- }
-
/**
* @param $table
* @param $alias
@@ -154,35 +71,6 @@ public function testLeftJoin($table, $alias, $expected)
}
}
- /**
- * @return array
- */
- public function providerRightJoin()
- {
- return [
- 'invalid-table' => [
- 'table' => ['table1'],
- 'alias' => '',
- 'expected' => '$table and $alias argument must be a string',
- ],
- 'invalid-alias' => [
- 'table' => 'table1',
- 'alias' => ['a'],
- 'expected' => '$table and $alias argument must be a string',
- ],
- 'no-alias' => [
- 'table' => 'table1',
- 'alias' => '',
- 'expected' => ' RIGHT JOIN (table1)',
- ],
- 'with-alias' => [
- 'table' => 'SELECT * FROM B',
- 'alias' => 'b',
- 'expected' => ' RIGHT JOIN (SELECT * FROM B) AS b',
- ],
- ];
- }
-
/**
* @param $table
* @param $alias
@@ -202,35 +90,6 @@ public function testRightJoin($table, $alias, $expected)
}
}
- /**
- * @return array
- */
- public function providerInnerJoin()
- {
- return [
- 'invalid-table' => [
- 'table' => ['table1'],
- 'alias' => '',
- 'expected' => '$table and $alias argument must be a string',
- ],
- 'invalid-alias' => [
- 'table' => 'table1',
- 'alias' => ['a'],
- 'expected' => '$table and $alias argument must be a string',
- ],
- 'no-alias' => [
- 'table' => 'table1',
- 'alias' => '',
- 'expected' => ' INNER JOIN (table1)',
- ],
- 'with-alias' => [
- 'table' => 'SELECT * FROM B',
- 'alias' => 'b',
- 'expected' => ' INNER JOIN (SELECT * FROM B) AS b',
- ],
- ];
- }
-
/**
* @param $table
* @param $alias
@@ -250,35 +109,6 @@ public function testInnerJoin($table, $alias, $expected)
}
}
- /**
- * @return array
- */
- public function providerFullJoin()
- {
- return [
- 'invalid-table' => [
- 'table' => ['table1'],
- 'alias' => '',
- 'expected' => '$table and $alias argument must be a string',
- ],
- 'invalid-alias' => [
- 'table' => 'table1',
- 'alias' => ['a'],
- 'expected' => '$table and $alias argument must be a string',
- ],
- 'no-alias' => [
- 'table' => 'table1',
- 'alias' => '',
- 'expected' => ' FULL JOIN (table1)',
- ],
- 'with-alias' => [
- 'table' => 'SELECT * FROM B',
- 'alias' => 'b',
- 'expected' => ' FULL JOIN (SELECT * FROM B) AS b',
- ],
- ];
- }
-
/**
* @param $table
* @param $alias
@@ -298,39 +128,6 @@ public function testFullJoin($table, $alias, $expected)
}
}
- /**
- * @return array
- */
- public function providerOn()
- {
- return [
- 'invalid-leftCol' => [
- 'leftCol' => ['table1'],
- 'condition' => '=',
- 'rightCol' => 'id',
- 'expected' => '$leftCol, $condition and $rightCol argument must be a string',
- ],
- 'invalid-condition' => [
- 'leftCol' => 'id',
- 'condition' => ['='],
- 'rightCol' => 'id',
- 'expected' => '$leftCol, $condition and $rightCol argument must be a string',
- ],
- 'invalid-rightCol' => [
- 'leftCol' => 'id',
- 'condition' => '=',
- 'rightCol' => ['id'],
- 'expected' => '$leftCol, $condition and $rightCol argument must be a string',
- ],
- 'success' => [
- 'leftCol' => 'a.id',
- 'condition' => '=',
- 'rightCol' => 'b.id',
- 'expected' => ' ON a.id = b.id',
- ],
- ];
- }
-
/**
* @param $leftCol
* @param $condition
@@ -381,7 +178,13 @@ public function testWhereAndGroup()
->whereAnd('name', '=', 'test');
$query = new Query();
$actual = $query->whereAndGroup($whereGroup)->whereAndGroup($whereGroup)->getQueryStr();
- $expected = " WHERE AND (id > 1 AND name = 'test') AND (id > 1 AND name = 'test')";
+ $expected = " WHERE (id > 1 AND name = 'test') AND (id > 1 AND name = 'test')";
+ $this->assertEquals($expected, $actual);
+
+ $whereGroup = new WhereGroup();
+ $query = new Query();
+ $actual = $query->select('*')->from('db')->whereAndGroup($whereGroup)->getQueryStr();
+ $expected = 'SELECT * FROM (db)';
$this->assertEquals($expected, $actual);
}
@@ -395,7 +198,13 @@ public function testWhereOrGroup()
->whereOr('name', '=', 'test');
$query = new Query();
$actual = $query->whereOrGroup($whereGroup)->whereOrGroup($whereGroup)->getQueryStr();
- $expected = " WHERE OR (id > 1 OR name = 'test') OR (id > 1 OR name = 'test')";
+ $expected = " WHERE (id > 1 OR name = 'test') OR (id > 1 OR name = 'test')";
+ $this->assertEquals($expected, $actual);
+
+ $whereGroup = new WhereGroup();
+ $query = new Query();
+ $actual = $query->select('*')->from('db')->whereOrGroup($whereGroup)->getQueryStr();
+ $expected = 'SELECT * FROM (db)';
$this->assertEquals($expected, $actual);
}
@@ -420,27 +229,6 @@ public function testUnionAll()
$this->assertEquals($expected, $actual);
}
- /**
- * @return array
- */
- public function providerGroupBy()
- {
- return [
- 'invalid-columns' => [
- 'columns' => new \stdClass(),
- 'expected' => '$columns argument must be an array or a string',
- ],
- 'string-column' => [
- 'columns' => 'id',
- 'expected' => ' GROUP BY id',
- ],
- 'array-column' => [
- 'columns' => ['id', 'name'],
- 'expected' => ' GROUP BY id, name',
- ],
- ];
- }
-
/**
* @param $columns
* @param $expected
@@ -459,30 +247,6 @@ public function testGroupBy($columns, $expected)
}
}
- /**
- * @return array
- */
- public function providerOrderBy()
- {
- return [
- 'invalid-column' => [
- 'columns' => new \stdClass(),
- 'sortType' => '',
- 'expected' => '$column and $sortType argument must be a string',
- ],
- 'invalid-sortType' => [
- 'columns' => 'id',
- 'sortType' => [''],
- 'expected' => '$column and $sortType argument must be a string',
- ],
- 'success' => [
- 'columns' => 'id',
- 'sortType' => 'DESC',
- 'expected' => ' ORDER BY id DESC, id DESC',
- ],
- ];
- }
-
/**
* @param $column
* @param $sortType
@@ -503,41 +267,60 @@ public function testOrderBy($column, $sortType, $expected)
}
/**
- * @return array
+ * @param $limit
+ * @param $expected
+ *
+ * @dataProvider providerLimit
*/
- public function providerLimit()
+ public function testLimit($limit, $expected)
{
- return [
- 'invalid-limit-object' => [
- 'limit' => new \stdClass(),
- 'expected' => '$limit argument must be an integer',
- ],
- 'invalid-limit-string' => [
- 'limit' => 'limit',
- 'expected' => '$limit argument must be an integer',
- ],
- 'invalid-limit-array' => [
- 'limit' => [1],
- 'expected' => '$limit argument must be an integer',
- ],
- 'success' => [
- 'limit' => 10,
- 'expected' => ' LIMIT 10',
- ],
- ];
+ $query = new Query();
+ try {
+ $actual = $query->limit($limit)->getQueryStr();
+ $this->assertEquals($expected, $actual);
+ } catch (\Exception $e) {
+ $this->assertInstanceOf(InvalidArgumentException::class, $e);
+ $this->assertEquals($expected, $e->getMessage());
+ }
}
/**
- * @param $limit
+ * @param $column
+ * @param $condition
+ * @param $value
+ * @param $firstHaving
* @param $expected
*
- * @dataProvider providerLimit
+ * @dataProvider providerAndHaving
*/
- public function testLimit($limit, $expected)
+ public function testAndHaving($column, $condition, $value, $firstHaving, $expected)
{
$query = new Query();
try {
- $actual = $query->limit($limit)->getQueryStr();
+ $this->setPrivateProp($query, 'isFirstHaving', $firstHaving);
+ $actual = $query->andHaving($column, $condition, $value)->getQueryStr();
+ $this->assertEquals($expected, $actual);
+ } catch (\Exception $e) {
+ $this->assertInstanceOf(InvalidArgumentException::class, $e);
+ $this->assertEquals($expected, $e->getMessage());
+ }
+ }
+
+ /**
+ * @param $column
+ * @param $condition
+ * @param $value
+ * @param $firstHaving
+ * @param $expected
+ *
+ * @dataProvider providerOrHaving
+ */
+ public function testOrHaving($column, $condition, $value, $firstHaving, $expected)
+ {
+ $query = new Query();
+ try {
+ $this->setPrivateProp($query, 'isFirstHaving', $firstHaving);
+ $actual = $query->orHaving($column, $condition, $value)->getQueryStr();
$this->assertEquals($expected, $actual);
} catch (\Exception $e) {
$this->assertInstanceOf(InvalidArgumentException::class, $e);
diff --git a/tests/TestCases.php b/tests/TestCases.php
index f0fda4d..c3c2cce 100644
--- a/tests/TestCases.php
+++ b/tests/TestCases.php
@@ -8,4 +8,21 @@
*/
class TestCases extends \PHPUnit\Framework\TestCase
{
+ /**
+ * @param $object
+ * @param $property
+ * @param $value
+ *
+ * @return bool
+ * @throws \ReflectionException
+ */
+ public function setPrivateProp(&$object, $property, $value)
+ {
+ $reflection = new \ReflectionClass(get_class($object));
+ $prop = $reflection->getProperty($property);
+ $prop->setAccessible(true);
+ $prop->setValue($object, $value);
+
+ return true;
+ }
}
diff --git a/tests/WhereGroupTest.php b/tests/WhereGroupTest.php
index dc84304..788fdaa 100644
--- a/tests/WhereGroupTest.php
+++ b/tests/WhereGroupTest.php
@@ -21,7 +21,7 @@ public function testWhereAdd()
->whereAnd('col3', 'IN', [1, 2, 3, 4])
->getWhereConditions();
- $expected = "col1 > 10 AND col2 IS NULL AND col3 IN ('1','2','3','4')";
+ $expected = "col1 > 10 AND col2 IS NULL AND col3 IN ('1', '2', '3', '4')";
$this->assertEquals($expected, $actual);
}
@@ -36,7 +36,7 @@ public function testWhereOr()
->whereOr('col3', 'IN', [1, 2, 3, 4])
->getWhereConditions();
- $expected = "col1 > 10 OR col2 IS NULL OR col3 IN ('1','2','3','4')";
+ $expected = "col1 > 10 OR col2 IS NULL OR col3 IN ('1', '2', '3', '4')";
$this->assertEquals($expected, $actual);
}
@@ -52,6 +52,15 @@ public function testWhereOrGroup()
$expected = "(col1 != 'not1' AND col1 != 'not2')";
$this->assertEquals($expected, $actual);
+
+ $whereGroup = new WhereGroup();
+ $actual = $whereGroup->whereOrGroup((new WhereGroup()))
+ ->whereAnd('col1', '!=', 'not2')
+ ->whereAnd('col2', '!=', 'not2')
+ ->getWhereConditions();
+
+ $expected = "col1 != 'not2' AND col2 != 'not2'";
+ $this->assertEquals($expected, $actual);
}
/**
@@ -66,5 +75,14 @@ public function testWhereAndGroup()
$expected = "(col1 != 'not1' AND col1 != 'not2')";
$this->assertEquals($expected, $actual);
+
+ $whereGroup = new WhereGroup();
+ $actual = $whereGroup->whereAndGroup((new WhereGroup()))
+ ->whereAnd('col1', '!=', 'not2')
+ ->whereAnd('col2', '!=', 'not2')
+ ->getWhereConditions();
+
+ $expected = "col1 != 'not2' AND col2 != 'not2'";
+ $this->assertEquals($expected, $actual);
}
}
diff --git a/tests/WhereTest.php b/tests/WhereTest.php
index e619b7f..e8afdc8 100644
--- a/tests/WhereTest.php
+++ b/tests/WhereTest.php
@@ -4,6 +4,7 @@
use MoiTran\PrestoQueryBuilder\Exception\InvalidArgumentException;
use MoiTran\PrestoQueryBuilder\Where;
+use MoiTran\PrestoQueryBuilder\Tests\Provider\WhereTestProvider;
/**
* Class ExampleTest
@@ -11,33 +12,7 @@
class WhereTest extends TestCases
{
use Where;
-
- /**
- * @return array
- */
- public function providerWhereThrowException()
- {
- return [
- 'column-invalid' => [
- 'column' => ['err'],
- 'condition' => '=',
- 'value' => 1,
- 'expected' => '$column and $condition argument must be a string',
- ],
- 'condition-invalid' => [
- 'column' => 'a',
- 'condition' => ['test'],
- 'value' => 1,
- 'expected' => '$column and $condition argument must be a string',
- ],
- 'value-invalid' => [
- 'column' => 'a',
- 'condition' => '=',
- 'value' => new \stdClass(),
- 'expected' => '$value argument must be a string, a numeric or an array',
- ],
- ];
- }
+ use WhereTestProvider;
/**
* @param $column
@@ -57,50 +32,6 @@ public function testWhereThrowException($column, $condition, $value, $expected)
}
}
- /**
- * @return array
- */
- public function providerGetWhereAndStr()
- {
- return [
- 'is-first-where' => [
- 'column' => 'col',
- 'condition' => '=',
- 'value' => 1,
- 'isFirstWhere' => true,
- 'expected' => ' WHERE col = 1',
- ],
- 'null-value' => [
- 'column' => 'col',
- 'condition' => 'IS',
- 'value' => NULL,
- 'isFirstWhere' => false,
- 'expected' => " AND col IS NULL",
- ],
- 'numeric-value' => [
- 'column' => 'col',
- 'condition' => '>',
- 'value' => 1.5,
- 'isFirstWhere' => false,
- 'expected' => " AND col > 1.5",
- ],
- 'string-value' => [
- 'column' => 'col',
- 'condition' => '=',
- 'value' => 'test',
- 'isFirstWhere' => false,
- 'expected' => " AND col = 'test'",
- ],
- 'array-value' => [
- 'column' => 'col',
- 'condition' => 'IN',
- 'value' => [1, 2, 3],
- 'isFirstWhere' => false,
- 'expected' => " AND col IN ('1','2','3')",
- ],
- ];
- }
-
/**
* @param $column
* @param $condition
@@ -117,50 +48,6 @@ public function testGetWhereAndStr($column, $condition, $value, $isFirstWhere, $
$this->assertEquals($expected, $actual);
}
- /**
- * @return array
- */
- public function providerGetWhereOrStr()
- {
- return [
- 'is-first-where' => [
- 'column' => 'col',
- 'condition' => '=',
- 'value' => 1,
- 'isFirstWhere' => true,
- 'expected' => ' WHERE col = 1',
- ],
- 'null-value' => [
- 'column' => 'col',
- 'condition' => 'IS',
- 'value' => NULL,
- 'isFirstWhere' => false,
- 'expected' => " OR col IS NULL",
- ],
- 'numeric-value' => [
- 'column' => 'col',
- 'condition' => '>',
- 'value' => 1.5,
- 'isFirstWhere' => false,
- 'expected' => " OR col > 1.5",
- ],
- 'string-value' => [
- 'column' => 'col',
- 'condition' => '=',
- 'value' => 'test',
- 'isFirstWhere' => false,
- 'expected' => " OR col = 'test'",
- ],
- 'array-value' => [
- 'column' => 'col',
- 'condition' => 'IN',
- 'value' => [1, 2, 3],
- 'isFirstWhere' => false,
- 'expected' => " OR col IN ('1','2','3')",
- ],
- ];
- }
-
/**
* @param $column
* @param $condition