#895386: taxonomy upgrade path clean-up.

From: Damien Tournoud <damien@commerceguys.com>


---
 field/field.install       |   69 +++++++++++++++++++++++++++++++++++++++++++++
 taxonomy/taxonomy.install |   44 ++++++++++++++++++-----------
 2 files changed, 96 insertions(+), 17 deletions(-)

diff --git modules/field/field.install modules/field/field.install
index d638f69..e92f963 100644
--- modules/field/field.install
+++ modules/field/field.install
@@ -240,6 +240,56 @@ function _update_7000_field_create_field(&$field) {
 }
 
 /**
+ * Utility function: delete a field and its instances and data from the database.
+ *
+ * This function is valid for a database schema version 7000.
+ *
+ * @ingroup update-api-6.x-to-7.x
+ * @param $field_name
+ *   The field name to delete.
+ */
+function _update_7000_field_delete_field($field_name) {
+  // Delete all instances.
+  db_delete('field_config_instance')
+    ->condition('field_name', $field_name)
+    ->execute();
+
+  // Mark field data for deletion.
+  module_invoke($field['storage']['module'], 'field_storage_delete_field', $field);
+
+  // Delete the field.
+  db_delete('field_config')
+    ->condition('field_name', $field_name)
+    ->execute();
+}
+
+/**
+ * Utility function: fetch all the field definitions from the database.
+ */
+function _update_7000_field_read_fields() {
+  $fields = array();
+  $results = db_query('SELECT * FROM {field_config} WHERE deleted = 0', array(), array('fetch' => PDO::FETCH_ASSOC));
+  foreach ($results as $record) {
+    $field = unserialize($record['data']);
+    $field['id'] = $record['id'];
+    $field['field_name'] = $record['field_name'];
+    $field['type'] = $record['type'];
+    $field['module'] = $record['module'];
+    $field['active'] = $record['active'];
+    $field['storage']['type'] = $record['storage_type'];
+    $field['storage']['module'] = $record['storage_module'];
+    $field['storage']['active'] = $record['storage_active'];
+    $field['locked'] = $record['locked'];
+    $field['cardinality'] = $record['cardinality'];
+    $field['translatable'] = $record['translatable'];
+    $field['deleted'] = $record['deleted'];
+
+    $fields[$field['field_name']] = $field;
+  }
+  return $fields;
+}
+
+/**
  * Utility function: create a field instance directly to the database.
  *
  * This function is valid for a database schema version 7000.
@@ -274,6 +324,25 @@ function _update_7000_field_create_instance($field, &$instance) {
 }
 
 /**
+ * Utility function: delete an instance from the database.
+ *
+ * This function is valid for a database schema version 7000.
+ *
+ * @ingroup update-api-6.x-to-7.x
+ */
+function _update_7000_field_delete_instance($instance) {
+  // Mark the field instance for deletion.
+  db_delete('field_config_instance')
+    ->condition('field_name', $instance['field_name'])
+    ->condition('entity_type', $instance['entity_type'])
+    ->condition('bundle', $instance['bundle'])
+    ->execute();
+
+  // Mark instance data for deletion.
+  module_invoke($field['storage']['module'], 'field_storage_delete_instance', $instance);
+}
+
+/**
  * @defgroup field-updates-6.x-to-7.x Field updates from 6.x to 7.x
  * @{
  */
diff --git modules/taxonomy/taxonomy.install modules/taxonomy/taxonomy.install
index 3be5829..0b7d388 100644
--- modules/taxonomy/taxonomy.install
+++ modules/taxonomy/taxonomy.install
@@ -264,6 +264,17 @@ function taxonomy_update_dependencies() {
 }
 
 /**
+ * Utility function: get the list of vocabularies directly from the database.
+ *
+ * This function is valid for a database schema version 7002.
+ *
+ * @ingroup update-api-6.x-to-7.x
+ */
+function _update_7002_taxonomy_get_vocabularies() {
+  return db_query('SELECT v.* FROM {taxonomy_vocabulary} v ORDER BY v.weight, v.name')->fetchAllAssoc('vid', PDO::FETCH_OBJ);
+}
+
+/**
  * Rename taxonomy tables.
  */
 function taxonomy_update_7001() {
@@ -299,7 +310,6 @@ function taxonomy_update_7002() {
       ->fields(array('machine_name' => $machine_name))
       ->condition('vid', $vid)
       ->execute();
-    field_attach_create_bundle('taxonomy_term', $machine_name);
   }
 
   // The machine_name unique key can only be added after we ensure the
@@ -404,7 +414,7 @@ function taxonomy_update_7004() {
         ),
       ),
     );
