From 49f12ac82f68e79a4c6fa69c19af7cab0cb6f007 Mon Sep 17 00:00:00 2001 From: Yuri Kuznetsov Date: Sun, 25 Jul 2021 10:15:00 +0300 Subject: [PATCH] orm refactoring --- application/Espo/ORM/Query/Delete.php | 18 +++ application/Espo/ORM/Query/LockTable.php | 4 +- application/Espo/ORM/Query/Select.php | 110 ++++++++++++------ application/Espo/ORM/Query/SelectBuilder.php | 4 +- application/Espo/ORM/Query/SelectingTrait.php | 45 +++++++ application/Espo/ORM/Query/Update.php | 18 +++ application/Espo/ORM/Query/UpdateBuilder.php | 1 - .../Espo/ORM/Repository/RDBRelation.php | 6 +- .../Repository/RDBRelationSelectBuilder.php | 6 +- .../Espo/ORM/Repository/RDBRepository.php | 6 +- .../Espo/ORM/Repository/RDBSelectBuilder.php | 6 +- .../unit/Espo/ORM/Query/SelectBuilderTest.php | 32 +++-- 12 files changed, 197 insertions(+), 59 deletions(-) diff --git a/application/Espo/ORM/Query/Delete.php b/application/Espo/ORM/Query/Delete.php index 6d6c6bad65..b36e155816 100644 --- a/application/Espo/ORM/Query/Delete.php +++ b/application/Espo/ORM/Query/Delete.php @@ -29,6 +29,8 @@ namespace Espo\ORM\Query; +use Espo\ORM\Query\Part\WhereClause; + use RuntimeException; /** @@ -47,6 +49,22 @@ class Delete implements Query return $this->params['from']; } + /** + * Get a from-alias + */ + public function getFromAlias(): ?string + { + return $this->params['fromAlias'] ?? null; + } + + /** + * Get a LIMIT. + */ + public function getLimit(): ?int + { + return $this->params['limit'] ?? null; + } + private function validateRawParams(array $params): void { $this->validateRawParamsSelecting($params); diff --git a/application/Espo/ORM/Query/LockTable.php b/application/Espo/ORM/Query/LockTable.php index c719e9cd68..c52c2e71df 100644 --- a/application/Espo/ORM/Query/LockTable.php +++ b/application/Espo/ORM/Query/LockTable.php @@ -38,9 +38,9 @@ class LockTable implements Query { use BaseTrait; - const MODE_SHARE = 'SHARE'; + public const MODE_SHARE = 'SHARE'; - const MODE_EXCLUSIVE = 'EXCLUSIVE'; + public const MODE_EXCLUSIVE = 'EXCLUSIVE'; protected function validateRawParams(array $params): void { diff --git a/application/Espo/ORM/Query/Select.php b/application/Espo/ORM/Query/Select.php index 92a1558a49..120691fdc8 100644 --- a/application/Espo/ORM/Query/Select.php +++ b/application/Espo/ORM/Query/Select.php @@ -32,13 +32,14 @@ namespace Espo\ORM\Query; use Espo\ORM\Query\Part\WhereClause; use Espo\ORM\Query\Part\SelectExpression; use Espo\ORM\Query\Part\OrderExpression; +use Espo\ORM\Query\Part\Expression; use RuntimeException; /** * Select parameters. * - * @todo Add validation and normalization (from ORM\DB\BaseQuery). + * @todo Add validation and normalization. */ class Select implements SelectingQuery { @@ -57,6 +58,48 @@ class Select implements SelectingQuery return $this->params['from'] ?? null; } + /** + * Get a from-alias + */ + public function getFromAlias(): ?string + { + return $this->params['fromAlias'] ?? null; + } + + /** + * Get a from-query. + */ + public function getFromQuery(): ?SelectingQuery + { + return $this->params['fromQuery'] ?? null; + } + + /** + * Get an OFFSET. + */ + public function getOffset(): ?int + { + return $this->params['offset'] ?? null; + } + + /** + * Get a LIMIT. + */ + public function getLimit(): ?int + { + return $this->params['limit'] ?? null; + } + + /** + * Get USE INDEX (list of indexes). + * + * @return string[] + */ + public function getUseIndex(): array + { + return $this->params['useIndex'] ?? []; + } + /** * Get SELECT items. * @@ -81,32 +124,6 @@ class Select implements SelectingQuery ); } - /** - * Get ORDER items. - * - * @return OrderExpression[] - */ - public function getOrder(): array - { - return array_map( - function ($item) { - if (is_array($item) && count($item)) { - $itemValue = is_int($item[0]) ? (string) $item[0] : $item[0]; - - return OrderExpression::fromString($itemValue) - ->withDirection($item[1] ?? OrderExpression::ASC); - } - - if (is_string($item)) { - return OrderExpression::fromString($item); - } - - throw new RuntimeException("Bad order item."); - }, - $this->params['orderBy'] ?? [] - ); - } - /** * Whether DISTINCT is applied. */ @@ -116,25 +133,48 @@ class Select implements SelectingQuery } /** - * Get GROUP BY items. + * Whether a FOR SHARE lock mode is set. */ - public function getGroupBy(): array + public function isForShare(): bool { - return $this->params['orderBy'] ?? []; + return $this->params['forShare'] ?? false; } /** - * Get WHERE clause. + * Whether a FOR UPDATE lock mode is set. */ - public function getWhere(): ?WhereClause + public function isForUpdate(): bool { - $whereClause = $this->params['whereClause'] ?? null; + return $this->params['forUpdate'] ?? false; + } - if ($whereClause === null || $whereClause === []) { + /** + * Get GROUP BY items. + * + * @return Expression[] + */ + public function getGroupBy(): array + { + return array_map( + function (string $item) { + return Expression::create($item); + }, + $this->params['groupBy'] ?? [] + ); + } + + /** + * Get HAVING clause. + */ + public function getHaving(): ?WhereClause + { + $havingClause = $this->params['havingClause'] ?? null; + + if ($havingClause === null || $havingClause === []) { return null; } - return WhereClause::fromRaw($whereClause); + return WhereClause::fromRaw($havingClause); } private function validateRawParams(array $params): void diff --git a/application/Espo/ORM/Query/SelectBuilder.php b/application/Espo/ORM/Query/SelectBuilder.php index 1cd697bb9f..e43f19068f 100644 --- a/application/Espo/ORM/Query/SelectBuilder.php +++ b/application/Espo/ORM/Query/SelectBuilder.php @@ -173,10 +173,10 @@ class SelectBuilder implements Builder * Passing a string|Expression will append an item. * * Usage options: + * * `groupBy(Expression|string $expression)` * * `groupBy([$expr1, $expr2, ...])` - * * `groupBy(string|Expression $expression)` * - * @param string|Expression|array $groupBy + * @param Expression|Expression[]|string|string[] $groupBy */ public function groupBy($groupBy): self { diff --git a/application/Espo/ORM/Query/SelectingTrait.php b/application/Espo/ORM/Query/SelectingTrait.php index 053dac7002..4aa75223c6 100644 --- a/application/Espo/ORM/Query/SelectingTrait.php +++ b/application/Espo/ORM/Query/SelectingTrait.php @@ -29,8 +29,53 @@ namespace Espo\ORM\Query; +use Espo\ORM\Query\Part\OrderExpression; +use Espo\ORM\Query\Part\WhereClause; + +use RuntimeException; + trait SelectingTrait { + /** + * Get ORDER items. + * + * @return OrderExpression[] + */ + public function getOrder(): array + { + return array_map( + function ($item) { + if (is_array($item) && count($item)) { + $itemValue = is_int($item[0]) ? (string) $item[0] : $item[0]; + + return OrderExpression::fromString($itemValue) + ->withDirection($item[1] ?? OrderExpression::ASC); + } + + if (is_string($item)) { + return OrderExpression::fromString($item); + } + + throw new RuntimeException("Bad order item."); + }, + $this->params['orderBy'] ?? [] + ); + } + + /** + * Get WHERE clause. + */ + public function getWhere(): ?WhereClause + { + $whereClause = $this->params['whereClause'] ?? null; + + if ($whereClause === null || $whereClause === []) { + return null; + } + + return WhereClause::fromRaw($whereClause); + } + private static function validateRawParamsSelecting(array $params): void { } diff --git a/application/Espo/ORM/Query/Update.php b/application/Espo/ORM/Query/Update.php index 84c4fc6027..29c81aeb2b 100644 --- a/application/Espo/ORM/Query/Update.php +++ b/application/Espo/ORM/Query/Update.php @@ -29,6 +29,8 @@ namespace Espo\ORM\Query; +use Espo\ORM\Query\Part\WhereClause; + use RuntimeException; /** @@ -39,6 +41,22 @@ class Update implements Query use SelectingTrait; use BaseTrait; + /** + * Get an entity type. + */ + public function getIn(): ?string + { + return $this->params['from'] ?? null; + } + + /** + * Get a LIMIT. + */ + public function getLimit(): ?int + { + return $this->params['limit'] ?? null; + } + private function validateRawParams(array $params): void { $this->validateRawParamsSelecting($params); diff --git a/application/Espo/ORM/Query/UpdateBuilder.php b/application/Espo/ORM/Query/UpdateBuilder.php index 9811b7349b..05ec950682 100644 --- a/application/Espo/ORM/Query/UpdateBuilder.php +++ b/application/Espo/ORM/Query/UpdateBuilder.php @@ -53,7 +53,6 @@ class UpdateBuilder implements Builder return $this; } - /** * For what entity type to build a query. */ diff --git a/application/Espo/ORM/Repository/RDBRelation.php b/application/Espo/ORM/Repository/RDBRelation.php index cbe8948b92..a986347802 100644 --- a/application/Espo/ORM/Repository/RDBRelation.php +++ b/application/Espo/ORM/Repository/RDBRelation.php @@ -305,13 +305,13 @@ class RDBRelation /** * Specify GROUP BY. * Passing an array will reset previously set items. - * Passing a string will append an item. + * Passing a string|Expression will append an item. * * Usage options: + * * `groupBy(Expression|string $expression)` * * `groupBy([$expr1, $expr2, ...])` - * * `groupBy(string|Expression $expression)` * - * @param string|Expression|array $groupBy + * @param Expression|Expression[]|string|string[] $groupBy */ public function groupBy($groupBy): Builder { diff --git a/application/Espo/ORM/Repository/RDBRelationSelectBuilder.php b/application/Espo/ORM/Repository/RDBRelationSelectBuilder.php index 1ca6108325..aaf09606a3 100644 --- a/application/Espo/ORM/Repository/RDBRelationSelectBuilder.php +++ b/application/Espo/ORM/Repository/RDBRelationSelectBuilder.php @@ -388,13 +388,13 @@ class RDBRelationSelectBuilder /** * Specify GROUP BY. * Passing an array will reset previously set items. - * Passing a string will append an item. + * Passing a string|Expression will append an item. * * Usage options: + * * `groupBy(Expression|string $expression)` * * `groupBy([$expr1, $expr2, ...])` - * * `groupBy(string|Expression $expression)` * - * @param string|Expression|array $groupBy + * @param Expression|Expression[]|string|string[] $groupBy */ public function groupBy($groupBy): self { diff --git a/application/Espo/ORM/Repository/RDBRepository.php b/application/Espo/ORM/Repository/RDBRepository.php index a98af10cd1..ad24b2e321 100644 --- a/application/Espo/ORM/Repository/RDBRepository.php +++ b/application/Espo/ORM/Repository/RDBRepository.php @@ -801,13 +801,13 @@ class RDBRepository extends Repository /** * Specify GROUP BY. * Passing an array will reset previously set items. - * Passing a string will append an item. + * Passing a string|Expression will append an item. * * Usage options: + * * `groupBy(Expression|string $expression)` * * `groupBy([$expr1, $expr2, ...])` - * * `groupBy(string|Expression $expression)` * - * @param string|Expression|array $groupBy + * @param Expression|Expression[]|string|string[] $groupBy */ public function groupBy($groupBy): RDBSelectBuilder { diff --git a/application/Espo/ORM/Repository/RDBSelectBuilder.php b/application/Espo/ORM/Repository/RDBSelectBuilder.php index 1e08c1378f..28a6339c2a 100644 --- a/application/Espo/ORM/Repository/RDBSelectBuilder.php +++ b/application/Espo/ORM/Repository/RDBSelectBuilder.php @@ -327,13 +327,13 @@ class RDBSelectBuilder /** * Specify GROUP BY. * Passing an array will reset previously set items. - * Passing a string will append an item. + * Passing a string|Expression will append an item. * * Usage options: + * * `groupBy(Expression|string $expression)` * * `groupBy([$expr1, $expr2, ...])` - * * `groupBy(string|Expression $expression)` * - * @param string|Expression|array $groupBy + * @param Expression|Expression[]|string|string[] $groupBy */ public function groupBy($groupBy): self { diff --git a/tests/unit/Espo/ORM/Query/SelectBuilderTest.php b/tests/unit/Espo/ORM/Query/SelectBuilderTest.php index c122d4bfc6..00f73e5344 100644 --- a/tests/unit/Espo/ORM/Query/SelectBuilderTest.php +++ b/tests/unit/Espo/ORM/Query/SelectBuilderTest.php @@ -248,8 +248,6 @@ class SelectBuilderTest extends \PHPUnit\Framework\TestCase $raw = $select->getRaw(); - $this->assertEquals(['test=' => null], $raw['havingClause']); - $this->assertEquals(['test'], $raw['groupBy']); } @@ -257,15 +255,35 @@ class SelectBuilderTest extends \PHPUnit\Framework\TestCase { $select = $this->builder ->from('Test') - ->having(Cond::equal(Expr::column('test'), null)) - ->groupBy([Expr::create('test')]) + ->groupBy([ + Expr::create('test1'), + Expr::create('test2'), + ]) ->build(); - $raw = $select->getRaw(); - $this->assertEquals(['test=' => null], $raw['havingClause']); + $this->assertEquals( + [ + Expr::create('test1'), + Expr::create('test2'), + ], + $select->getGroupBy() + ); + } - $this->assertEquals(['test'], $raw['groupBy']); + public function testHaving1() + { + $select = $this->builder + ->from('Test') + ->having(Cond::equal(Expr::column('test'), null)) + ->groupBy(Expr::create('test')) + ->build(); + + + $this->assertEquals( + Cond::equal(Expr::column('test'), null)->getRaw(), + $select->getHaving()->getRaw() + ); } public function testOrder1()