public function testBelongsToIndex() { Cache::flush(); Schema\Builder::getInstance()->migrate(App::collection('auths')->getModel(), array('attributes' => array(array('name' => 'lucky_number_id', 'type' => 'integer', 'unique' => true)), 'relationships' => array('belongs_to' => 'lucky_numbers'))); $auths_cache = SchemaCache::get('auths'); $this->assertTrue($auths_cache['attributes'][0]['name'] == 'lucky_number_id'); }
public static function getRelation($model, $relation_name) { $schema = Cache::get($model->getTable()); if (isset($schema['relationships'])) { // TODO: refactoring. // change the way to store relationships to prevent excessive loops foreach ($schema['relationships'] as $relation_type => $fields) { foreach ($fields as $field => $config) { if ($field == $relation_name || $config['collection'] == $relation_name) { return static::getRelationInstance($model, $relation_type, $field, $config); } } } } return null; }
public function __construct(array $attributes = array()) { if (isset($attributes['table_name'])) { static::$lastTableName = $attributes['table_name']; $this->setTable(static::$lastTableName); unset($attributes['table_name']); } elseif (static::$lastTableName) { $this->setTable(static::$lastTableName); } // Configure date fields to output / $table_name = $this->getTable(); $this->schema = Schema\Cache::get($table_name); if ($this->schema && isset($this->schema['attributes'])) { foreach ($this->schema['attributes'] as $attribute) { if (isset($attribute['type']) && $attribute['type'] == 'timestamp') { array_push($this->dates, $attribute['name']); } } } parent::__construct($attributes); static::loadObserver($table_name); }
public function testMigrateAddRelationship() { Schema\Builder::getInstance()->migrate(App::collection('schema_cache')->getModel(), array('relationships' => array('has_many' => array('contacts')))); Schema\Builder::getInstance()->migrate(App::collection('schema_cache')->getModel(), array('relationships' => array('has_many' => array('contacts')))); $this->assertTrue(SchemaCache::get('schema_caches') == array('attributes' => array(), 'relationships' => array('has_many' => array('contacts' => array('collection' => 'contacts', 'foreign_key' => 'schema_cach_id', 'primary_key' => '_id'))), 'lock_attributes' => false)); }
/** * migrate * * @param Hook\Model\Collection $model * @param array $collection_config * * @return bool */ public function migrate($model, $collection_config, $is_dynamic = false) { $that = $this; $result = false; $connection = $model->getConnectionResolver()->connection(); // Ignore NoSQL databases. if (!$connection->getPdo()) { return; } // Get modified Schema\Grammar for hook features. $connection->setSchemaGrammar($this->getSchemaGrammar($connection)); // Set custom blueprint resolver $builder = $connection->getSchemaBuilder(); $builder->blueprintResolver(function ($table, $callback) { return new \Hook\Database\Schema\Blueprint($table, $callback); }); $table = $model->getTable(); $table_schema = Cache::get($table); $table_prefix = Context::getPrefix(); $collection_config = $this->sanitizeConfigs($table, $collection_config, $is_dynamic); $is_creating = !$builder->hasTable($table); if (!empty($collection_config['attributes']) || !empty($collection_config['relationships'])) { $migrate = function ($t) use($that, &$table, &$table_prefix, &$builder, &$is_creating, &$table_schema, $collection_config, &$result) { $table_columns = array('created_at', 'updated_at', 'deleted_at'); if ($is_creating) { $that->createCollection($t); } else { $table_columns = array_merge($table_columns, $builder->getColumnListing($table)); } foreach ($collection_config['attributes'] as $attribute) { if (!isset($attribute['name'])) { throw new MethodFailureException('invalid_schema'); } $field_name = strtolower(array_remove($attribute, 'name')); $type = camel_case(array_remove($attribute, 'type') ?: 'string'); $default = array_remove($attribute, 'default'); $index = array_remove($attribute, 'index'); $unique = array_remove($attribute, 'unique') || $index == 'unique'; $required = array_remove($attribute, 'required'); // Skip if column already exists // TODO: deprecate strtolower if (in_array($field_name, array_map('strtolower', $table_columns))) { continue; } // include field_name to list of collection columns array_push($table_columns, $field_name); if (count($attribute) > 0) { // the remaining attributes on field definition are // the data-type related collection_config, such as 'length', // 'allowed', 'total', 'places', etc. $column = $t->newColumn($type, $field_name, $attribute); } else { $column = $t->{$type}($field_name); } // apply default value if ($default !== NULL) { $required = true; $column->default($default); } // spatial indexes are NOT NULL by default $nullable = !$required && $type !== 'point'; // columns are nullable unless specified as 'required' if ($nullable) { $column->nullable(); } if ($index == 'spatial') { // apply geospatial index, only MyISAM $t->spatialIndex($field_name); } else { if ($index && !$unique) { // apply index if specified $column->index(); } } if ($unique) { // apply unique index if specified $unique_fields = !is_array($unique) ? $field_name : array_unique(array_merge(array($field_name), $unique)); $t->unique($unique_fields); } } // onDelete / onUpdate actions $actions = array('restrict' => "RESTRICT", 'cascade' => "CASCADE", 'none' => "NO ACTION", 'null' => "SET NULL", 'default' => "SET DEFAULT"); if (!isset($collection_config['relationships'])) { $collection_config['relationships'] = array(); } foreach ($collection_config['relationships'] as $relation => $fields) { // only create field on belongs_to relationships if ($relation == "belongs_to") { foreach ($fields as $field => $config) { // create 'foreign_key' column on collection. if (!in_array($config['foreign_key'], array_map('strtolower', $table_columns))) { $column = $t->unsignedInteger($config['foreign_key']); $column->nullable(); } // create collection if it doesn't exists if (!$builder->hasTable($config['collection'])) { $builder->create($table_prefix . $config['collection'], function ($t) use($that) { $that->createCollection($t); }); } // // // // create foreign key on database // // // // TODO: list foreign keys already defined before // // trying to create it. // // // $t->foreign($config['foreign_key']) // ->references($config['primary_key']) // ->on($table_prefix . $config['collection']) // ->onDelete($actions[$config['on_delete']]) // ->onUpdate($actions[$config['on_update']]); } } } // return true when any modification is present if (count($t->getColumns()) > 0 || count($t->getCommands()) > 0) { $result = true; } }; if ($is_creating) { // CREATE TABLE statement $builder->create($table_prefix . $table, $migrate); } else { // ALTER TABLE statement. $builder->table($table_prefix . $table, $migrate); } } // merge previous schema with new one. $table_schema = $this->mergeSchema($table_schema, $collection_config, $is_dynamic); // Cache table schema for further reference Cache::forever($table, $table_schema); $app_collections = Cache::get('app_collections'); Cache::forever('app_collections', array_unique(array_merge($app_collections, array($table)))); return $result; }