-    field_create_field($field);
+    _update_7000_field_create_field($field);
 
     foreach ($vocabulary->nodes as $bundle) {
       $instance = array(
@@ -427,7 +437,7 @@ function taxonomy_update_7004() {
           ),
         ),
       );
-      field_create_instance($instance);
+      _update_7000_field_create_instance($instance);
     }
   }
 
@@ -438,7 +448,7 @@ function taxonomy_update_7004() {
 
   // Allowed values for this extra vocabs field is every vocabulary.
   $allowed_values = array();
-  foreach (taxonomy_get_vocabularies() as $vocabulary) {
+  foreach (_update_7002_taxonomy_get_vocabularies() as $vocabulary) {
     $allowed_values[] = array(
       'vid' => $vocabulary->vid,
       'parent' => 0,
@@ -455,14 +465,14 @@ function taxonomy_update_7004() {
       'allowed_values' => $allowed_values,
     ),
   );
-  field_create_field($field);
+  _update_7000_field_create_field($field);
 
-  foreach (node_type_get_types() as $bundle) {
+  foreach (_update_7000_node_get_types() as $bundle) {
     $instance = array(
       'label' => 'Taxonomy upgrade extras',
       'field_name' => $field_name,
-      'bundle' => $bundle->type,
       'entity_type' => 'node',
+      'bundle' => $bundle->type,
       'description' => 'Debris left over after upgrade from Drupal 6',
       'widget' => array(
         'type' => 'taxonomy_autocomplete',
@@ -478,7 +488,7 @@ function taxonomy_update_7004() {
         ),
       ),
     );
-    field_create_instance($instance);
+    _update_7000_field_create_instance($instance);
   }
 
   $fields = array('help', 'multiple', 'required', 'tags');
@@ -528,7 +538,7 @@ function taxonomy_update_7005(&$sandbox) {
   // provides the delta value for each term reference data insert. The
   // deltas are reset for each new revision.
 
-  $field_info = field_info_fields();
+  $field_info = _update_7000_field_read_fields();
 
   // This is a multi-pass update. On the first call we need to initialize some
   // variables.
@@ -635,8 +645,9 @@ function taxonomy_update_7005(&$sandbox) {
 
       // Table and column found in the field's storage details. During upgrades,
       // it's always SQL.
-      $table = key($field['storage']['details']['sql'][FIELD_LOAD_REVISION]);
-      $value_column = $field['storage']['details']['sql'][FIELD_LOAD_REVISION][$table]['tid'];
+      $table_name = "field_data_{$field_name}";
+      $revision_name = "field_revision_{$field_name}";
+      $value_column = $field_name . '_tid';
 
       // Column names and values in field storage are the same for current and
       // revision.
@@ -644,12 +655,11 @@ function taxonomy_update_7005(&$sandbox) {
       $values = array($etid, $record->nid, $record->vid, $record->type, LANGUAGE_NONE, $deltas[$field_name]++, $record->tid);
 
       // Insert rows into the revision table.
-      db_insert($table)->fields($columns)->values($values)->execute();
+      db_insert($revision_name)->fields($columns)->values($values)->execute();
 
       // is_current column is a node ID if this revision is also current.
       if ($record->is_current) {
-        $table = key($field['storage']['details']['sql'][FIELD_LOAD_CURRENT]);
-        db_insert($table)->fields($columns)->values($values)->execute();
+        db_insert($table_name)->fields($columns)->values($values)->execute();
 
         // Update the {taxonomy_index} table.
         db_insert('taxonomy_index')
@@ -680,13 +690,13 @@ function taxonomy_update_7005(&$sandbox) {
 
     // Determine necessity of taxonomyextras field.
     $field = $field_info['taxonomyextra'];
-    $table = key($field['storage']['details']['sql'][FIELD_LOAD_REVISION]);
-    $node_types = db_select($table)->distinct()->fields($table, array('bundle'))
+    $revision_name = "field_revision_{$field[field_name]}";
+    $node_types = db_select($revision_name)->distinct()->fields($revision_name, array('bundle'))
       ->execute()->fetchCol();
 
     if (empty($node_types)) {
       // Delete the overflow field if there are no rows in the revision table.
-      field_delete_field('taxonomyextra');
+      _update_7000_field_delete_field('taxonomyextra');
     }
     else {
       // Remove instances which are not actually used.
