/**
  * Generates junction table for a MANY_MANY relationship
  * @param string $modelClassName
  * @param array $relationMetadata
  * @param $messageLogger
  */
 public static function resolve($modelClassName, array $relationMetadata, &$messageLogger)
 {
     if (empty($modelClassName) || !@class_exists($modelClassName) || empty($relationMetadata) || count($relationMetadata) < 2 || $relationMetadata[0] != RedBeanModel::MANY_MANY || !@class_exists($relationMetadata[1])) {
         return;
     }
     $relatedModelClassName = $relationMetadata[1];
     $relationLinkName = null;
     if (isset($relationMetadata[4])) {
         $relationLinkName = $relationMetadata[4];
     }
     $tableName = RedBeanManyToManyRelatedModels::getTableNameByModelClassNames($modelClassName, $relatedModelClassName, $relationLinkName);
     if (ProcessedTableCache::isProcessed($tableName, static::CACHE_KEY)) {
         return;
     }
     $columns = array();
     $columns[] = RedBeanModelMemberToColumnUtil::resolveForeignKeyColumnMetadata(null, $modelClassName);
     $columns[] = RedBeanModelMemberToColumnUtil::resolveForeignKeyColumnMetadata(null, $relatedModelClassName);
     $indexes = static::resolveIndexesByColumnNames($columns);
     $schemaDefinition = array($tableName => array('columns' => $columns, 'indexes' => $indexes));
     CreateOrUpdateExistingTableFromSchemaDefinitionArrayUtil::generateOrUpdateTableBySchemaDefinition($schemaDefinition, $messageLogger);
     ProcessedTableCache::setAsProcessed($tableName, static::CACHE_KEY);
 }
 /**
  * Provide a schema definition array queries to create/update database schema are executed.
  * @param array $schemaDefinition
  * @param $messageLogger
  * @param $validate
  * @throws CException
  * @throws Exception|RedBean_Exception_SQL
  */
 public static function generateOrUpdateTableBySchemaDefinition(array $schemaDefinition, &$messageLogger, $validate = true)
 {
     $tableName = strtolower(key($schemaDefinition));
     if ($validate) {
         $schemaValidation = static::validateSchemaDefinition($schemaDefinition);
         if (!$schemaValidation['isValid']) {
             $errorMessage = Zurmo::t('Core', 'Invalid Schema definition received for {{tableName}}.', array('{{tableName}}' => $tableName));
             $errorMessage .= ' ' . $schemaValidation['message'];
             $messageLogger->addErrorMessage($errorMessage);
             throw new CException($errorMessage);
         }
     }
     $columnsAndIndexes = reset($schemaDefinition);
     if (ProcessedTableCache::isProcessed($tableName, static::CACHE_KEY) && Yii::app()->params['isFreshInstall']) {
         // we don't skip if running under updateSchema as we might have multiple requests to update same table.
         return;
     }
     $messageLogger->addInfoMessage(Zurmo::t('Core', 'Creating/Updating schema for {{tableName}}', array('{{tableName}}' => $tableName)));
     $existingFields = array();
     // only check for table existence if we are not on fresh install
     if (!isset(Yii::app()->params['isFreshInstall']) || !Yii::app()->params['isFreshInstall']) {
         try {
             $existingFields = ZurmoRedBean::$writer->getColumnsWithDetails($tableName);
         } catch (RedBean_Exception_SQL $e) {
             //42S02 - Table does not exist.
             if (!in_array($e->getSQLState(), array('42S02'))) {
                 throw $e;
             }
         }
     }
     if (empty($existingFields)) {
         $query = static::resolveCreateTableQuery($tableName, $columnsAndIndexes);
     } else {
         $existingIndexes = ZurmoRedBean::$writer->getIndexes($tableName);
         $query = static::resolveAlterTableQuery($tableName, $columnsAndIndexes, $existingFields, $existingIndexes);
     }
     if ($query) {
         ZurmoRedBean::exec($query);
     }
     ProcessedTableCache::setAsProcessed($tableName, static::CACHE_KEY);
 }