/** * Alter Table method * * @param string $type Type of operation to be done * @param array $tables List of tables and fields * @return boolean Return true in case of success, otherwise false * @access protected */ protected function _alterTable($type, $tables) { foreach ($tables as $table => $fields) { $indexes = array(); if (isset($fields['indexes'])) { $indexes = $fields['indexes']; unset($fields['indexes']); } foreach ($fields as $field => $col) { $model = new Model(array('table' => $table, 'ds' => $this->connection)); $tableFields = $this->db->describe($model); if ($type === 'drop') { $field = $col; } if ($type !== 'add' && !isset($tableFields[$field])) { throw new MigrationException($this, sprintf(__d('migrations', 'Field "%s" does not exists in "%s".', true), $field, $table)); } switch ($type) { case 'add': if (isset($tableFields[$field])) { throw new MigrationException($this, sprintf(__d('migrations', 'Field "%s" already exists in "%s".', true), $field, $table)); } $sql = $this->db->alterSchema(array($table => array('add' => array($field => $col)))); break; case 'drop': $sql = $this->db->alterSchema(array($table => array('drop' => array($field => array())))); break; case 'change': $sql = $this->db->alterSchema(array($table => array('change' => array($field => array_merge($tableFields[$field], $col))))); break; case 'rename': $sql = $this->db->alterSchema(array($table => array('change' => array($field => array_merge($tableFields[$field], array('name' => $col)))))); break; } if ($type == 'rename') { $data = array('table' => $table, 'old_name' => $field, 'new_name' => $col); } else { $data = array('table' => $table, 'field' => $field); } $this->_invokeCallbacks('beforeAction', $type . '_field', $data); if (@$this->db->execute($sql) === false) { throw new MigrationException($this, sprintf(__d('migrations', 'SQL Error: %s', true), $this->db->error)); } $this->_invokeCallbacks('afterAction', $type . '_field', $data); } foreach ($indexes as $key => $index) { if (is_numeric($key)) { $key = $index; $index = array(); } $sql = $this->db->alterSchema(array($table => array($type => array('indexes' => array($key => $index))))); $this->_invokeCallbacks('beforeAction', $type . '_index', array('table' => $table, 'index' => $key)); if (@$this->db->execute($sql) === false) { throw new MigrationException($this, sprintf(__d('migrations', 'SQL Error: %s', true), $this->db->error)); } $this->_invokeCallbacks('afterAction', $type . '_index', array('table' => $table, 'index' => $key)); } } return true; }
/** * Since Datasource has the method `describe()`, it won't be caught `__call()`. * This ensures it is called on the original datasource properly. * * @param mixed $model * @return mixed */ public function describe($model) { if (method_exists($this->source, 'describe')) { return $this->source->describe($model); } return $this->describe($model); }
/** * Alter Table method * * @param string $type Type of operation to be done * @param array $tables List of tables and fields * @return boolean Return true in case of success, otherwise false * @access protected */ public function _alterTable($type, $tables) { foreach ($tables as $table => $fields) { $indexes = array(); if (isset($fields['indexes'])) { $indexes = $fields['indexes']; unset($fields['indexes']); } foreach ($fields as $field => $col) { switch ($type) { case 'add': $sql = $this->db->alterSchema(array($table => array('add' => array($field => $col)))); break; case 'drop': $field = $col; $sql = $this->db->alterSchema(array($table => array('drop' => array($field => array())))); break; case 'change': $model = new Model(array('table' => $table, 'ds' => $this->connection)); $tableFields = $this->db->describe($model); $sql = $this->db->alterSchema(array($table => array('change' => array($field => array_merge($tableFields[$field], $col))))); break; case 'rename': $model = new Model(array('table' => $table, 'ds' => $this->connection)); $tableFields = $this->db->describe($model); $sql = $this->db->alterSchema(array($table => array('change' => array($field => array_merge($tableFields[$field], array('name' => $col)))))); break; } if ($type == 'rename') { $data = array('table' => $table, 'old_name' => $field, 'new_name' => $col); } else { $data = array('table' => $table, 'field' => $field); } $this->__invokeCallbacks('beforeAction', $type . '_field', $data); $this->db->execute($sql); $this->__invokeCallbacks('afterAction', $type . '_field', $data); } foreach ($indexes as $key => $index) { if (is_numeric($key)) { $key = $index; $index = array(); } $sql = $this->db->alterSchema(array($table => array($type => array('indexes' => array($key => $index))))); $this->__invokeCallbacks('beforeAction', $type . '_index', array('table' => $table, 'index' => $key)); $this->db->execute($sql); $this->__invokeCallbacks('afterAction', $type . '_index', array('table' => $table, 'index' => $key)); } } return true; }
/** * Returns a Model description (metadata) or null if none found. * * @param Model|string $model Name of database table to inspect or model instance * @return array Array of Metadata for the $model */ public function describe($model) { return parent::describe($model); }
/** * Alter Table method * * @param string $type Type of operation to be done * @param array $tables List of tables and fields * @return boolean Return true in case of success, otherwise false */ protected function _alterTable($type, $tables) { foreach ($tables as $table => $fields) { $indexes = array(); if (isset($fields['indexes'])) { $indexes = $fields['indexes']; unset($fields['indexes']); } if ($type == 'drop') { $this->_alterIndexes($indexes, $type, $table); } foreach ($fields as $field => $col) { $model = new Model(array('table' => $table, 'ds' => $this->connection)); try { $tableFields = $this->db->describe($model); } catch (Exception $e) { throw new MigrationException($this, sprintf(__d('migrations', 'Table "%s" does not exists.'), $table)); } if (!$tableFields) { throw new MigrationException($this, sprintf(__d('migrations', 'Table "%s" does not exists.'), $table)); } if ($type === 'drop') { $field = $col; } if ($type !== 'add' && !isset($tableFields[$field])) { throw new MigrationException($this, sprintf(__d('migrations', 'Field "%s" does not exists in "%s".'), $field, $table)); } switch ($type) { case 'add': if (isset($tableFields[$field])) { throw new MigrationException($this, sprintf(__d('migrations', 'Field "%s" already exists in "%s".'), $field, $table)); } $sql = $this->db->alterSchema(array($table => array('add' => array($field => $col)))); break; case 'drop': $sql = $this->db->alterSchema(array($table => array('drop' => array($field => array())))); break; case 'change': $def = array_merge($tableFields[$field], $col); if (!empty($def['length']) && !empty($col['type']) && (substr($col['type'], 0, 4) == 'date' || substr($col['type'], 0, 4) == 'time')) { $def['length'] = null; } $sql = $this->db->alterSchema(array($table => array('change' => array($field => $def)))); break; case 'rename': $sql = $this->db->alterSchema(array($table => array('change' => array($field => array_merge($tableFields[$field], array('name' => $col)))))); break; } if ($type == 'rename') { $data = array('table' => $table, 'old_name' => $field, 'new_name' => $col); } else { $data = array('table' => $table, 'field' => $field); } $this->_invokeCallbacks('beforeAction', $type . '_field', $data); if (@$this->db->execute($sql) === false) { throw new MigrationException($this, sprintf(__d('migrations', 'SQL Error: %s'), $this->db->error)); } $this->_invokeCallbacks('afterAction', $type . '_field', $data); } if ($type != 'drop') { $this->_alterIndexes($indexes, $type, $table); } } return true; }
/** * Returns a Model description (metadata) or null if none found. * * @param object $model Reference to calling model * @return mixed Model metadata */ public function describe(&$model) { $cache = parent::describe($model); if ($cache != null) { return $cache; } $fields = (array) $this->read($model); return $fields; }