From 9b9d3d9634fe65143b9239dacb1dda6d0f8625f9 Mon Sep 17 00:00:00 2001 From: yuri Date: Mon, 30 Nov 2015 11:15:21 +0200 Subject: [PATCH 1/3] ORM: ability to join children --- application/Espo/ORM/DB/Query/Base.php | 28 +++++++++++++++++++------- tests/Espo/ORM/DB/QueryTest.php | 21 ++++++++++++++++--- 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/application/Espo/ORM/DB/Query/Base.php b/application/Espo/ORM/DB/Query/Base.php index d5e9abb9bd..c909b4a070 100644 --- a/application/Espo/ORM/DB/Query/Base.php +++ b/application/Espo/ORM/DB/Query/Base.php @@ -724,6 +724,8 @@ abstract class Base $joinAlias = $relationName; } + $joinAlias = $this->sanitize($joinAlias); + $pre = ($left) ? 'LEFT ' : ''; if ($relOpt['type'] == IEntity::MANY_MANY) { @@ -738,7 +740,7 @@ abstract class Base $distantTable = $this->toDb($relOpt['entity']); - $alias = $this->sanitize($joinAlias); + $alias = $joinAlias; $midAlias = $alias . 'Middle'; @@ -759,14 +761,12 @@ abstract class Base . "{$alias}.deleted = " . $this->pdo->quote(0) . ""; return $join; - } - - if ($relOpt['type'] == IEntity::HAS_MANY) { + } else if ($relOpt['type'] == IEntity::HAS_MANY) { $foreignKey = $keySet['foreignKey']; $distantTable = $this->toDb($relOpt['entity']); - $alias = $this->sanitize($relationName); + $alias = $joinAlias; // TODO conditions @@ -776,9 +776,23 @@ abstract class Base . "{$alias}.deleted = " . $this->pdo->quote(0) . ""; return $join; - } + } else if ($relOpt['type'] == IEntity::HAS_CHILDREN) { + $foreignKey = $keySet['foreignKey']; + $foreignType = $keySet['foreignType']; + $distantTable = $this->toDb($relOpt['entity']); - if ($relOpt['type'] == IEntity::BELONGS_TO) { + $alias = $joinAlias; + + $join = + "{$pre}JOIN `{$distantTable}` AS `{$alias}` ON " . $this->toDb($entity->getEntityType()) . "." . $this->toDb('id') . " = {$alias}." . $this->toDb($foreignKey) + . " AND " + . "{$alias}." . $this->toDb($foreignType) . " = " . $this->pdo->quote($entity->getEntityType()) + . " AND " + . "{$alias}.deleted = " . $this->pdo->quote(0) . ""; + + return $join; + + } else if ($relOpt['type'] == IEntity::BELONGS_TO) { return $pre . $this->getBelongsToJoin($entity, $relationName); } diff --git a/tests/Espo/ORM/DB/QueryTest.php b/tests/Espo/ORM/DB/QueryTest.php index 419b659b9c..532ffdf2d9 100644 --- a/tests/Espo/ORM/DB/QueryTest.php +++ b/tests/Espo/ORM/DB/QueryTest.php @@ -99,7 +99,7 @@ class QueryTest extends PHPUnit_Framework_TestCase 'limit' => 20 )); - $expectedSql = + $expectedSql = "SELECT account.id AS `id`, account.name AS `name`, account.deleted AS `deleted` FROM `account` " . "WHERE account.deleted = '0' ORDER BY account.name ASC LIMIT 10, 20"; @@ -112,7 +112,7 @@ class QueryTest extends PHPUnit_Framework_TestCase )); - $expectedSql = + $expectedSql = "SELECT comment.id AS `id`, comment.post_id AS `postId`, post.name AS `postName`, comment.name AS `name`, comment.deleted AS `deleted` FROM `comment` " . "LEFT JOIN `post` AS `post` ON comment.post_id = post.id " . "WHERE comment.deleted = '0'"; @@ -125,7 +125,7 @@ class QueryTest extends PHPUnit_Framework_TestCase $sql = $this->query->createSelectQuery('Comment', array( 'select' => array('id', 'name') )); - $expectedSql = + $expectedSql = "SELECT comment.id AS `id`, comment.name AS `name` FROM `comment` " . "WHERE comment.deleted = '0'"; @@ -192,6 +192,21 @@ class QueryTest extends PHPUnit_Framework_TestCase $this->assertEquals($expectedSql, $sql); } + public function testSelectWithJoinChildren() + { + $sql = $this->query->createSelectQuery('Post', array( + 'select' => ['id', 'name'], + 'leftJoins' => [['notes', 'notesLeft']] + )); + + $expectedSql = + "SELECT post.id AS `id`, post.name AS `name` FROM `post` " . + "LEFT JOIN `note` AS `notesLeft` ON post.id = notesLeft.parent_id AND notesLeft.parent_type = 'Post' AND notesLeft.deleted = '0' " . + "WHERE post.deleted = '0'"; + + $this->assertEquals($expectedSql, $sql); + } + public function testOrderBy() { $sql = $this->query->createSelectQuery('Comment', array( From 6174245b22476d61138bc86c64df256aaf3b65a7 Mon Sep 17 00:00:00 2001 From: yuri Date: Mon, 30 Nov 2015 12:22:48 +0200 Subject: [PATCH 2/3] cleanup --- tests/testData/DB/Entities.php | 48 +++++++++++++++++----------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/tests/testData/DB/Entities.php b/tests/testData/DB/Entities.php index 165294c58a..790db2257a 100644 --- a/tests/testData/DB/Entities.php +++ b/tests/testData/DB/Entities.php @@ -14,11 +14,11 @@ class Account extends TEntity { public $fields = array( 'id' => array( - 'type' => Entity::ID, + 'type' => Entity::ID, ), 'name' => array( 'type' => Entity::VARCHAR, - 'len' => 255, + 'len' => 255, ), 'deleted' => array( 'type' => Entity::BOOL, @@ -34,20 +34,20 @@ class Account extends TEntity 'entityId', 'teamId', ), - 'conditions' => array('entityType' => 'Account') + 'conditions' => array('entityType' => 'Account') ), ); } class Team extends TEntity -{ +{ public $fields = array( 'id' => array( - 'type' => Entity::ID, + 'type' => Entity::ID, ), 'name' => array( 'type' => Entity::VARCHAR, - 'len' => 255, + 'len' => 255, ), 'deleted' => array( 'type' => Entity::BOOL, @@ -58,10 +58,10 @@ class Team extends TEntity } class Contact extends TEntity -{ +{ public $fields = array( 'id' => array( - 'type' => Entity::ID, + 'type' => Entity::ID, ), 'name' => array( 'type' => Entity::VARCHAR, @@ -73,10 +73,10 @@ class Contact extends TEntity 'orderBy' => "contact.first_name {direction}, contact.last_name {direction}", ), 'firstName' => array( - 'type' => Entity::VARCHAR, + 'type' => Entity::VARCHAR, ), 'lastName' => array( - 'type' => Entity::VARCHAR, + 'type' => Entity::VARCHAR, ), 'deleted' => array( 'type' => Entity::BOOL, @@ -87,14 +87,14 @@ class Contact extends TEntity } class Post extends TEntity -{ +{ public $fields = array( 'id' => array( - 'type' => Entity::ID, + 'type' => Entity::ID, ), 'name' => array( 'type' => Entity::VARCHAR, - 'len' => 255, + 'len' => 255, ), 'privateField' => array( 'notStorable' => true, @@ -111,7 +111,7 @@ class Post extends TEntity 'type' => Entity::BOOL, 'default' => 0, ), - ); + ); public $relations = array( 'tags' => array( 'type' => Entity::MANY_MANY, @@ -144,10 +144,10 @@ class Post extends TEntity } class Comment extends TEntity -{ +{ public $fields = array( 'id' => array( - 'type' => Entity::ID, + 'type' => Entity::ID, ), 'postId' => array( 'type' => Entity::FOREIGN_ID, @@ -159,14 +159,14 @@ class Comment extends TEntity ), 'name' => array( 'type' => Entity::VARCHAR, - 'len' => 255, + 'len' => 255, ), 'deleted' => array( 'type' => Entity::BOOL, 'default' => 0, ), ); - + public $relations = array( 'post' => array( 'type' => Entity::BELONGS_TO, @@ -178,14 +178,14 @@ class Comment extends TEntity } class Tag extends TEntity -{ +{ public $fields = array( 'id' => array( - 'type' => Entity::ID, + 'type' => Entity::ID, ), 'name' => array( 'type' => Entity::VARCHAR, - 'len' => 50, + 'len' => 50, ), 'deleted' => array( 'type' => Entity::BOOL, @@ -196,14 +196,14 @@ class Tag extends TEntity class Note extends TEntity -{ +{ public $fields = array( 'id' => array( - 'type' => Entity::ID, + 'type' => Entity::ID, ), 'name' => array( 'type' => Entity::VARCHAR, - 'len' => 50, + 'len' => 50, ), 'parentId' => array( 'type' => Entity::FOREIGN_ID, From 2e04fd5a3b5dc3a0bfd34ffbc4ac99d90c7fc821 Mon Sep 17 00:00:00 2001 From: yuri Date: Mon, 30 Nov 2015 14:14:29 +0200 Subject: [PATCH 3/3] style --- frontend/client/src/views/fields/array.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/frontend/client/src/views/fields/array.js b/frontend/client/src/views/fields/array.js index da8a5cdef8..443594eb44 100644 --- a/frontend/client/src/views/fields/array.js +++ b/frontend/client/src/views/fields/array.js @@ -26,19 +26,19 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -Espo.define('Views.Fields.Array', ['Views.Fields.Base', 'lib!Selectize'], function (Dep) { +Espo.define('views/fields/array', ['views/fields/base', 'lib!Selectize'], function (Dep) { return Dep.extend({ type: 'array', - listTemplate: 'fields.array.detail', + listTemplate: 'fields/array/detail', - detailTemplate: 'fields.array.detail', + detailTemplate: 'fields/array/detail', - editTemplate: 'fields.array.edit', + editTemplate: 'fields/array/edit', - searchTemplate: 'fields.array.search', + searchTemplate: 'fields/array/search', data: function () { var itemHtmlList = [];