You are here

taxonomy_edge.rebuild.inc in Taxonomy Edge 7.2

This file contains the functions for reuilding various tables.

File

taxonomy_edge.rebuild.inc
View source
<?php

/**
 * @file
 *
 * This file contains the functions for reuilding various tables.
 */

/**
 * Start batch job for rebuild of edges
 */
function taxonomy_edge_rebuild_edges_batch($vid) {
  $batch = array(
    'operations' => array(
      array(
        'taxonomy_edge_rebuild_edges',
        array(
          $vid,
        ),
      ),
    ),
    'finished' => 'taxonomy_edge_rebuild_finished',
    'file' => drupal_get_path('module', 'taxonomy_edge') . '/taxonomy_edge.rebuild.inc',
    'title' => t('Rebuilding taxonomy edges'),
    'init_message' => t('Rebuilding taxonomy edges'),
  );
  batch_set($batch);
}

/**
 * Start batch job for rebuild of order
 */
function taxonomy_edge_rebuild_order_batch($vid) {
  $batch = array(
    'operations' => array(
      array(
        'taxonomy_edge_rebuild_order',
        array(
          $vid,
        ),
      ),
    ),
    'finished' => 'taxonomy_edge_rebuild_finished',
    'file' => drupal_get_path('module', 'taxonomy_edge') . '/taxonomy_edge.rebuild.inc',
    'title' => t('Rebuilding taxonomy edge order'),
    'init_message' => t('Rebuilding taxonomy edge order'),
  );
  batch_set($batch);
}

/**
 * Finished function for rebuild tree batch operation.
 *
 * @param type $success
 * @param type $result
 * @param type $operations
 */
function taxonomy_edge_rebuild_finished($success, $results, $operations) {
  if ($success) {

    // Here we do something meaningful with the results.
    $message = theme('item_list', array(
      'items' => $results,
    ));
  }
  else {

    // An error occurred.
    // $operations contains the operations that remained unprocessed.
    $error_operation = reset($operations);
    $message = t('An error occurred while processing %error_operation with arguments: @arguments', array(
      '%error_operation' => $error_operation[0],
      '@arguments' => print_r($error_operation[1], TRUE),
    ));
  }
  drupal_set_message($message);
}

/**
 * Rebuild entire edge list.
 *
 * @return integer
 *   Total number of rows inserted.
 */
