orm: select item
This commit is contained in:
@@ -68,6 +68,9 @@ class SelectBuilder
|
||||
|
||||
private $sourceQuery = null;
|
||||
|
||||
/**
|
||||
* @var SearchParams
|
||||
*/
|
||||
private $searchParams = null;
|
||||
|
||||
private $applyAccessControlFilter = false;
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\ORM\Query\Part;
|
||||
|
||||
class SelectExpression implements SelectItem
|
||||
{
|
||||
private $expression;
|
||||
|
||||
private $alias = null;
|
||||
|
||||
public function __construct(Expression $expression, ?string $alias = null)
|
||||
{
|
||||
$this->expression = $expression;
|
||||
$this->alias = $alias;
|
||||
}
|
||||
|
||||
public function getExpression(): Expression
|
||||
{
|
||||
return $this->expression;
|
||||
}
|
||||
|
||||
public function getAlias(): ?string
|
||||
{
|
||||
return $this->alias;
|
||||
}
|
||||
|
||||
public static function create(Expression $expression, ?string $alias = null): self
|
||||
{
|
||||
return new self($expression, $alias);
|
||||
}
|
||||
|
||||
public static function fromString(string $expression): self
|
||||
{
|
||||
return self::create(
|
||||
Expression::create($expression)
|
||||
);
|
||||
}
|
||||
|
||||
public function withAlias(?string $alias): self
|
||||
{
|
||||
$obj = clone $this;
|
||||
$obj->alias = $alias;
|
||||
|
||||
return $obj;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\ORM\Query\Part;
|
||||
|
||||
interface SelectItem
|
||||
{
|
||||
public function getExpression(): Expression;
|
||||
|
||||
public function getAlias(): ?string;
|
||||
}
|
||||
@@ -30,6 +30,8 @@
|
||||
namespace Espo\ORM\Query;
|
||||
|
||||
use Espo\ORM\Query\Part\WhereClause;
|
||||
use Espo\ORM\Query\Part\SelectExpression as SelectExpr;
|
||||
use Espo\ORM\Query\Part\SelectItem;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
@@ -43,9 +45,9 @@ class Select implements SelectingQuery
|
||||
use SelectingTrait;
|
||||
use BaseTrait;
|
||||
|
||||
const ORDER_ASC = 'ASC';
|
||||
public const ORDER_ASC = 'ASC';
|
||||
|
||||
const ORDER_DESC = 'DESC';
|
||||
public const ORDER_DESC = 'DESC';
|
||||
|
||||
/**
|
||||
* Get an entity type.
|
||||
@@ -57,10 +59,26 @@ class Select implements SelectingQuery
|
||||
|
||||
/**
|
||||
* Get select items.
|
||||
*
|
||||
* @return SelectItem[]
|
||||
*/
|
||||
public function getSelect(): array
|
||||
{
|
||||
return $this->params['select'] ?? [];
|
||||
return array_map(
|
||||
function ($item) {
|
||||
if (is_array($item) && count($item)) {
|
||||
return SelectExpr::fromString($item[0])
|
||||
->withAlias($item[1] ?? null);
|
||||
}
|
||||
|
||||
if (is_string($item)) {
|
||||
return SelectExpr::fromString($item);
|
||||
}
|
||||
|
||||
throw new RuntimeException("Bad select item.");
|
||||
},
|
||||
$this->params['select'] ?? []
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
namespace Espo\ORM\Query;
|
||||
|
||||
use Espo\ORM\Query\Part\Expression;
|
||||
use Espo\ORM\Query\Part\SelectItem;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use RuntimeException;
|
||||
@@ -126,21 +127,23 @@ class SelectBuilder implements Builder
|
||||
/**
|
||||
* Specify SELECT. Columns and expressions to be selected. If not called, then
|
||||
* all entity attributes will be selected. Passing an array will reset
|
||||
* previously set items. Passing a string will append an item.
|
||||
* previously set items. Passing a string|Expression|SelectItem will append the item.
|
||||
*
|
||||
* Usage options:
|
||||
* * `select([$expr1, $expr2, ...])`
|
||||
* * `select([[$expr1, $alias1], [$expr2, $alias2], ...])`
|
||||
* * `select([$selectItem1, $selectItem2, ...])`
|
||||
* * `select(string|Expression $expression)`
|
||||
* * `select(string|Expression $expression, string $alias)`
|
||||
* * `select(SelectItem $selectItem)`
|
||||
*
|
||||
* @param array|string|Expression $select An array of attributes or one attribute.
|
||||
* @param array|string|Expression|SelectItem $select An array of expressions or one expression.
|
||||
* @param string|null $alias An alias. Actual if the first parameter is a string.
|
||||
*/
|
||||
public function select($select, ?string $alias = null): self
|
||||
{
|
||||
if (is_array($select)) {
|
||||
$this->params['select'] = $this->normilizeExpressionItemArray($select);
|
||||
$this->params['select'] = $this->normilizeSelectItemArray($select);
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -148,12 +151,15 @@ class SelectBuilder implements Builder
|
||||
if ($select instanceof Expression) {
|
||||
$select = $select->getValue();
|
||||
}
|
||||
else if ($select instanceof SelectItem) {
|
||||
$alias = $alias ?? $select->getAlias();
|
||||
$select = $select->getExpression()->getValue();
|
||||
}
|
||||
|
||||
if (is_string($select)) {
|
||||
$this->params['select'] = $this->params['select'] ?? [];
|
||||
|
||||
$this->params['select'][] =
|
||||
$alias ?
|
||||
$this->params['select'][] = $alias ?
|
||||
[$select, $alias] :
|
||||
$select;
|
||||
|
||||
@@ -166,7 +172,7 @@ class SelectBuilder implements Builder
|
||||
/**
|
||||
* 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([$expr1, $expr2, ...])`
|
||||
@@ -264,4 +270,43 @@ class SelectBuilder implements Builder
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function normilizeSelectItemArray(array $itemList): array
|
||||
{
|
||||
$resultList = [];
|
||||
|
||||
foreach ($itemList as $item) {
|
||||
if ($item instanceof Expression) {
|
||||
$resultList[] = $item->getValue();
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($item instanceof SelectItem) {
|
||||
$resultList[] = $item->getAlias() ?
|
||||
[$item->getExpression()->getValue(), $item->getAlias()] :
|
||||
[$item->getExpression()->getValue()];
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!is_array($item) || !count($item) || !$item[0] instanceof Expression) {
|
||||
$resultList[] = $item;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$newItem = [$item[0]->getValue()];
|
||||
|
||||
if (count($item) > 1) {
|
||||
$newItem[] = $item[1];
|
||||
}
|
||||
|
||||
$resultList[] = $newItem;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
return $resultList;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ use Espo\ORM\{
|
||||
Query\Query,
|
||||
Query\Builder,
|
||||
Query\Part\Expression,
|
||||
Query\Part\SelectItem,
|
||||
};
|
||||
|
||||
use ReflectionClass;
|
||||
@@ -51,15 +52,17 @@ class QueryBuilder
|
||||
/**
|
||||
* Specify SELECT. Columns and expressions to be selected. If not called, then
|
||||
* all entity attributes will be selected. Passing an array will reset
|
||||
* previously set items. Passing a string will append an item.
|
||||
* previously set items. Passing a string|Expression|SelectItem will append the item.
|
||||
*
|
||||
* Usage options:
|
||||
* * `select([$expr1, $expr2, ...])`
|
||||
* * `select([[$expr1, $alias1], [$expr2, $alias2], ...])`
|
||||
* * `select([$selectItem1, $selectItem2, ...])`
|
||||
* * `select(string|Expression $expression)`
|
||||
* * `select(string|Expression $expression, string $alias)`
|
||||
* * `select(SelectItem $selectItem)`
|
||||
*
|
||||
* @param array|string|Expression $select An array of attributes or one attribute.
|
||||
* @param array|string|Expression|SelectItem $select An array of expressions or one expression.
|
||||
* @param string|null $alias An alias. Actual if the first parameter is a string.
|
||||
*/
|
||||
public function select($select = null, ?string $alias = null): SelectBuilder
|
||||
|
||||
@@ -35,6 +35,7 @@ use Espo\ORM\{
|
||||
EntityManager,
|
||||
Query\Select,
|
||||
Query\Part\WhereItem,
|
||||
Query\Part\SelectItem,
|
||||
Mapper\RDBMapper,
|
||||
Repository\RDBRelationSelectBuilder as Builder,
|
||||
};
|
||||
@@ -285,15 +286,17 @@ class RDBRelation
|
||||
/**
|
||||
* Specify SELECT. Columns and expressions to be selected. If not called, then
|
||||
* all entity attributes will be selected. Passing an array will reset
|
||||
* previously set items. Passing a string will append an item.
|
||||
* previously set items. Passing a string|Expression|SelectItem will append the item.
|
||||
*
|
||||
* Usage options:
|
||||
* * `select([$expr1, $expr2, ...])`
|
||||
* * `select([[$expr1, $alias1], [$expr2, $alias2], ...])`
|
||||
* * `select([$selectItem1, $selectItem2, ...])`
|
||||
* * `select(string|Expression $expression)`
|
||||
* * `select(string|Expression $expression, string $alias)`
|
||||
* * `select(SelectItem $selectItem)`
|
||||
*
|
||||
* @param array|string|Expression $select An array of attributes or one attribute.
|
||||
* @param array|string|Expression|SelectItem $select An array of expressions or one expression.
|
||||
* @param string|null $alias An alias. Actual if the first parameter is a string.
|
||||
*/
|
||||
public function select($select = [], ?string $alias = null): Builder
|
||||
|
||||
@@ -37,6 +37,7 @@ use Espo\ORM\{
|
||||
Query\Select,
|
||||
Query\SelectBuilder,
|
||||
Query\Part\WhereItem,
|
||||
Query\Part\SelectItem,
|
||||
Mapper\Mapper,
|
||||
};
|
||||
|
||||
@@ -363,15 +364,17 @@ class RDBRelationSelectBuilder
|
||||
/**
|
||||
* Specify SELECT. Columns and expressions to be selected. If not called, then
|
||||
* all entity attributes will be selected. Passing an array will reset
|
||||
* previously set items. Passing a string will append an item.
|
||||
* previously set items. Passing a string|Expression|SelectItem will append the item.
|
||||
*
|
||||
* Usage options:
|
||||
* * `select([$expr1, $expr2, ...])`
|
||||
* * `select([[$expr1, $alias1], [$expr2, $alias2], ...])`
|
||||
* * `select([$selectItem1, $selectItem2, ...])`
|
||||
* * `select(string|Expression $expression)`
|
||||
* * `select(string|Expression $expression, string $alias)`
|
||||
* * `select(SelectItem $selectItem)`
|
||||
*
|
||||
* @param array|string|Expression $select An array of attributes or one attribute.
|
||||
* @param array|string|Expression|SelectItem $select An array of expressions or one expression.
|
||||
* @param string|null $alias An alias. Actual if the first parameter is a string.
|
||||
*/
|
||||
public function select($select, ?string $alias = null): self
|
||||
|
||||
@@ -38,6 +38,7 @@ use Espo\ORM\{
|
||||
Mapper\RDBMapper,
|
||||
Query\Select,
|
||||
Query\Part\WhereItem,
|
||||
Query\Part\SelectItem,
|
||||
};
|
||||
|
||||
use StdClass;
|
||||
@@ -331,7 +332,7 @@ class RDBRepository extends Repository
|
||||
|
||||
$selectItemList = $select->getSelect();
|
||||
|
||||
if (empty($selectItemList)) {
|
||||
if ($selectItemList === []) {
|
||||
$selectItemList[] = '*';
|
||||
}
|
||||
|
||||
@@ -781,15 +782,17 @@ class RDBRepository extends Repository
|
||||
/**
|
||||
* Specify SELECT. Columns and expressions to be selected. If not called, then
|
||||
* all entity attributes will be selected. Passing an array will reset
|
||||
* previously set items. Passing a string will append an item.
|
||||
* previously set items. Passing a string|Expression|SelectItem will append the item.
|
||||
*
|
||||
* Usage options:
|
||||
* * `select([$expr1, $expr2, ...])`
|
||||
* * `select([[$expr1, $alias1], [$expr2, $alias2], ...])`
|
||||
* * `select([$selectItem1, $selectItem2, ...])`
|
||||
* * `select(string|Expression $expression)`
|
||||
* * `select(string|Expression $expression, string $alias)`
|
||||
* * `select(SelectItem $selectItem)`
|
||||
*
|
||||
* @param array|string|Expression $select An array of attributes or one attribute.
|
||||
* @param array|string|Expression|SelectItem $select An array of expressions or one expression.
|
||||
* @param string|null $alias An alias. Actual if the first parameter is a string.
|
||||
*/
|
||||
public function select($select = [], ?string $alias = null): RDBSelectBuilder
|
||||
|
||||
@@ -37,6 +37,7 @@ use Espo\ORM\{
|
||||
Query\Select,
|
||||
Query\SelectBuilder,
|
||||
Query\Part\WhereItem,
|
||||
Query\Part\SelectItem,
|
||||
Mapper\Mapper,
|
||||
};
|
||||
|
||||
@@ -303,15 +304,17 @@ class RDBSelectBuilder
|
||||
/**
|
||||
* Specify SELECT. Columns and expressions to be selected. If not called, then
|
||||
* all entity attributes will be selected. Passing an array will reset
|
||||
* previously set items. Passing a string will append an item.
|
||||
* previously set items. Passing a string|Expression|SelectItem will append the item.
|
||||
*
|
||||
* Usage options:
|
||||
* * `select([$expr1, $expr2, ...])`
|
||||
* * `select([[$expr1, $alias1], [$expr2, $alias2], ...])`
|
||||
* * `select([$selectItem1, $selectItem2, ...])`
|
||||
* * `select(string|Expression $expression)`
|
||||
* * `select(string|Expression $expression, string $alias)`
|
||||
* * `select(SelectItem $selectItem)`
|
||||
*
|
||||
* @param array|string|Expression $select An array of attributes or one attribute.
|
||||
* @param array|string|Expression|SelectItem $select An array of expressions or one expression.
|
||||
* @param string|null $alias An alias. Actual if the first parameter is a string.
|
||||
*/
|
||||
public function select($select, ?string $alias = null): self
|
||||
|
||||
@@ -33,6 +33,7 @@ use Espo\ORM\{
|
||||
Query\SelectBuilder,
|
||||
Query\Part\Condition as Cond,
|
||||
Query\Part\Expression as Expr,
|
||||
Query\Part\SelectExpression,
|
||||
};
|
||||
|
||||
class SelectBuilderTest extends \PHPUnit\Framework\TestCase
|
||||
@@ -65,7 +66,14 @@ class SelectBuilderTest extends \PHPUnit\Framework\TestCase
|
||||
->select('test')
|
||||
->build();
|
||||
|
||||
$this->assertEquals(['id', 'name', 'test'], $select->getSelect());
|
||||
$this->assertEquals(
|
||||
[
|
||||
SelectExpression::fromString('id'),
|
||||
SelectExpression::fromString('name'),
|
||||
SelectExpression::fromString('test'),
|
||||
],
|
||||
$select->getSelect()
|
||||
);
|
||||
}
|
||||
|
||||
public function testSelect2()
|
||||
@@ -76,7 +84,13 @@ class SelectBuilderTest extends \PHPUnit\Framework\TestCase
|
||||
->select(['id', 'name'])
|
||||
->build();
|
||||
|
||||
$this->assertEquals(['id', 'name'], $select->getSelect());
|
||||
$this->assertEquals(
|
||||
[
|
||||
SelectExpression::fromString('id'),
|
||||
SelectExpression::fromString('name'),
|
||||
],
|
||||
$select->getSelect()
|
||||
);
|
||||
}
|
||||
|
||||
public function testSelect3()
|
||||
@@ -86,7 +100,12 @@ class SelectBuilderTest extends \PHPUnit\Framework\TestCase
|
||||
->select('test', 'hello')
|
||||
->build();
|
||||
|
||||
$this->assertEquals([['test', 'hello']], $select->getSelect());
|
||||
$this->assertEquals(
|
||||
[
|
||||
SelectExpression::fromString('test')->withAlias('hello'),
|
||||
],
|
||||
$select->getSelect()
|
||||
);
|
||||
}
|
||||
|
||||
public function testSelect4()
|
||||
@@ -96,7 +115,12 @@ class SelectBuilderTest extends \PHPUnit\Framework\TestCase
|
||||
->select(Expr::create('test'), 'hello')
|
||||
->build();
|
||||
|
||||
$this->assertEquals([['test', 'hello']], $select->getSelect());
|
||||
$this->assertEquals(
|
||||
[
|
||||
SelectExpression::fromString('test')->withAlias('hello'),
|
||||
],
|
||||
$select->getSelect()
|
||||
);
|
||||
}
|
||||
|
||||
public function testSelect5()
|
||||
@@ -107,7 +131,13 @@ class SelectBuilderTest extends \PHPUnit\Framework\TestCase
|
||||
->select([Expr::create('id'), Expr::create('name')])
|
||||
->build();
|
||||
|
||||
$this->assertEquals(['id', 'name'], $select->getSelect());
|
||||
$this->assertEquals(
|
||||
[
|
||||
SelectExpression::fromString('id'),
|
||||
SelectExpression::fromString('name'),
|
||||
],
|
||||
$select->getSelect()
|
||||
);
|
||||
}
|
||||
|
||||
public function testSelect6()
|
||||
@@ -121,7 +151,34 @@ class SelectBuilderTest extends \PHPUnit\Framework\TestCase
|
||||
])
|
||||
->build();
|
||||
|
||||
$this->assertEquals([['id', 'id'], ['name', 'name']], $select->getSelect());
|
||||
$this->assertEquals(
|
||||
[
|
||||
SelectExpression::fromString('id')->withAlias('id'),
|
||||
SelectExpression::fromString('name')->withAlias('name'),
|
||||
],
|
||||
$select->getSelect()
|
||||
);
|
||||
}
|
||||
|
||||
public function testSelect7()
|
||||
{
|
||||
$select = $this->builder
|
||||
->from('Test')
|
||||
->select([
|
||||
'id',
|
||||
SelectExpression::create(Expr::create('name'))
|
||||
])
|
||||
->select(SelectExpression::fromString('test')->withAlias('testAlias'))
|
||||
->build();
|
||||
|
||||
$this->assertEquals(
|
||||
[
|
||||
SelectExpression::fromString('id'),
|
||||
SelectExpression::fromString('name'),
|
||||
SelectExpression::fromString('test')->withAlias('testAlias'),
|
||||
],
|
||||
$select->getSelect()
|
||||
);
|
||||
}
|
||||
|
||||
public function testCloneNotSame()
|
||||
|
||||
@@ -36,6 +36,7 @@ use Espo\ORM\{
|
||||
Query\Update,
|
||||
Query\Delete,
|
||||
Query\Union,
|
||||
Query\Part\SelectExpression,
|
||||
};
|
||||
|
||||
use RuntimeException;
|
||||
@@ -96,7 +97,13 @@ class QueryBuilderTest extends \PHPUnit\Framework\TestCase
|
||||
->from('Test')
|
||||
->build();
|
||||
|
||||
$this->assertEquals(['col1', 'col2'], $select->getSelect());
|
||||
$this->assertEquals(
|
||||
[
|
||||
SelectExpression::fromString('col1'),
|
||||
SelectExpression::fromString('col2'),
|
||||
],
|
||||
$select->getSelect()
|
||||
);
|
||||
}
|
||||
|
||||
public function testSelectFrom2()
|
||||
@@ -106,7 +113,12 @@ class QueryBuilderTest extends \PHPUnit\Framework\TestCase
|
||||
->from('Test')
|
||||
->build();
|
||||
|
||||
$this->assertEquals([['col1', 'alias1']], $select->getSelect());
|
||||
$this->assertEquals(
|
||||
[
|
||||
SelectExpression::fromString('col1')->withAlias('alias1')
|
||||
],
|
||||
$select->getSelect()
|
||||
);
|
||||
}
|
||||
public function testInsert1()
|
||||
{
|
||||
@@ -237,5 +249,5 @@ class QueryBuilderTest extends \PHPUnit\Framework\TestCase
|
||||
$this->queryBuilder
|
||||
->union()
|
||||
->build();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user