/** * Provided a modelClassName, members and corresponding rules columns array is generated for schema generation. * Members with unique validators are tracked separately to be used with index array generation later. * @param string $modelClassName * @param array $members * @param array $rules * @param $messageLogger * @return array * @throws CException */ public static function resolve($modelClassName, array $members, array $rules, &$messageLogger) { $messageLogger->addInfoMessage(Zurmo::t('Core', 'Building Column definitions for {{model}}', array('{{model}}' => $modelClassName))); $membersWithRules = array(); $columns = array(); foreach ($rules as $rule) { if (in_array($rule[0], $members)) { $membersWithRules[$rule[0]][] = $rule; } } foreach ($membersWithRules as $member => $rules) { $column = RedBeanModelMemberRulesToColumnAdapter::resolve($modelClassName, $rules, $messageLogger); if ($column) { $columns[] = $column; } else { $errorMessage = Zurmo::t('Core', 'Failed to resolve {{model}}.{{member}} to column', array('{{model}}' => $modelClassName, '{{member}}' => $member)); $messageLogger->addErrorMessage($errorMessage); throw new CException($errorMessage); } } if (count($members) != count($columns)) { $errorMessage = Zurmo::t('Core', 'Not all members for {{model}} could be translated to columns.', array('{{model}}' => $modelClassName)); $messageLogger->addErrorMessage($errorMessage); $errorMessage .= Zurmo::t('Core', 'Members') . ': ('; $errorMessage .= join(', ', $members); $errorMessage .= '),' . Zurmo::t('Core', 'Columns') . ' ('; // Not Coding Standard $columnNames = RedBeanModelMemberToColumnUtil::resolveColumnNamesArrayFromColumnSchemaDefinition($columns); $columnNames = join(', ', $columnNames); $errorMessage .= $columnNames . ')'; throw new CException($errorMessage); } $messageLogger->addInfoMessage(Zurmo::t('Core', 'Column definitions Built')); return $columns; }
public static function resolve($modelClassName) { $canHaveBeenParentModelClassName = static::resolveParentThatCanHaveBeen($modelClassName); if (!$canHaveBeenParentModelClassName) { return null; } $column = RedBeanModelMemberToColumnUtil::resolveForeignKeyColumnMetadata(null, $canHaveBeenParentModelClassName); return $column; }
public static function resolve($mixinModelClassName) { $column = null; if (!empty($mixinModelClassName) && @class_exists($mixinModelClassName) && $mixinModelClassName::getCanHaveBean()) { $column = RedBeanModelMemberToColumnUtil::resolveForeignKeyColumnMetadata(null, $mixinModelClassName); return $column; } return $column; }
/** * Provided indexName and metadata is resolved to match the requirements of schema definition * @param array $indexMetadata passed by reference, array containing index definition * @return bool whether or not we were able to resolve index correctly */ public static function resolve(array &$indexMetadata) { if (empty($indexMetadata['members']) || !is_array($indexMetadata['members'])) { return false; } $unique = false; if (isset($indexMetadata['unique'])) { $unique = $indexMetadata['unique']; } $indexMembers = $indexMetadata['members']; // Begin Not Coding Standard $indexMembers = array_map(function ($indexMember) { return RedBeanModelMemberToColumnUtil::resolve($indexMember); }, $indexMembers); // End Not Coding Standard $indexMetadata = array('columns' => $indexMembers, 'unique' => $unique); return true; }
/** * Adds externalSystemId column to specific table if it does not exist * @param $tableName * @param $maxLength * @param $columnName */ public static function addExternalIdColumnIfMissing($tableName, $maxLength = 255, $columnName = null) { if (!isset($columnName)) { $columnName = static::EXTERNAL_SYSTEM_ID_COLUMN_NAME; } // check if external_system_id exists in fields $columnExists = ZurmoRedBean::$writer->doesColumnExist($tableName, $columnName); if (!$columnExists) { // if not, update model and add an external_system_id field $type = 'string'; $length = null; RedBeanModelMemberRulesToColumnAdapter::resolveStringTypeAndLengthByMaxLength($type, $length, $maxLength); $columns = array(); $columns[] = RedBeanModelMemberToColumnUtil::resolveColumnMetadataByHintType($columnName, $type, $length); $schema = CreateOrUpdateExistingTableFromSchemaDefinitionArrayUtil::getTableSchema($tableName, $columns); CreateOrUpdateExistingTableFromSchemaDefinitionArrayUtil::generateOrUpdateTableBySchemaDefinition($schema, new MessageLogger()); } }
/** * 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); }
/** * Provided modelClassName and rules for a member we resolve a column in table. * @param string $modelClassName * @param array $rules * @param $messageLogger * @return array|bool */ public static function resolve($modelClassName, array $rules, &$messageLogger) { if (empty($rules)) { return false; } $member = $rules[0][0]; assert('strpos($member, " ") === false'); $name = RedBeanModelMemberToColumnUtil::resolve($member); $type = null; $length = null; $notNull = null; $default = null; static::resolveColumnTypeAndLengthFromRules($modelClassName, $member, $rules, $type, $length, $notNull, $default, $messageLogger); if (!isset($type)) { return false; } return RedBeanModelMemberToColumnUtil::resolveColumnMetadataByHintType($name, $type, $length, null, $notNull, $default, null); }
protected static function resolvePolymorphicTypeColumnByLinkName($linkName) { $linkName .= '_type'; return RedBeanModelMemberToColumnUtil::resolveColumnMetadataByHintType($linkName); }
protected function createImportTempTable($columnCount, $tableName) { $importColumns = array(); for ($i = 0; $i < $columnCount; $i++) { $columnName = 'column_' . $i; $importColumns[] = RedBeanModelMemberToColumnUtil::resolveColumnMetadataByHintType($columnName, 'string', 50); } ImportDatabaseUtil::createTableByTableNameAndImportColumns($tableName, $importColumns); }
protected static function validateIndexDefinitionsFromSchema(array $indexes, array $columns) { $columnNames = RedBeanModelMemberToColumnUtil::resolveColumnNamesArrayFromColumnSchemaDefinition($columns); foreach ($indexes as $indexName => $index) { $indexNameLength = strlen($indexName); if (!is_string($indexName)) { return static::returnSchemaValidationResult(Zurmo::t('Core', 'Index Name: {{indexName}} is not a string', array('{{indexName}}' => $indexName))); } if ($indexNameLength > 64) { return static::returnSchemaValidationResult(Zurmo::t('Core', 'Index Name: {{indexName}} is {{length}} characters, {{over}} characters over limit(64).', array('{{indexName}}' => $indexName, '{{length}}' => $indexNameLength, '{{over}}' => $indexNameLength - 64))); } if (count($index) != 2) { return static::returnSchemaValidationResult(Zurmo::t('Core', 'Index: {{indexName}} does not have 2 clauses', array('{{indexName}}' => $indexName))); } if (!ArrayUtil::isValidArrayIndex('columns', $index)) { return static::returnSchemaValidationResult(Zurmo::t('Core', 'Index: {{indexName}} does not have indexed column names', array('{{indexName}}' => $indexName))); } if (!ArrayUtil::isValidArrayIndex('unique', $index)) { return static::returnSchemaValidationResult(Zurmo::t('Core', 'Index: {{indexName}} does not have index uniqueness clause defined', array('{{indexName}}' => $indexName))); } if (!is_array($index['columns'])) { return static::returnSchemaValidationResult(Zurmo::t('Core', 'Index: {{indexName}} column definition is not an array', array('{{indexName}}' => $indexName))); } foreach ($index['columns'] as $column) { list($column) = explode('(', $column); if (!in_array($column, $columnNames)) { return static::returnSchemaValidationResult(Zurmo::t('Core', 'Index: {{indexName}} column: {{columnName}} does not exist' . ' in current schema definition provided. Columns: {{columns}}', array('{{indexName}}' => $indexName, '{{columnName}}' => $column, '{{columns}}' => print_r($columnNames, true)))); } } } return static::returnSchemaValidationResult(null, true); }
protected static function getReservedColumnMetadata() { $columns = array(); $reservedColumnsTypes = array('status' => 'integer', 'serializedMessages' => 'string', 'analysisStatus' => 'integer', 'serializedAnalysisMessages' => 'string'); foreach ($reservedColumnsTypes as $columnName => $type) { $length = null; $unsigned = null; if ($type === 'string') { // populate the proper type given it would be 1024 char string depending on db type. RedBeanModelMemberRulesToColumnAdapter::resolveStringTypeAndLengthByMaxLength($type, $length, 1024); } else { // forcing integers to be unsigned $unsigned = DatabaseCompatibilityUtil::resolveUnsignedByHintType($type, false); } // last argument is false because we do not want these column names to be resolved to lower characters $columns[] = RedBeanModelMemberToColumnUtil::resolveColumnMetadataByHintType($columnName, $type, $length, $unsigned, null, null, null, false); } return $columns; }
/** * @depends testResolveForeignKeyColumnMetadataWithRelatedModelClassName */ public function testResolveColumnMetadataByHintTypeWithStringWithoutId() { $unresolvedName = 'memberNameGoesHere'; $columnDefinition = RedBeanModelMemberToColumnUtil::resolveColumnMetadataByHintType($unresolvedName); $this->assertNotEmpty($columnDefinition); $this->assertCount(6, $columnDefinition); $this->assertArrayHasKey('name', $columnDefinition); $this->assertEquals('membernamegoeshere', $columnDefinition['name']); $this->assertArrayHasKey('type', $columnDefinition); $this->assertEquals('VARCHAR(255)', $columnDefinition['type']); $this->assertArrayHasKey('unsigned', $columnDefinition); $this->assertNull($columnDefinition['unsigned']); $this->assertArrayHasKey('notNull', $columnDefinition); $this->assertEquals('NULL', $columnDefinition['notNull']); // Not Coding Standard $this->assertArrayHasKey('collation', $columnDefinition); $this->assertEquals('COLLATE utf8_unicode_ci', $columnDefinition['collation']); $this->assertArrayHasKey('default', $columnDefinition); $this->assertEquals('DEFAULT NULL', $columnDefinition['default']); // Not Coding Standard $this->assertArrayNotHasKey('length', $columnDefinition); }