From d99f31dc0f7f3158a6922159b97c087a99253268 Mon Sep 17 00:00:00 2001 From: Taras Machyshyn Date: Tue, 24 Dec 2013 12:40:05 +0200 Subject: [PATCH] added entityTeam relation support --- application/Espo/Controllers/Admin.php | 2 +- .../Core/Utils/Database/Converters/Links.php | 19 +++++ .../Utils/Database/Converters/Relations.php | 38 +++++---- .../Core/Utils/Database/Converters/Schema.php | 81 +++++++++++++++---- .../Doctrine/DBAL/Platforms/MySqlPlatform.php | 5 +- 5 files changed, 111 insertions(+), 34 deletions(-) diff --git a/application/Espo/Controllers/Admin.php b/application/Espo/Controllers/Admin.php index 33424d6382..eb9a3486fe 100644 --- a/application/Espo/Controllers/Admin.php +++ b/application/Espo/Controllers/Admin.php @@ -8,7 +8,7 @@ use \Espo\Core\Exceptions\Error, class Admin extends \Espo\Core\Controllers\Base { - public function __construct(Container $container, ServiceFactory $serviceFactory) + public function __construct(\Espo\Core\Container $container, \Espo\Core\ServiceFactory $serviceFactory) { parent::__construct($container, $serviceFactory); diff --git a/application/Espo/Core/Utils/Database/Converters/Links.php b/application/Espo/Core/Utils/Database/Converters/Links.php index ae516d70de..c0a0ba6dd5 100644 --- a/application/Espo/Core/Utils/Database/Converters/Links.php +++ b/application/Espo/Core/Utils/Database/Converters/Links.php @@ -56,6 +56,19 @@ class Links $params['targetEntity'] = $foreignParams['entityName']; $foreignParams['targetEntity'] = $params['entityName']; + //hardcode for Teams + if (isset($link['params'])) { + switch ($link['params']['type']) { + case 'hasMany': + if ($params['targetEntity'] == 'Team') { + $method = 'teamRelation'; + } + break; + } + } + //END: hardcode + + if (method_exists($this, $method)) { return $this->$method($params, $foreignParams); } @@ -100,6 +113,12 @@ class Links } + protected function teamRelation($params, $foreignParams) + { + return $this->getRelations()->teamRelation($params, $foreignParams); + } + + /*protected function hasChildrenBelongsToParent() diff --git a/application/Espo/Core/Utils/Database/Converters/Relations.php b/application/Espo/Core/Utils/Database/Converters/Relations.php index 49f6bb035f..2319fb716e 100644 --- a/application/Espo/Core/Utils/Database/Converters/Relations.php +++ b/application/Espo/Core/Utils/Database/Converters/Relations.php @@ -167,22 +167,7 @@ class Relations 'foreignType' => $foreignParams['link']['name'].'Type', //???: 'foreignKey' => $params['link']['name'].'Id', ), ), - ), - - /*$foreignParams['entityName'] => array ( - 'fields' => array( - $foreignParams['link']['name'].'Id' => array( - 'type' => Entity::FOREIGN_ID, - ), - $foreignParams['link']['name'].'Type' => array( - 'type' => Entity::FOREIGN_TYPE, - ), - $foreignParams['link']['name'].'Name' => array( - 'type' => Entity::VARCHAR, - 'notStorable' => true, - ), - ), - ), */ + ), ); @@ -217,6 +202,27 @@ class Relations return $relation; } + public function teamRelation($params, $foreignParams) + { + return array( + $params['entityName'] => array( + 'relations' => array( + $params['link']['name'] => array( + 'type' => Entity::MANY_MANY, + 'entity' => $params['targetEntity'], + 'relationName' => 'EntityTeam', + 'midKeys' => array( + 'entityId', + 'teamId', + ), + 'conditions' => array('entityType' => $params['entityName']), + ), + ), + ), + ); + + } + public function hasOne($params, $foreignParams) { diff --git a/application/Espo/Core/Utils/Database/Converters/Schema.php b/application/Espo/Core/Utils/Database/Converters/Schema.php index aae693cfb1..e9fbbd89c8 100644 --- a/application/Espo/Core/Utils/Database/Converters/Schema.php +++ b/application/Espo/Core/Utils/Database/Converters/Schema.php @@ -28,6 +28,12 @@ class Schema 'len' => '24', ); + //todo: same array in Converters\Orm + protected $defaultLength = array( + 'varchar' => 255, + 'int' => 11, + ); + protected $notStorableTypes = array( 'foreign' ); @@ -39,7 +45,7 @@ class Schema $this->typeList = array_keys(\Doctrine\DBAL\Types\Type::getTypesMap()); } - protected function getDbalSchema() + protected function getSchema() { return $this->dbalSchema; } @@ -49,7 +55,7 @@ class Schema //convertToSchema public function process(array $databaseMeta, $entityDefs) { - $schema = $this->getDbalSchema(); + $schema = $this->getSchema(); $tables = array(); foreach ($databaseMeta as $entityName => $entityParams) { @@ -90,7 +96,10 @@ class Schema continue; } - $tables[$entityName]->addColumn(Util::toUnderScore($fieldName), $fieldType, $this->getDbFieldParams($fieldParams)); + $columnName = Util::toUnderScore($fieldName); + if (!$tables[$entityName]->hasColumn($columnName)) { + $tables[$entityName]->addColumn($columnName, $fieldType, $this->getDbFieldParams($fieldParams)); + } } $tables[$entityName]->setPrimaryKey($primaryColumns); @@ -107,21 +116,20 @@ class Schema switch ($relationParams['type']) { case 'manyMany': $tableName = $relationParams['relationName']; - $tables[$tableName] = $schema->createTable( Util::toUnderScore($tableName) ); - $tables[$tableName]->addColumn('id', $this->idParams['dbType'], array('length'=>$this->idParams['len'])); - $relationEntities = array($entityName, $relationParams['entity']); - $relationKeys = array($relationParams['key'], $relationParams['foreignKey']); - foreach($relationParams['midKeys'] as $index => $midKey) { - $usMidKey = Util::toUnderScore($midKey); - $tables[$tableName]->addColumn($usMidKey, $this->idParams['dbType'], array('length'=>$this->idParams['len'])); + //check for duplication tables + if (!isset($tables[$tableName])) { //no needs to create the table if it already exists + + if ($tableName == 'EntityTeam') { //hardcode for Teams + if (isset($relationParams['conditions'])) { + $relationParams['midKeys'] = array_merge($relationParams['midKeys'], array_keys($relationParams['conditions'])); + } + $tables[$tableName] = $this->prepareManyMany($entityName, $relationParams, $tables, false); + } else { + $tables[$tableName] = $this->prepareManyMany($entityName, $relationParams, $tables); + } - $relationKey = Util::toUnderScore($relationKeys[$index]); - $tables[$tableName]->addForeignKeyConstraint($tables[$relationEntities[$index]], array($usMidKey), array($relationKey), array("onUpdate" => "CASCADE")); } - - $tables[$tableName]->addColumn('deleted', 'bool', array('default' => 0)); - $tables[$tableName]->setPrimaryKey(array("id")); break; case 'belongsTo': @@ -140,6 +148,49 @@ class Schema } + /** + * Prepare a relation table for the manyMany relation + * + * @param array $relationParams + * @param array $tables + * @param bool $isForeignKey + * + * @return \Doctrine\DBAL\Schema\Table + */ + protected function prepareManyMany($entityName, $relationParams, $tables, $isForeignKey = true) + { + $tableName = $relationParams['relationName']; + + $table = $this->getSchema()->createTable( Util::toUnderScore($tableName) ); + $table->addColumn('id', $this->idParams['dbType'], array('length'=>$this->idParams['len'])); + + if ($isForeignKey) { + $relationEntities = array($entityName, $relationParams['entity']); + $relationKeys = array($relationParams['key'], $relationParams['foreignKey']); + } + + foreach($relationParams['midKeys'] as $index => $midKey) { + $usMidKey = Util::toUnderScore($midKey); + + if (preg_match('/_id$/i', $usMidKey)) { + $table->addColumn($usMidKey, $this->idParams['dbType'], array('length'=>$this->idParams['len'])); + } else { + $table->addColumn($usMidKey, 'varchar', array('length'=>$this->defaultLength['varchar'])); + } + + if ($isForeignKey) { + $relationKey = Util::toUnderScore($relationKeys[$index]); + $table->addForeignKeyConstraint($tables[$relationEntities[$index]], array($usMidKey), array($relationKey), array("onUpdate" => "CASCADE")); + } + } + + $table->addColumn('deleted', 'bool', array('default' => 0)); + $table->setPrimaryKey(array("id")); + + return $table; + } + + protected function getDbFieldParams($fieldParams) { $dbFieldParams = array(); diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php index a9e774c597..dcb61c2423 100644 --- a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php +++ b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php @@ -546,7 +546,8 @@ class MySqlPlatform extends AbstractPlatform . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnArray); } - foreach ($diff->renamedColumns as $oldColumnName => $column) { + /* espo: It works not correctly. It can rename some existing fields + foreach ($diff->renamedColumns as $oldColumnName => $column) { if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) { continue; } @@ -555,7 +556,7 @@ class MySqlPlatform extends AbstractPlatform $columnArray['comment'] = $this->getColumnComment($column); $queryParts[] = 'CHANGE ' . $oldColumnName . ' ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnArray); - } + } */ $sql = array(); $tableSql = array();