diff --git a/docs/Select.md b/docs/Select.md index d67e002..fe8092d 100644 --- a/docs/Select.md +++ b/docs/Select.md @@ -70,7 +70,7 @@ SELECT * FROM `users` WHERE (`id` > 1) AND (`group_id` = 2); ```php $results = $query->select('users')->like(['name', '%John%'])->all(); -# or with WHERE +// or with WHERE $results = $query->select('users')->where([['name', 'LIKE', '%John%']])->all(); ``` or it's able to use two strings (instead of an array) in parameters since [v0.3.5](https://github.com/co0lc0der/simple-query-builder-php/releases/tag/v0.3.5) @@ -84,7 +84,7 @@ SELECT * FROM `users` WHERE (`name` LIKE '%John%'); ```php $results = $query->select('users')->notLike(['name', '%John%'])->all(); -# or with WHERE +// or with WHERE $results = $query->select('users')->where([['name', 'NOT LIKE', '%John%']])->all(); ``` or it's able to use two strings (instead of an array) in parameters since [v0.3.5](https://github.com/co0lc0der/simple-query-builder-php/releases/tag/v0.3.5) @@ -100,7 +100,7 @@ since [v0.3.5](https://github.com/co0lc0der/simple-query-builder-php/releases/ta ```php $results = $query->select('users')->isNull('phone')->all(); -# or with WHERE +// or with WHERE $results = $query->select('users')->where([['phone', 'is null']])->all(); ``` Result query @@ -110,10 +110,10 @@ SELECT * FROM `users` WHERE (`phone` IS NULL); ```php $results = $query->select('customers')->isNotNull('address')->all(); -# or +// or $results = $query->select('customers')->notNull('address')->all(); -# or with WHERE +// or with WHERE $results = $query->select('customers')->where([['address', 'is not null']])->all(); ``` Result query @@ -145,7 +145,7 @@ SELECT * FROM `posts` WHERE (`user_id` = 3) OFFSET 14 LIMIT 7; ```php $results = $query->select('users', ['counter' => 'COUNT(*)'])->one(); -# or +// or $results = $query->count('users'); ``` Result query @@ -174,7 +174,13 @@ ORDER BY `b`.`id` DESC; ``` #### `DISTINCT` ```php -$results = $query->select('customers', ['city', 'country'], true)->orderBy('country desc')->all(); +$results = $query->select('customers', ['city', 'country'], true) + ->orderBy('country desc')->all(); +``` +or since [v0.4.1](https://github.com/co0lc0der/simple-query-builder-php/releases/tag/v0.4.1) +```php +$results = $query->selectDistinct('customers', ['city', 'country']) + ->orderBy('country desc')->all(); ``` Result query ```sql diff --git a/docs/Select_ext.md b/docs/Select_ext.md index d8c2e30..606e025 100644 --- a/docs/Select_ext.md +++ b/docs/Select_ext.md @@ -79,12 +79,12 @@ ORDER BY `cp`.`cab_id` ASC, `cp`.`printer_id` DESC; ``` ### `LEFT [OUTER] JOIN` ```php -# LEFT JOIN +// LEFT JOIN $results = $query->select('employees', ['employees.employee_id', 'employees.last_name', 'positions.title']) ->join('positions', ['employees.position_id', 'positions.position_id'], "left") ->all(); -# or LEFT OUTER JOIN +// or LEFT OUTER JOIN $results = $query->select('employees', ['employees.employee_id', 'employees.last_name', 'positions.title']) ->join('positions', ['employees.position_id', 'positions.position_id'], "left outer") ->all(); @@ -158,7 +158,7 @@ $results = $query->select('clients', ['name', 'age']) ->select('employees', ['name', 'age']) ->all(); -# or +// or $results = $query->select('clients', ['name', 'age']) ->unionSelect('employees') ->all(); @@ -176,11 +176,24 @@ $results = $query->select('clients', ['name', 'age']) ->select('employees', ['name', 'age']) ->all(); -# or +// or $results = $query->select('clients', ['name', 'age']) ->unionSelect('employees', true) ->all(); ``` +or since [v0.4.1](https://github.com/co0lc0der/simple-query-builder-php/releases/tag/v0.4.1) +```php +$results = $query->select('clients', ['name', 'age']) + ->unionAll() + ->select('employees', ['name', 'age']) + ->all(); + + +// or +$results = $query->select('clients', ['name', 'age']) + ->unionSelectAll('employees') + ->all(); +``` Result query ```sql SELECT `name`, `age` FROM `clients` diff --git a/docs/Table.md b/docs/Table.md index 2d26b16..ee98c42 100644 --- a/docs/Table.md +++ b/docs/Table.md @@ -4,7 +4,7 @@ Truncate a table **! This method will be moved into _TableBuilder_ class !** ```php -$query->truncate('users')->go() +$query->truncate('users')->go(); ``` Result query ```sql @@ -15,7 +15,7 @@ TRUNCATE TABLE `users`; **! This method will be moved into _TableBuilder_ class !** ```php -$query->drop('temporary')->go() +$query->drop('temporary')->go(); ``` Result query ```sql @@ -23,7 +23,7 @@ DROP TABLE IF EXISTS `temporary`; ``` - Without `IF EXISTS` ```php -$query->drop('temporary', false)->go() +$query->drop('temporary', false)->go(); ``` Result query ```sql diff --git a/docs/View.md b/docs/View.md index c34dc62..261ea4a 100644 --- a/docs/View.md +++ b/docs/View.md @@ -17,7 +17,7 @@ One more example $query->select('users') ->isNull('email') ->createView('users_no_email') - ->go() + ->go(); ``` Result query ```sql @@ -45,7 +45,7 @@ DROP VIEW IF EXISTS `users_no_email`; ``` - Without `IF EXISTS` ```php -$query->dropView('users_no_email', false)->go() +$query->dropView('users_no_email', false)->go(); ``` Result query ```sql diff --git a/src/QueryBuilder.php b/src/QueryBuilder.php index 6b64d79..6e27c99 100644 --- a/src/QueryBuilder.php +++ b/src/QueryBuilder.php @@ -200,7 +200,7 @@ public function go(): int /** * @param array|string $table * @param string $field - * @return string|$this + * @return QueryBuilder|array */ public function count($table, string $field = '') { @@ -221,7 +221,7 @@ public function count($table, string $field = '') /** * @param string $column - * @return QueryBuilder|string|array + * @return QueryBuilder|array */ public function column(string $column = 'id') { @@ -236,6 +236,7 @@ public function column(string $column = 'id') } $this->query(); + return array_column($this->result, $column); //$this->query('', [], $column, self::FETCH_COLUMN); //return $this->result; @@ -268,6 +269,7 @@ public function pluck(string $key = 'id', string $column = '') } $this->query(); + return array_column($this->result, $column, $key); } @@ -511,7 +513,7 @@ private function prepareSorting(string $field = '', string $sort = ''): array * @param array $params * @param int|string $column * @param int $fetch - * @return $this + * @return QueryBuilder */ public function query(string $sql = '', array $params = [], $column = 0, int $fetch = self::FETCH_ALL): QueryBuilder { @@ -556,12 +558,13 @@ public function query(string $sql = '', array $params = [], $column = 0, int $fe return $this; } - /** - * @param array|string $table - * @param array|string $fields - * @return $this - */ - public function select($table, $fields = '*', $dist = false): QueryBuilder + /** + * @param array|string $table + * @param array|string $fields + * @param bool $dist + * @return QueryBuilder + */ + public function select($table, $fields = '*', bool $dist = false): QueryBuilder { if (empty($table) || empty($fields)) { $this->setError('Empty $table or $fields in ' . __METHOD__); @@ -595,10 +598,27 @@ public function select($table, $fields = '*', $dist = false): QueryBuilder return $this; } + /** + * @param array|string $table + * @param array|string $fields + * @return QueryBuilder + */ + public function selectDistinct($table, $fields = '*'): QueryBuilder + { + if (!empty($table) && !empty($fields)) { + $this->select($table, $fields, true); + } else { + $this->setError('Empty $table or $fields in ' . __METHOD__); + return $this; + } + + return $this; + } + /** * @param array|string $where * @param string $addition - * @return $this + * @return QueryBuilder */ public function where($where, string $addition = ''): QueryBuilder { @@ -624,7 +644,7 @@ public function where($where, string $addition = ''): QueryBuilder /** * @param array|string $having - * @return $this + * @return QueryBuilder */ public function having($having): QueryBuilder { @@ -647,7 +667,7 @@ public function having($having): QueryBuilder /** * @param array|string $field * @param string $value - * @return $this + * @return QueryBuilder */ public function like($field, string $value = ''): QueryBuilder { @@ -670,7 +690,7 @@ public function like($field, string $value = ''): QueryBuilder /** * @param array|string $field * @param string $value - * @return $this + * @return QueryBuilder */ public function notLike($field, string $value = ''): QueryBuilder { @@ -707,7 +727,7 @@ public function isNull(string $field): QueryBuilder /** * @param string $field - * @return $this + * @return QueryBuilder */ public function isNotNull(string $field): QueryBuilder { @@ -722,7 +742,7 @@ public function isNotNull(string $field): QueryBuilder /** * @param string $field - * @return $this + * @return QueryBuilder */ public function notNull(string $field): QueryBuilder { @@ -732,7 +752,7 @@ public function notNull(string $field): QueryBuilder /** * @param int $limit - * @return $this + * @return QueryBuilder */ public function limit(int $limit = 1): QueryBuilder { @@ -747,7 +767,7 @@ public function limit(int $limit = 1): QueryBuilder /** * @param int $offset - * @return $this + * @return QueryBuilder */ public function offset(int $offset = 0): QueryBuilder { @@ -758,7 +778,7 @@ public function offset(int $offset = 0): QueryBuilder /** * @param string|array $field * @param string $sort - * @return $this + * @return QueryBuilder */ public function orderBy($field = '', string $sort = ''): QueryBuilder { @@ -793,7 +813,7 @@ public function orderBy($field = '', string $sort = ''): QueryBuilder /** * @param string|array $field - * @return $this + * @return QueryBuilder */ public function groupBy($field = ''): QueryBuilder { @@ -809,7 +829,7 @@ public function groupBy($field = ''): QueryBuilder /** * @param array|string $table - * @return $this + * @return QueryBuilder */ public function delete($table): QueryBuilder { @@ -835,7 +855,7 @@ public function delete($table): QueryBuilder /** * @param array|string $table * @param array $fields - * @return $this + * @return QueryBuilder */ public function insert($table, array $fields = []): QueryBuilder { @@ -880,7 +900,7 @@ public function insert($table, array $fields = []): QueryBuilder /** * @param array|string $table * @param array $fields - * @return $this + * @return QueryBuilder */ public function update($table, array $fields = []): QueryBuilder { @@ -914,9 +934,9 @@ public function update($table, array $fields = []): QueryBuilder /** * @param array|string $table - * @param $on + * @param array|string $on * @param string $join_type - * @return $this + * @return QueryBuilder */ public function join($table, $on, string $join_type = 'INNER'): QueryBuilder { @@ -963,7 +983,7 @@ public function join($table, $on, string $join_type = 'INNER'): QueryBuilder /** * @param bool $unionAll - * @return $this + * @return QueryBuilder */ public function union(bool $unionAll = false): QueryBuilder { @@ -972,10 +992,20 @@ public function union(bool $unionAll = false): QueryBuilder return $this; } + /** + * @return QueryBuilder + */ + public function unionAll(): QueryBuilder + { + $this->concat = true; + $this->sql .= ' UNION ALL '; + return $this; + } + /** * @param string|array $table * @param bool $unionAll - * @return $this + * @return QueryBuilder */ public function unionSelect($table, bool $unionAll = false): QueryBuilder { @@ -984,11 +1014,6 @@ public function unionSelect($table, bool $unionAll = false): QueryBuilder return $this; } - if (mb_strpos(mb_strtolower($this->sql), 'union') !== false) { - $this->setError('SQL has already UNION in ' . __METHOD__); - return $this; - } - $this->concat = true; $fields = $this->fields ? : '*'; $this->sql .= $unionAll ? ' UNION ALL ' : ' UNION '; @@ -1004,7 +1029,23 @@ public function unionSelect($table, bool $unionAll = false): QueryBuilder } /** - * @return $this + * @param string|array $table + * @return QueryBuilder + */ + public function unionSelectAll($table): QueryBuilder + { + if (empty($table)) { + $this->setError('Empty $table in ' . __METHOD__); + return $this; + } + + $this->unionSelect($table, true); + + return $this; + } + + /** + * @return QueryBuilder */ public function excepts(): QueryBuilder { @@ -1014,8 +1055,8 @@ public function excepts(): QueryBuilder } /** - * @param $table - * @return $this + * @param string|array $table + * @return QueryBuilder */ public function exceptSelect($table): QueryBuilder { @@ -1043,7 +1084,7 @@ public function exceptSelect($table): QueryBuilder } /** - * @return $this + * @return QueryBuilder */ public function intersect(): QueryBuilder { @@ -1053,8 +1094,8 @@ public function intersect(): QueryBuilder } /** - * @param $table - * @return $this + * @param string|array $table + * @return QueryBuilder */ public function intersectSelect($table): QueryBuilder { @@ -1092,7 +1133,7 @@ public function __toString(): string /** * @param string $viewName * @param bool $addExists - * @return $this + * @return QueryBuilder */ public function createView(string $viewName, bool $addExists = true): QueryBuilder { @@ -1117,7 +1158,7 @@ public function createView(string $viewName, bool $addExists = true): QueryBuild /** * @param string $viewName * @param bool $addExists - * @return $this + * @return QueryBuilder */ public function dropView(string $viewName, bool $addExists = true): QueryBuilder { @@ -1138,7 +1179,7 @@ public function dropView(string $viewName, bool $addExists = true): QueryBuilder /** * @param string $table * @param bool $addExists - * @return $this + * @return QueryBuilder */ public function drop(string $table, bool $addExists = true): QueryBuilder { @@ -1157,7 +1198,7 @@ public function drop(string $table, bool $addExists = true): QueryBuilder /** * @param string $table - * @return $this + * @return QueryBuilder */ public function truncate(string $table): QueryBuilder { @@ -1172,6 +1213,9 @@ public function truncate(string $table): QueryBuilder return $this; } + /** + * @return string + */ public function getDriver(): string { return strtolower($this->pdo->getAttribute(PDO::ATTR_DRIVER_NAME)); diff --git a/tests/SqlSelectExtTest.php b/tests/SqlSelectExtTest.php index 7a5f9db..cc63e12 100644 --- a/tests/SqlSelectExtTest.php +++ b/tests/SqlSelectExtTest.php @@ -183,6 +183,20 @@ public function testSelectUnionAllWhere() $this->assertSame([3000, 3000], $result->getParams()); } + public function testSelectUnionAllMethodWhere() + { + $result = $this->qb->select('clients', ['name', 'age', 'total_sum' => 'account_sum + account_sum * 0.1']) + ->where([['account_sum', '<', 3000]]) + ->unionAll() + ->select('clients', ['name', 'age', 'total_sum' => 'account_sum + account_sum * 0.3']) + ->where([['account_sum', '>=', 3000]]); + + $this->assertSame($this->qb, $result); + $this->assertSame(false, $result->hasError()); + $this->assertSame("SELECT `name`, `age`, account_sum + account_sum * 0.1 AS `total_sum` FROM `clients` WHERE (`account_sum` < 3000) UNION ALL SELECT `name`, `age`, account_sum + account_sum * 0.3 AS `total_sum` FROM `clients` WHERE (`account_sum` >= 3000)", $result->getSql()); + $this->assertSame([3000, 3000], $result->getParams()); + } + public function testSelectUnionWhereOrderBy() { $result = $this->qb->select('departments', ['department_id', 'department_name']) @@ -211,6 +225,20 @@ public function testSelectUnionAllWhereOrderBy() $this->assertSame([10, 'Rassohin'], $result->getParams()); } + public function testSelectUnionAllMethodWhereOrderBy() + { + $result = $this->qb->select('departments', ['department_id', 'department_name']) + ->where([['department_id', '>=', 10]]) + ->unionAll() + ->select('employees', ['employee_id', 'last_name']) + ->where([['last_name', 'Rassohin']])->orderBy('2'); + + $this->assertSame($this->qb, $result); + $this->assertSame(false, $result->hasError()); + $this->assertSame("SELECT `department_id`, `department_name` FROM `departments` WHERE (`department_id` >= 10) UNION ALL SELECT `employee_id`, `last_name` FROM `employees` WHERE (`last_name` = 'Rassohin') ORDER BY `2` ASC", $result->getSql()); + $this->assertSame([10, 'Rassohin'], $result->getParams()); + } + public function testUnionSelectEmptyTable() { $result = $this->qb->select('clients', ['name', 'age'])->unionSelect(''); @@ -220,22 +248,22 @@ public function testUnionSelectEmptyTable() $this->assertSame($result->getErrorMessage(), 'Empty $table in QueryBuilder::unionSelect'); } - public function testUnionSelectIncorrectTable() + public function testUnionSelectAllMethodEmptyTable() { - $result = $this->qb->select('clients', ['name', 'age'])->unionSelect(2); + $result = $this->qb->select('clients', ['name', 'age'])->unionSelectAll(''); $this->assertSame($this->qb, $result); $this->assertSame(true, $result->hasError()); - $this->assertSame($result->getErrorMessage(), 'Incorrect type of $table in QueryBuilder::unionSelect. $table must be a string or an array'); + $this->assertSame($result->getErrorMessage(), 'Empty $table in QueryBuilder::unionSelectAll'); } - public function testUnionSelectDoubleUnion() + public function testUnionSelectIncorrectTable() { - $result = $this->qb->select('clients', ['name', 'age'])->union()->unionSelect('clients'); + $result = $this->qb->select('clients', ['name', 'age'])->unionSelect(2); $this->assertSame($this->qb, $result); $this->assertSame(true, $result->hasError()); - $this->assertSame($result->getErrorMessage(), 'SQL has already UNION in QueryBuilder::unionSelect'); + $this->assertSame($result->getErrorMessage(), 'Incorrect type of $table in QueryBuilder::unionSelect. $table must be a string or an array'); } public function testUnionSelectWhere() @@ -260,6 +288,17 @@ public function testUnionAllSelectWhere() $this->assertSame([10], $result->getParams()); } + public function testUnionSelectAllMethodWhere() + { + $result = $this->qb->select('cabs', ['id', 'name']) + ->unionSelectAll('printer_models')->where([['id', '<', 10]]); + + $this->assertSame($this->qb, $result); + $this->assertSame(false, $result->hasError()); + $this->assertSame("SELECT `id`, `name` FROM `cabs` UNION ALL SELECT `id`, `name` FROM `printer_models` WHERE (`id` < 10)", $result->getSql()); + $this->assertSame([10], $result->getParams()); + } + public function testSelectExceptsWhere() { $result = $this->qb->select('contacts', ['contact_id', 'last_name', 'first_name']) diff --git a/tests/SqlSelectTest.php b/tests/SqlSelectTest.php index a72f498..f8fcee0 100644 --- a/tests/SqlSelectTest.php +++ b/tests/SqlSelectTest.php @@ -21,7 +21,7 @@ protected function setUp(): void } } - public function testEmptyTable() + public function testSelectEmptyTable() { $result = $this->qb->select('', 'param'); @@ -30,7 +30,7 @@ public function testEmptyTable() $this->assertSame($result->getErrorMessage(), 'Empty $table or $fields in QueryBuilder::select'); } - public function testEmptyFields() + public function testSelectEmptyFields() { $result = $this->qb->select('users', []); @@ -39,7 +39,7 @@ public function testEmptyFields() $this->assertSame($result->getErrorMessage(), 'Empty $table or $fields in QueryBuilder::select'); } - public function testEmptyTableAndFields() + public function testSelectEmptyTableAndFields() { $result = $this->qb->select('', []); @@ -68,7 +68,7 @@ public function testGetSqlNoValues() $this->assertSame([1], $result->getParams()); } - public function testSelectAll() + public function testSelect() { $result = $this->qb->select('users'); @@ -77,6 +77,15 @@ public function testSelectAll() $this->assertSame([], $result->getParams()); } + public function testSelectAliasAll() + { + $result = $this->qb->select(['u' => 'users'], 'u.*'); + + $this->assertSame(false, $result->hasError()); + $this->assertSame("SELECT u.* FROM `users` AS `u`", $result->getSql()); + $this->assertSame([], $result->getParams()); + } + public function testSelectWhereEq() { $result = $this->qb->select('users')->where([['id', '=', 10]]); @@ -257,6 +266,33 @@ public function testSelectCounter() $this->assertSame([], $result->getParams()); } + public function testSelectDistinctMethodEmptyTable() + { + $result = $this->qb->selectDistinct('', 'param'); + + $this->assertSame($this->qb, $result); + $this->assertSame(true, $result->hasError()); + $this->assertSame($result->getErrorMessage(), 'Empty $table or $fields in QueryBuilder::selectDistinct'); + } + + public function testSelectDistinctMethodEmptyFields() + { + $result = $this->qb->selectDistinct('users', []); + + $this->assertSame($this->qb, $result); + $this->assertSame(true, $result->hasError()); + $this->assertSame($result->getErrorMessage(), 'Empty $table or $fields in QueryBuilder::selectDistinct'); + } + + public function testSelectDistinctMethodEmptyTableAndFields() + { + $result = $this->qb->selectDistinct('', []); + + $this->assertSame($this->qb, $result); + $this->assertSame(true, $result->hasError()); + $this->assertSame($this->qb->getErrorMessage(), 'Empty $table or $fields in QueryBuilder::selectDistinct'); + } + public function testSelectDistinctOrderBy() { $result = $this->qb->select('customers', 'city', true)->orderBy('city'); @@ -266,6 +302,15 @@ public function testSelectDistinctOrderBy() $this->assertSame([], $result->getParams()); } + public function testSelectDistinctMethodOrderBy() + { + $result = $this->qb->selectDistinct('customers', 'city')->orderBy('city'); + + $this->assertSame(false, $result->hasError()); + $this->assertSame("SELECT DISTINCT `city` FROM `customers` ORDER BY `city` ASC", $result->getSql()); + $this->assertSame([], $result->getParams()); + } + public function testSelectDistinctOrderBy2Col() { $result = $this->qb->select('customers', ['city', 'country'], true)->orderBy('country desc'); @@ -275,6 +320,15 @@ public function testSelectDistinctOrderBy2Col() $this->assertSame([], $result->getParams()); } + public function testSelectDistinctMethodOrderBy2Col() + { + $result = $this->qb->selectDistinct('customers', ['city', 'country'])->orderBy('country desc'); + + $this->assertSame(false, $result->hasError()); + $this->assertSame("SELECT DISTINCT `city`, `country` FROM `customers` ORDER BY `country` DESC", $result->getSql()); + $this->assertSame([], $result->getParams()); + } + public function testSelectOrderByTwoParams() { $result = $this->qb->select(['b' => 'branches'], ['b.id', 'b.name']) @@ -347,7 +401,7 @@ public function testSelectGroupByHavingCount() $this->assertSame(['Nevada', 20], $result->getParams()); } - public function testSelectSumm() + public function testSelectSum() { $result = $this->qb->select("1+5 as 'res'");