function taxonomy_edge_rebuild_edges($vid, &$context) {
  $depth = 0;
  $max_depth = variable_get('taxonomy_edge_max_depth', TAXONOMY_EDGE_MAX_DEPTH);
  $time = microtime(TRUE);

  // Acquire lock to avoid conflicts with queue
  if (!lock_acquire('taxonomy_edge_rebuild_edges_' . $vid)) {
    $context['success'] = FALSE;
    $context['message'] = t('Could not acquire lock!');
    $context['results'] = array(
      'rows' => 0,
      'depth' => 0,
      'time' => microtime(TRUE) - $time,
    );
    return;
  }
  set_time_limit(86400);

  // Clear the queue, we're rebulding anyways ...
  $queue = DrupalQueue::get('taxonomy_edge_items_' . $vid, TRUE);
  $queue
    ->deleteQueue();

  // Please use a proper isolation level, so that transaction provides us with a
  // snapshot
  $tx = db_transaction();

  // Clear out tables

  #$using = "{taxonomy_term_edge}, {taxonomy_term_edge_path}";

  #db_query("DELETE FROM {taxonomy_term_edge} USING $using WHERE {taxonomy_term_edge}.pid = {taxonomy_term_edge_path}.pid AND {taxonomy_term_edge_path}.vid = :vid", array(':vid' => $vid));
  db_query("DELETE FROM {taxonomy_term_edge} WHERE vid = :vid", array(
    ':vid' => $vid,
  ));
  db_query("DELETE FROM {taxonomy_term_edge_path} WHERE vid = :vid", array(
    ':vid' => $vid,
  ));
  $total_rows = 0;

  // @todo Atomise properly?
  $pid = taxonomy_edge_get_root_pid();
  if (!db_query("SELECT pid FROM {taxonomy_term_edge} WHERE pid = :pid", array(
    ':pid' => $pid,
  ))
    ->fetchField()) {

    // Initial edges
    $total_rows += db_query("\n      INSERT INTO {taxonomy_term_edge} (vid, pid, parent, distance)\n      SELECT :vid, pid, :pid, 0\n      FROM {taxonomy_term_edge_path}\n      WHERE pid = :pid \n    ", array(
      ':vid' => $vid,
      ':pid' => $pid,
    ))
      ->rowCount();
  }
  $context['message'] = t('Processed %rows rows - current depth: %depth', array(
    '%rows' => $total_rows,
    '%depth' => $depth,
  ));
  $context['finished'] = 0.5;
  while ($max_depth-- > 0) {

    // Path for depth $depth
    $result = db_query("\n      INSERT INTO {taxonomy_term_edge_path} (tid, vid, temp_pid)\n      SELECT h.tid, d.vid, e.pid\n      FROM {taxonomy_term_edge} e\n      INNER JOIN {taxonomy_term_edge_path} p ON e.pid = p.pid\n      INNER JOIN {taxonomy_term_hierarchy} h ON h.parent = p.tid AND e.distance = :depth\n      INNER JOIN {taxonomy_term_data} d ON d.tid = h.tid\n      WHERE d.vid = :vid\n    ", array(
      ':depth' => $depth,
      ':vid' => $vid,
    ));

    // Edges for those paths
    $rows = db_query("\n      INSERT INTO {taxonomy_term_edge} (vid, pid, parent, distance)\n      SELECT :vid, p.pid, p.pid, 0\n      FROM {taxonomy_term_edge_path} p\n      WHERE p.temp_pid > 0 AND p.vid = :vid\n    ", array(
      ':vid' => $vid,
    ))
      ->rowCount();

    // Edges for those paths parents
    $rows += db_query("\n      INSERT INTO {taxonomy_term_edge} (vid, pid, parent, distance)\n      SELECT :vid, p.pid, e.parent, e.distance + 1\n      FROM {taxonomy_term_edge_path} p \n      INNER JOIN {taxonomy_term_edge} e ON p.temp_pid = e.pid\n      WHERE p.temp_pid > 0 AND p.vid = :vid\n    ", array(
      ':vid' => $vid,
    ))
      ->rowCount();
    if ($rows <= 0) {
      break;
    }
    $depth++;
    db_query("UPDATE {taxonomy_term_edge_path} SET temp_pid = 0 WHERE temp_pid > 0 AND vid = :vid", array(
      ':vid' => $vid,
    ));
    $total_rows += $rows;
    $context['message'] = t('Processed %rows rows - current depth: %depth', array(
      '%rows' => $total_rows,
      '%depth' => $depth,
    ));
    $context['finished'] += (1 - $context['finished']) / 2;
  }
  $context['finished'] = 1;
  $context['results'][] = t('Taxonomy edges rebuilt: %rows processed with depth %depth in %time seconds', array(
    '%rows' => $total_rows,
    '%depth' => $depth,
    '%time' => microtime(TRUE) - $time,
  ));
  taxonomy_edge_invalidate_order($vid);
  lock_release('taxonomy_edge_rebuild_edges_' . $vid);
  return $total_rows;
}

/**
 * Rebuild the sorted tree.
 */
function taxonomy_edge_rebuild_order($vid, &$context) {

  // Acquire lock
  if (!lock_acquire('taxonomy_edge_rebuild_edges_' . $vid)) {
    $context['success'] = FALSE;
    $context['message'] = t('Could not acquire lock!');
    return;
  }
  $tx = db_transaction();
  $time = microtime(TRUE);
  db_query("DELETE FROM {taxonomy_term_edge_order} WHERE vid = :vid", array(
    ':vid' => $vid,
  ));
  $total_rows = db_query("\n    INSERT INTO {taxonomy_term_edge_order} (vid, pid)\n    SELECT :vid, op.pid\n    FROM {taxonomy_term_edge_path} op\n    WHERE op.vid = :vid\n    ORDER BY " . _taxonomy_edge_generate_term_path_query('op.pid'), array(
    ':vid' => $vid,
  ))
    ->rowCount();
  $context['finished'] = 1;
  $context['results'][] = t('Trees sorted: %rows leaves in %time seconds', array(
    '%rows' => $total_rows,
    '%time' => microtime(TRUE) - $time,
  ));
  lock_release('taxonomy_edge_rebuild_edges_' . $vid);
}

Functions

Namesort descending Description
taxonomy_edge_rebuild_edges Rebuild entire edge list.
taxonomy_edge_rebuild_edges_batch Start batch job for rebuild of edges
taxonomy_edge_rebuild_finished Finished function for rebuild tree batch operation.
taxonomy_edge_rebuild_order Rebuild the sorted tree.
taxonomy_edge_rebuild_order_batch Start batch job for rebuild of order