Created
August 17, 2010 03:54
-
-
Save bangpound/528371 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Migrate {taxonomy_term_node} table to field storage. | |
*/ | |
function taxonomy_update_7005(&$sandbox) { | |
// This is a multi-pass update. On the first call we need to initialize some | |
// variables. | |
if (!isset($sandbox['total'])) { | |
$sandbox['last'] = 0; | |
$sandbox['count'] = 0; | |
$query = db_select('taxonomy_term_node', 't'); | |
$sandbox['total'] = $query->countQuery()->execute()->fetchField(); | |
// Use an inline version of Drupal 6 taxonomy_get_vocabularies() here since | |
// we can no longer rely on $vocabulary->nodes from the API function. | |
$result = db_query('SELECT v.vid, v.machine_name, n.type FROM {taxonomy_vocabulary} v INNER JOIN {taxonomy_vocabulary_node_type} n ON v.vid = n.vid'); | |
$vocabularies = array(); | |
foreach ($result as $record) { | |
// If no node types are associated with a vocabulary, the LEFT JOIN will | |
// return a NULL value for type. | |
if (isset($record->type)) { | |
$vocabularies[$record->vid][$record->type] = 'taxonomy_'. $record->machine_name; | |
} | |
} | |
if (!empty($vocabularies)) { | |
$sandbox['vocabularies'] = $vocabularies; | |
} | |
} | |
else { | |
$field_info = field_info_fields(); | |
$etid = _field_sql_storage_etid('node'); | |
// We do each pass in batches of 1000. | |
$batch = 1000; | |
// Query selects all revisions at once and processes them in revision and | |
// term weight order. | |
$query = 'SELECT td.vid AS vocab_id, td.tid, tn.nid, tn.vid, n.type, n2.created, n2.sticky, n2.nid AS is_current FROM {taxonomy_term_data} td LEFT JOIN {taxonomy_term_node} tn ON td.tid = tn.tid LEFT JOIN {node} n ON tn.nid = n.nid LEFT JOIN {node} n2 ON tn.vid = n2.vid ORDER BY tn.vid, td.weight ASC'; | |
$result = db_query_range($query, $sandbox['last'], $batch); | |
if (isset($sandbox['cursor'])) { | |
$values = $sandbox['cursor']['values']; | |
$deltas = $sandbox['cursor']['deltas']; | |
} | |
else { | |
$deltas = array(); | |
} | |
foreach ($result as $record) { | |
$sandbox['count'] += 1; | |
// Use the valid field for this vocabulary and node type or use the | |
// overflow vocabulary if there is no valid field. | |
$field_name = isset($sandbox['vocabularies'][$record->vocab_id][$record->type]) ? $sandbox['vocabularies'][$record->vocab_id][$record->type] : 'taxonomyextra_upgrade'; | |
$field = $field_info[$field_name]; | |
// Start deltas from 0, and increment by one for each term attached to a | |
// node. | |
if (!isset($deltas[$field_name])) { | |
$deltas[$field_name] = 0; | |
} | |
if (isset($values)) { | |
// If the last inserted revision_id is the same as the current record, | |
// use the previous deltas to calculate the next delta. | |
if ($record->vid == $values[2]) { | |
// see field_default_validate(). | |
if ($field['cardinality'] != FIELD_CARDINALITY_UNLIMITED && ($deltas[$field_name] + 1) >= $field['cardinality']) { | |
// For excess values for a single value field, switch over to the | |
// overflow field. | |
$field_name = 'taxonomyextra_upgrade'; | |
$field = $field_info[$field_name]; | |
} | |
} | |
else { | |
// When the record is a new revision, empty the deltas array. | |
$deltas = array($field_name => 0); | |
} | |
} | |
// 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']; | |
// Column names and values in field storage are the same for current and | |
// revision. | |
$columns = array('etid', 'entity_id', 'revision_id', 'bundle', 'language', 'delta', $value_column); | |
$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(); | |
// 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(); | |
// Update the {taxonomy_index} table. | |
db_insert('taxonomy_index') | |
->fields(array('nid', 'tid', 'sticky', 'created',)) | |
->values(array($record->nid, $record->tid, $record->sticky, $record->created)) | |
->execute(); | |
} | |
} | |
// Store the set of inserted values and the current revision's deltas in the | |
// sandbox. | |
$sandbox['cursor'] = array( | |
'values' => $values, | |
'deltas' => $deltas, | |
); | |
$sandbox['last'] += $batch; | |
} | |
if ($sandbox['count'] < $sandbox['total']) { | |
$sandbox['#finished'] = FALSE; | |
} | |
else { | |
db_drop_table('taxonomy_vocabulary_node_type'); | |
db_drop_table('taxonomy_term_node'); | |
// If there are no vocabs, we're done. | |
$sandbox['#finished'] = TRUE; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment