/** * 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); }
/** * 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); }