function chado_publish_records

3.x tripal_chado.api.inc chado_publish_records($values, $job_id = NULL)

Publishes content in Chado as a new TripalEntity entity.

Parameters

$values: A key/value associative array that supports the following keys:

  • bundle_name: The name of the the TripalBundle (e.g. bio_data-12345).

$job_id: (Optional) The numeric job ID as provided by the Tripal jobs system. There is no need to specify this argument if this function is being called outside of the jobs systems.

Return value

boolean TRUE if all of the records of the given bundle type were published, and FALSE if a failure occured.

Related topics

3 calls to chado_publish_records()
chado_migrate_tripal_content_type in tripal_chado/api/tripal_chado.migrate.api.inc
Migrate Tripal content types
tripal_chado_migrate_selected_types in tripal_chado/includes/tripal_chado.migrate.inc
Migrate only selected Tripal v2 content types
tripal_chado_publish_records in tripal_chado/api/tripal_chado.DEPRECATED.api.inc
Publishes content in Chado as a new TripalEntity entity.
1 string reference to 'chado_publish_records'
tripal_chado_publish_form_submit in tripal_chado/includes/tripal_chado.publish.inc
Submit handler for the tripal_chado_publish_form form.

File

tripal_chado/api/tripal_chado.api.inc, line 40
This file contains miscellaneous API functions specific to working with records in Chado that do not have a home in any other sub category of API functions.

Code

