orm select manager changes

This commit is contained in:
yuri
2019-03-07 17:40:28 +02:00
parent 50fe25eab3
commit d197391668
3 changed files with 83 additions and 11 deletions

View File

@@ -823,6 +823,12 @@ class Base
$type = $w['type'];
}
if ($forbidComplexExpressions) {
if ($type && in_array($type, ['subQueryIn', 'subQueryNotIn', 'not'])) {
throw new Forbidden("SelectManager::checkWhere: Sub-queries are forbidden.");
}
}
$entityType = $this->getEntityType();
if ($attribute && $forbidComplexExpressions) {
@@ -835,7 +841,7 @@ class Base
if (strpos($attribute, '.')) {
list($link, $attribute) = explode('.', $attribute);
if (!$this->getSeed()->hasRelation($link)) {
throw new Forbidden("SelectManager::checkWhere: Unknow relation '{$link}' in where.");
throw new Forbidden("SelectManager::checkWhere: Unknown relation '{$link}' in where.");
}
$entityType = $this->getSeed($this->getEntityType())->getRelationParam($link, 'entity');
if (!$entityType) {
@@ -2312,7 +2318,7 @@ class Base
return $selectParams1;
}
protected function applyLeftJoinsFromWhere($where, array &$result)
public function applyLeftJoinsFromWhere($where, array &$result)
{
if (!is_array($where)) return;
@@ -2321,7 +2327,7 @@ class Base
}
}
protected function applyLeftJoinsFromWhereItem($item, array &$result)
public function applyLeftJoinsFromWhereItem($item, array &$result)
{
$type = $item['type'] ?? null;
@@ -2341,8 +2347,17 @@ class Base
$attribute = $item['attribute'] ?? null;
if (!$attribute) return;
$this->applyLeftJoinsFromAttribute($attribute, $result);
}
protected function applyLeftJoinsFromAttribute(string $attribute, array &$result)
{
if (strpos($attribute, ':') !== false) {
list($function, $attribute) = explode(':', $attribute);
$argumentList = \Espo\ORM\DB\Query\Base::getAllAttributesFromComplexExpression($attribute);
foreach ($argumentList as $argument) {
$this->applyLeftJoinsFromAttribute($argument, $result);
}
return;
}
if (strpos($attribute, '.') !== false) {

View File

@@ -508,6 +508,39 @@ abstract class Base
return $part;
}
public static function getAllAttributesFromComplexExpression(string $expression, &$list = null) : array
{
if (!$list) $list = [];
$arguments = $expression;
if (strpos($expression, ':')) {
$dilimeterPosition = strpos($expression, ':');
$function = substr($expression, 0, $dilimeterPosition);
$arguments = substr($expression, $dilimeterPosition + 1);
if (substr($arguments, 0, 1) === '(' && substr($arguments, -1) === ')') {
$arguments = substr($arguments, 1, -1);
}
} else {
if (
!self::isArgumentString($expression) &&
!self::isArgumentNumeric($expression) &&
!self::isArgumentBoolOrNull($expression)
) {
$list[] = $expression;
}
return [];
}
$argumentList = self::parseArgumentListFromFunctionContent($arguments);
foreach ($argumentList as $argument) {
self::getAllAttributesFromComplexExpression($argument, $list);
}
return $list;
}
static protected function parseArgumentListFromFunctionContent($functionContent)
{
$functionContent = trim($functionContent);
@@ -571,22 +604,36 @@ abstract class Base
return $argumentList;
}
protected static function isArgumentString(string $argument)
{
return
substr($argument, 0, 1) === '\'' && substr($argument, -1) === '\''
||
substr($argument, 0, 1) === '"' && substr($argument, -1) === '"';
}
protected static function isArgumentNumeric(string $argument)
{
return is_numeric($argument);
}
protected static function isArgumentBoolOrNull(string $argument)
{
return in_array(strtoupper($argument), ['NULL', 'TRUE', 'FALSE']);
}
protected function getFunctionArgumentPart($entity, $attribute, $distinct = false, &$params = null)
{
$argument = $attribute;
if (
substr($argument, 0, 1) === '\'' && substr($argument, -1) === '\''
||
substr($argument, 0, 1) === '"' && substr($argument, -1) === '"'
) {
if (self::isArgumentString($argument)) {
$string = substr($argument, 1, -1);
$string = $this->quote($string);
return $string;
} else if (is_numeric($argument)) {
} else if (self::isArgumentNumeric($argument)) {
$string = $this->quote($argument);
return $string;
} else if (in_array(strtoupper($argument), ['NULL', 'TRUE', 'FALSE'])) {
} else if (self::isArgumentBoolOrNull($argument)) {
return strtoupper($argument);
}

View File

@@ -739,4 +739,14 @@ class QueryTest extends \PHPUnit\Framework\TestCase
$this->assertEquals($expectedSql, $sql);
}
public function testGetAllAttributesFromComplexExpression()
{
$expression = "CONCAT:(MONTH:comment.created_at,' ',CONCAT:(comment.name,'+'))";
$list = $this->query::getAllAttributesFromComplexExpression($expression);
$this->assertTrue(in_array('comment.created_at', $list));
$this->assertTrue(in_array('comment.name', $list));
}
}