From 1e6cc7e8a22bda09f9acf0c8101401d1b74a6e01 Mon Sep 17 00:00:00 2001 From: Yuri Kuznetsov Date: Fri, 14 Aug 2020 14:04:03 +0300 Subject: [PATCH] custom order --- .../ORM/QueryComposer/BaseQueryComposer.php | 100 +++++++++++------- .../unit/Espo/ORM/MysqlQueryComposerTest.php | 20 ++++ tests/unit/testData/DB/Entities.php | 6 +- 3 files changed, 85 insertions(+), 41 deletions(-) diff --git a/application/Espo/ORM/QueryComposer/BaseQueryComposer.php b/application/Espo/ORM/QueryComposer/BaseQueryComposer.php index 590d2fa536..d056d27e5c 100644 --- a/application/Espo/ORM/QueryComposer/BaseQueryComposer.php +++ b/application/Espo/ORM/QueryComposer/BaseQueryComposer.php @@ -1043,51 +1043,63 @@ abstract class BaseQueryComposer implements QueryComposer $defs = $fieldDefs['order']; if (is_string($defs)) { - $part = $defs; $defs = []; - $part = str_replace('{direction}', $order, $part); - } else { - if (!empty($defs['sql'])) { - $part = $defs['sql']; - $part = str_replace('{direction}', $order, $part); - } else - if (!empty($defs['order'])) { - $list = []; - - if (!is_array($defs['order'])) { - throw new LogicException("Bad custom order defenition."); - } - - $modifiedOrder = []; - - foreach ($defs['order'] as $item) { - if (!is_array($item) && !isset($item[0])) { - throw new LogicException("Bad custom order defenition."); - } - - $newItem = [ - $item[0], - ]; - - if (isset($item[1]) && $item[1] === '{direction}') { - $newItem[] = $order; - } - - $modifiedOrder[] = $newItem; - } - - $part = $this->getOrderExpressionPart($entity, $modifiedOrder, null, false, $params, true); - } else { - $part = $this->toDb($entity->getEntityType()) . '.' . $this->toDb($this->sanitize($attribute)); - - $part .= ' ' . $order; - } } if ($params) { $this->applyAttributeCustomParams($defs, $params); } + if (is_string($fieldDefs['order'])) { + $defs = []; + $part = $fieldDefs['order']; + + $part = str_replace('{direction}', $order, $part); + + return $part; + } + + if (!empty($defs['sql'])) { + $part = $defs['sql']; + $part = str_replace('{direction}', $order, $part); + + return $part; + } + + if (!empty($defs['order'])) { + $list = []; + + if (!is_array($defs['order'])) { + throw new LogicException("Bad custom order defenition."); + } + + $modifiedOrder = []; + + foreach ($defs['order'] as $item) { + if (!is_array($item) && !isset($item[0])) { + throw new LogicException("Bad custom order defenition."); + } + + $newItem = [ + $item[0], + ]; + + if (isset($item[1]) && $item[1] === '{direction}') { + $newItem[] = $order; + } + + $modifiedOrder[] = $newItem; + } + + $part = $this->getOrderExpressionPart($entity, $modifiedOrder, null, false, $params, true); + + return $part; + } + + $part = $this->toDb($entity->getEntityType()) . '.' . $this->toDb($this->sanitize($attribute)); + + $part .= ' ' . $order; + return $part; } @@ -1565,10 +1577,14 @@ abstract class BaseQueryComposer implements QueryComposer if (is_array($item)) { $orderByInternal = $item[0]; $orderInternal = null; + if (!empty($item[1])) { $orderInternal = $item[1]; } - $arr[] = $this->getOrderExpressionPart($entity, $orderByInternal, $orderInternal, $useColumnAlias, $params); + + $arr[] = $this->getOrderExpressionPart( + $entity, $orderByInternal, $orderInternal, $useColumnAlias, $params, $noCustom + ); } } @@ -1622,11 +1638,15 @@ abstract class BaseQueryComposer implements QueryComposer } if ($useColumnAlias) { - $fieldPath = '`'. $this->sanitizeSelectAlias($orderBy) . '`'; + $fieldPath = '`' . $this->sanitizeSelectAlias($orderBy) . '`'; } else { $fieldPath = $this->getAttributePathForOrderBy($entity, $orderBy, $params); } + if (!$fieldPath) { + throw new LogicException("Could not handle 'order'."); + } + return "{$fieldPath} " . $order; } diff --git a/tests/unit/Espo/ORM/MysqlQueryComposerTest.php b/tests/unit/Espo/ORM/MysqlQueryComposerTest.php index 070d3d892a..d734616018 100644 --- a/tests/unit/Espo/ORM/MysqlQueryComposerTest.php +++ b/tests/unit/Espo/ORM/MysqlQueryComposerTest.php @@ -1481,4 +1481,24 @@ class MysqlQueryComposerTest extends \PHPUnit\Framework\TestCase $this->assertEquals($expectedSql, $sql); } + + public function testCustomOrder1() + { + $queryBuilder = new QueryBuilder(); + + $select = $queryBuilder->select() + ->from('TestWhere') + ->order('testVarchar', 'DESC') + ->build(); + + $sql = $this->query->compose($select); + + $expectedSql = + "SELECT test_where.id AS `id`, test_where.test AS `test` ". + "FROM `test_where` ". + "JOIN `test` AS `t` ON t.id = test_where.id ". + "ORDER BY test_where.test DESC, t.id DESC"; + + $this->assertEquals($expectedSql, $sql); + } } diff --git a/tests/unit/testData/DB/Entities.php b/tests/unit/testData/DB/Entities.php index 431b5e2094..043e4be480 100644 --- a/tests/unit/testData/DB/Entities.php +++ b/tests/unit/testData/DB/Entities.php @@ -481,7 +481,11 @@ class TestWhere extends TEntity 'order' => [ 'order' => [ ['test', '{direction}'], - ] + ['t.id', '{direction}'], + ], + 'joins' => [ + ['Test', 't', ['t.id:' => 'id']], + ], ], ], 'testInt' => [