public static function FieldChangeHelper::changeSchema in Helper 7
1 call to FieldChangeHelper::changeSchema()
- FieldChangeHelper::changeType in lib/
FieldChangeHelper.php - Change a field's type, even if it has data.
File
- lib/
FieldChangeHelper.php, line 109
Class
Code
public static function changeSchema(array &$field, array $column_renames = array()) {
// Update the field schema
$old_schema = array_intersect_key($field, array(
'columns' => '',
'indexes' => '',
'foreign keys' => '',
));
module_load_install($field['module']);
$new_schema = (array) module_invoke($field['module'], 'field_schema', $field);
$new_schema += array(
'columns' => array(),
'indexes' => array(),
'foreign keys' => array(),
);
$field['data']['columns'] = $new_schema['columns'];
$field['data']['indexes'] = $new_schema['indexes'];
$field['data']['foreign keys'] = $new_schema['foreign keys'];
$data_table = _field_sql_storage_tablename($field);
$revision_table = _field_sql_storage_revision_tablename($field);
// Validate that all the columns described in the existing schema actually exist.
foreach (array_keys($old_schema['columns']) as $old_column) {
$old_column_name = _field_sql_storage_columnname($field['field_name'], $old_column);
if (!db_field_exists($data_table, $old_column_name)) {
throw new Exception();
}
if (!db_field_exists($revision_table, $old_column_name)) {
throw new Exception();
}
// Attempt to re-use any columns that have the same name.
// This can be skipped by setting $column_renames['column-name'] = FALSE;
if (!empty($new_schema['columns'][$old_column]) && !isset($column_renames[$old_column])) {
$column_renames[$old_column] = $old_column;
}
}
// Validate that any columns to be renamed actually exist.
foreach ($column_renames as $old_column => $new_column) {
if (!isset($old_schema['columns'][$old_column])) {
throw new Exception("Cannot rename field {$field['field_name']} column {$old_column} because it does not exist in the old schema.");
}
if (!isset($new_schema['columns'][$new_column])) {
throw new Exception("Cannot rename field {$field['field_name']} column {$old_column} to {$new_column} because it does not exist in the new schema.");
}
}
// Remove all existing indexes.
foreach ($old_schema['indexes'] as $index => $index_fields) {
$index_name = _field_sql_storage_indexname($field['field_name'], $index);
if (db_index_exists($data_table, $index_name)) {
watchdog('helper', "Dropped index {$data_table}.{$index_name}");
db_drop_index($data_table, $index_name);
}
if (db_index_exists($revision_table, $index_name)) {
watchdog('helper', "Dropped index {$revision_table}.{$index_name}");
db_drop_index($revision_table, $index_name);
}
}
// Rename any columns.
foreach ($column_renames as $old_column => $new_column) {
$old_column_name = _field_sql_storage_columnname($field['field_name'], $old_column);
if ($new_column === FALSE) {
db_drop_field($data_table, $old_column_name);
watchdog('helper', "Dropped column {$data_table}.{$old_column_name}");
db_drop_field($revision_table, $old_column_name);
watchdog('helper', "Dropped column {$revision_table}.{$old_column_name}");
unset($old_schema['columns'][$old_column]);
}
else {
$new_column_name = _field_sql_storage_columnname($field['field_name'], $new_column);
db_change_field($data_table, $old_column_name, $new_column_name, $new_schema['columns'][$new_column]);
watchdog('helper', "Changed column {$data_table}.{$old_column_name}<br/><pre>" . print_r($new_schema['columns'][$new_column], TRUE) . '</pre>');
db_change_field($revision_table, $old_column_name, $new_column_name, $new_schema['columns'][$new_column]);
watchdog('helper', "Changed column {$revision_table}.{$old_column_name}<br/><pre>" . print_r($new_schema['columns'][$new_column], TRUE) . '</pre>');
// Remove these fields so they aren't removed or added in the code below.
unset($new_schema['columns'][$new_column]);
unset($old_schema['columns'][$old_column]);
}
}
// Remove any old columns.
$old_columns = array_diff_key($old_schema['columns'], $new_schema['columns']);
foreach (array_keys($old_columns) as $old_column) {
$old_column_name = _field_sql_storage_columnname($field['field_name'], $old_column);
db_drop_field($data_table, $old_column_name);
watchdog('helper', "Dropped column {$data_table}.{$old_column_name}");
db_drop_field($revision_table, $old_column_name);
watchdog('helper', "Dropped column {$revision_table}.{$old_column_name}");
}
// Add any new columns.
$new_columns = array_diff_key($new_schema['columns'], $old_schema['columns']);
foreach (array_keys($new_columns) as $new_column) {
$new_column_name = _field_sql_storage_columnname($field['field_name'], $new_column);
db_add_field($data_table, $new_column_name, $new_schema['columns'][$new_column]);
watchdog('helper', "Added column {$data_table}.{$new_column_name}");
db_add_field($revision_table, $new_column_name, $new_schema['columns'][$new_column]);
watchdog('helper', "Added column {$revision_table}.{$new_column_name}");
}
// Re-add indexes.
foreach ($new_schema['indexes'] as $index => $index_fields) {
foreach ($index_fields as &$index_field) {
if (is_array($index_field)) {
$index_field[0] = _field_sql_storage_columnname($field['field_name'], $index_field[0]);
}
else {
$index_field = _field_sql_storage_columnname($field['field_name'], $index_field);
}
}
$index_name = _field_sql_storage_indexname($field['field_name'], $index);
db_add_index($data_table, $index_name, $index_fields);
watchdog('helper', "Added index {$data_table}.{$index_name}<br/><pre>" . print_r($index_fields, TRUE) . '</pre>');
db_add_index($revision_table, $index_name, $index_fields);
watchdog('helper', "Added index {$revision_table}.{$index_name}<br/><pre>" . print_r($index_fields, TRUE) . '</pre>');
}
}