diff --git a/modules/field/field.crud.inc b/modules/field/field.crud.inc index e4486d0..3c2128b 100644 --- a/modules/field/field.crud.inc +++ b/modules/field/field.crud.inc @@ -31,9 +31,7 @@ * Other properties, if omitted, will be given the following default values: * - cardinality: 1 * - locked: FALSE - * - indexes: the field-type indexes, specified by the field type's - * hook_field_schema(). The indexes specified in $field are added - * to those default indexes. It is possible to override the + * - custom indexes: An array of indexes that should override the * definition of a field-type index by providing an index with the * same name, or to remove it by redefining it as an empty array * of columns. Overriding field-type indexes should be done @@ -102,6 +100,7 @@ function field_create_field($field) { 'settings' => array(), 'storage' => array(), 'deleted' => 0, + 'custom indexes' => array(), ); // Check that the field type is known. @@ -137,12 +136,8 @@ function field_create_field($field) { $field['columns'] = $schema['columns']; // 'foreign keys' are hardcoded in the field type. $field['foreign keys'] = $schema['foreign keys']; - // 'indexes' can be both hardcoded in the field type, and specified in the - // incoming $field definition. - $field += array( - 'indexes' => array(), - ); - $field['indexes'] += $schema['indexes']; + // 'indexes' can be overridden by the 'custom indexes' value if set. + $field['indexes'] = $field['custom indexes'] + $schema['indexes']; // The serialized 'data' column contains everything from $field that does not // have its own column and is not automatically populated when the field is @@ -249,12 +244,8 @@ function field_update_field($field) { $field['columns'] = $schema['columns']; // 'foreign keys' are hardcoded in the field type. $field['foreign keys'] = $schema['foreign keys']; - // 'indexes' can be both hardcoded in the field type, and specified in the - // incoming $field definition. - $field += array( - 'indexes' => array(), - ); - $field['indexes'] += $schema['indexes']; + // 'indexes' can be overridden by the 'custom indexes' value if set. + $field['indexes'] = $field['custom indexes'] + $schema['indexes']; $has_data = field_has_data($field); diff --git a/modules/field/tests/field.test b/modules/field/tests/field.test index 1e59315..5c68976 100644 --- a/modules/field/tests/field.test +++ b/modules/field/tests/field.test @@ -2497,7 +2497,7 @@ class FieldCrudTestCase extends FieldTestCase { $field_definition = array( 'field_name' => 'field_2', 'type' => 'test_field', - 'indexes' => array( + 'custom indexes' => array( 'value' => array(), ), ); @@ -2511,7 +2511,7 @@ class FieldCrudTestCase extends FieldTestCase { $field_definition = array( 'field_name' => 'field_3', 'type' => 'test_field', - 'indexes' => array( + 'custom indexes' => array( 'value_2' => array('value'), ), ); @@ -2522,6 +2522,59 @@ class FieldCrudTestCase extends FieldTestCase { } /** + * Test changing a field's schema using field_update_field(). + */ + function testFieldSchemaUpdate() { + $schema = Database::getConnection()->schema(); + + // Create a test field. + $field_definition = array( + 'field_name' => 'test', + 'type' => 'test_field', + ); + field_create_field($field_definition); + + $this->assertTrue($schema->tableExists('field_data_test')); + $this->assertTrue($schema->fieldExists('field_data_test', 'test_value')); + $this->assertTrue($schema->indexExists('field_data_test', 'test_value')); + $this->assertFalse($schema->fieldExists('field_data_test', 'test_value2')); + $this->assertFalse($schema->indexExists('field_data_test', 'test_value2')); + + // Register an additional column and index for field_test_field_schema(). + variable_set('field_test_field_schema_override', array( + 'columns' => array( + 'value2' => array( + 'type' => 'int', + 'size' => 'medium', + 'not null' => FALSE, + ), + ), + 'indexes' => array( + 'value2' => array('value2'), + ), + )); + + // Update the field, which should add the new value2 column and index. + field_update_field($field_definition); + $this->assertTrue($schema->tableExists('field_data_test')); + $this->assertTrue($schema->fieldExists('field_data_test', 'test_value')); + $this->assertTrue($schema->indexExists('field_data_test', 'test_value')); + $this->assertTrue($schema->fieldExists('field_data_test', 'test_value2')); + $this->assertTrue($schema->indexExists('field_data_test', 'test_value2')); + + // Unregister the additional value2 column and index. + variable_del('field_test_field_schema_override'); + + // Update the field, which should now remove the value2 column and index. + field_update_field($field_definition); + $this->assertTrue($schema->tableExists('field_data_test')); + $this->assertTrue($schema->fieldExists('field_data_test', 'test_value')); + $this->assertTrue($schema->indexExists('field_data_test', 'test_value')); + $this->assertFalse($schema->fieldExists('field_data_test', 'test_value2')); + $this->assertFalse($schema->indexExists('field_data_test', 'test_value2')); + } + + /** * Test the deletion of a field. */ function testDeleteField() { diff --git a/modules/field/tests/field_test.install b/modules/field/tests/field_test.install index eaf1390..a1c6ecb 100644 --- a/modules/field/tests/field_test.install +++ b/modules/field/tests/field_test.install @@ -118,7 +118,7 @@ function field_test_schema() { */ function field_test_field_schema($field) { if ($field['type'] == 'test_field') { - return array( + $schema = array( 'columns' => array( 'value' => array( 'type' => 'int', @@ -130,6 +130,10 @@ function field_test_field_schema($field) { 'value' => array('value'), ), ); + if ($override = variable_get('field_test_field_schema_override', array())) { + $schema = drupal_array_merge_deep($override, $schema); + } + return $schema; } else { $foreign_keys = array();