function chado_publish_records($values, $job_id = NULL) {

  // We want the job object in order to report progress.
  if (is_object($job_id)) {
    $job = $job_id;
  }
  if (is_numeric($job_id)) {
    $job = new TripalJob();
    $job->load($job_id);
  }
  $report_progress = FALSE;
  if (is_object($job)) {
    $report_progress = TRUE;
  }

  // Make sure we have the required options: bundle_name.
  if (!array_key_exists('bundle_name', $values) or !$values['bundle_name']) {
    tripal_report_error('tripal_chado', TRIPAL_ERROR, 
    "Could not publish record: @error", 
    array('@error' => 'The bundle name must be provided'));
    return FALSE;
  }

  // Get the incoming arguments from the $values array.
  $bundle_name = $values['bundle_name'];
  $filters = array_key_exists('filters', $values) ? $values['filters'] : array();
  $sync_node = array_key_exists('sync_node', $values) ? $values['sync_node'] : '';

  // Load the bundle entity so we can get information about which Chado
  // table/field this entity belongs to.
  $bundle = tripal_load_bundle_entity(array('name' => $bundle_name));
  if (!$bundle) {
    tripal_report_error('tripal_chado', TRIPAL_ERROR, 
    "Unknown bundle. Could not publish record: @error", 
    array('@error' => 'The bundle name must be provided'));
    return FALSE;
  }
  $chado_entity_table = chado_get_bundle_entity_table($bundle);


  // Get the mapping of the bio data type to the Chado table.
  $chado_bundle = db_select('chado_bundle', 'cb')
    ->fields('cb')
    ->condition('bundle_id', $bundle->id)
    ->execute()
    ->fetchObject();
  if (!$chado_bundle) {
    tripal_report_error('tripal_chado', TRIPAL_ERROR, 
    "Cannot find mapping of bundle to Chado tables. Could not publish record.");
    return FALSE;
  }

  $table = $chado_bundle->data_table;
  $type_column = $chado_bundle->type_column;
  $type_linker_table = $chado_bundle->type_linker_table;
  $cvterm_id = $chado_bundle->type_id;
  $type_value = $chado_bundle->type_value;

  // Get the table information for the Chado table.
  $table_schema = chado_get_schema($table);
  $pkey_field = $table_schema['primary key'][0];

  // Construct the SQL for identifying which records should be published.
  $args = array();
  $select = "SELECT T.$pkey_field as record_id ";
  $from = "
    FROM {" . $table . "} T
      LEFT JOIN [" . $chado_entity_table . "] CE on CE.record_id = T.$pkey_field
  ";

  // For migration of Tripal v2 nodes to entities we want to include the
  // coresponding chado linker table.
  if ($sync_node && db_table_exists('chado_' . $table)) {
    $select = "SELECT T.$pkey_field as record_id, CT.nid ";
    $from .= " INNER JOIN [chado_" . $table . "] CT ON CT.$pkey_field = T.$pkey_field";
  }
  $where = " WHERE CE.record_id IS NULL ";

  // Handle records that are mapped to property tables.
  if ($type_linker_table and $type_column and $type_value) {
    $propschema = chado_get_schema($type_linker_table);
    $fkeys = $propschema['foreign keys'][$table]['columns'];
    foreach ($fkeys as $leftkey => $rightkey) {
      if ($rightkey == $pkey_field) {
        $from .= " INNER JOIN {" . $type_linker_table . "} LT ON T.$pkey_field = LT.$leftkey ";
      }
    }
    $where .= "AND LT.$type_column = :cvterm_id and LT.value = :prop_value";
    $args[':cvterm_id'] = $cvterm_id;
    $args[':prop_value'] = $type_value;
  }

  // Handle records that are mapped to cvterm linking tables.
  if ($type_linker_table and $type_column and !$type_value) {
    $cvtschema = chado_get_schema($type_linker_table);
    $fkeys = $cvtschema['foreign keys'][$table]['columns'];
    foreach ($fkeys as $leftkey => $rightkey) {
      if ($rightkey == $pkey_field) {
        $from .= " INNER JOIN {" . $type_linker_table . "} LT ON T.$pkey_field = LT.$leftkey ";
      }
    }
    $where .= "AND LT.$type_column = :cvterm_id";
    $args[':cvterm_id'] = $cvterm_id;
  }

  // Handle records that are mapped via a type_id column in the base table.
  if (!$type_linker_table and $type_column) {
    $where .= "AND T.$type_column = :cvterm_id";
    $args[':cvterm_id'] = $cvterm_id;
  }

  // Handle the case where records are in the cvterm table and mapped via a single
  // vocab.  Here we use the type_value for the cv_id.
  if ($table == 'cvterm' and $type_value) {
    $where .= "AND T.cv_id = :cv_id";
    $args[':cv_id'] = $type_value;
  }

  // Handle the case where records are in the cvterm table but we want to
  // use all of the child terms.
  if ($table == 'cvterm' and !$type_value) {
    $where .= "AND T.cvterm_id IN (
       SELECT CVTP.subject_id
       FROM {cvtermpath} CVTP
       WHERE CVTP.object_id = :cvterm_id)
     ";
    $args[':cvterm_id'] = $cvterm_id;
  }

  // Now add in any additional filters
  $fields = field_info_field_map();
  foreach ($fields as $field_name => $details) {
    if (array_key_exists('TripalEntity', $details['bundles']) and 
      in_array($bundle_name, $details['bundles']['TripalEntity']) and 
      in_array($field_name, array_keys($filters))) {
      $instance = field_info_instance('TripalEntity', $field_name, $bundle_name);
      $chado_table = $instance['settings']['chado_table'];
      $chado_column = $instance['settings']['chado_column'];
      if ($chado_table == $table) {
        $where .= " AND T.$chado_column = :$field_name";
        $args[":$field_name"] = $filters[$field_name];
      }
    }
  }
  // First get the count
  $sql = "SELECT count(*) as num_records " . $from . $where;
  $result = chado_query($sql, $args);
  $count = $result->fetchField();

  // calculate the interval for updates
  $interval = intval($count / 50);
  if ($interval < 1) {
    $interval = 1;
  }

  // Perform the query.
  $sql = $select . $from . $where;
  $records = chado_query($sql, $args);
  $transaction = db_transaction();

  print "\nNOTE: publishing records is performed using a database transaction. \n" .
    "If the load fails or is terminated prematurely then the entire set of \n" .
    "is rolled back with no changes to the database\n\n";

  $i = 0;
  printf("%d of %d records. (%0.2f%%) Memory: %s bytes\r", $i, $count, 0, number_format(memory_get_usage()));
  try {
    while ($record = $records->fetchObject()) {

      // update the job status every interval
      if ($i % $interval == 0) {
        $complete = ($i / $count) * 33.33333333;
        // Currently don't support setting job progress within a transaction.
        // if ($report_progress) { $job->setProgress(intval($complete * 3)); }
        printf("%d of %d records. (%0.2f%%) Memory: %s bytes\r", $i, $count, $complete * 3, number_format(memory_get_usage()));
      }

      // First save the tripal_entity record.
      $record_id = $record->record_id;
      $ec = entity_get_controller('TripalEntity');
      $entity = $ec->create(array(
        'bundle' => $bundle_name,
        'term_id' => $bundle->term_id,
        // Add in the Chado details for when the hook_entity_create()
        // is called and our tripal_chado_entity_create() implementation
        // can deal with it.
        'chado_record' => chado_generate_var($table, array($pkey_field => $record_id)),
        'chado_record_id' => $record_id,
      ));
      $entity = $entity->save();
      if (!$entity) {
        throw new Exception('Could not create entity.');
      }

      // Next save the chado entity record.
      $entity_record = array(
        'entity_id' => $entity->id,
        'record_id' => $record_id,
      );

      // For the Tv2 to Tv3 migration we want to add the nid to the
      // entity so we can associate the node with the entity.
      if (property_exists($record, 'nid')) {
        $entity_record['nid'] = $record->nid;
      }
      $result = db_insert($chado_entity_table)
        ->fields($entity_record)
        ->execute();
      if (!$result) {
        throw new Exception('Could not create mapping of entity to Chado record.');
      }

      $i++;
    }
  }
  catch (Exception $e) {
    $transaction->rollback();
    $error = $e->getMessage();
    tripal_report_error('tripal_chado', TRIPAL_ERROR, "Could not publish record: @error", array('@error' => $error));
    drupal_set_message('Failed publishing record. See recent logs for more details.', 'error');
    return FALSE;
  }
  drupal_set_message("Succesfully published $i " . $bundle->label . " record(s).");
  return TRUE;
}