Browse Source

Added fix for checking duplicate records on insert"

Stephen Ficklin 9 years ago
parent
commit
b79c8d4255

+ 2 - 2
tripal_core/api/tripal_core.chado_query.api.inc

@@ -941,8 +941,8 @@ function chado_delete_record($table, $match, $options = NULL) {
  *     and the type of sort (i.e. ASC, DESC) as the values.  The results in the
  *     query will be sorted by the key values in the direction listed by the value
  *  - is_duplicate: TRUE or FALSE.  Checks the values submited to see if
- *     they violate any of the unique constraints. If so, the record
- *     is returned, if not, FALSE is returned.
+ *     they violate any of the unique constraints. If not, the record
+ *     is returned, if so, FALSE is returned.
  *  - pager:  Use this option if it is desired to return only a subset of results
  *     so that they may be shown with in a Drupal-style pager. This should be
  *     an array with two keys: 'limit' and 'element'.  The value of 'limit'

+ 51 - 43
tripal_entities/includes/TripalEntityController.inc

@@ -82,53 +82,61 @@ class TripalEntityController extends EntityAPIController {
     global $user;
     $pkeys = array();
 
-    // If our entity has no id, then we need to give it a
-    // time of creation.
-    if (empty($entity->id)) {
-      $entity->created = time();
-      $invocation = 'entity_insert';
-    }
-    else {
-      $invocation = 'entity_update';
-      $pkeys = array('id');
-    }
+    $transaction  = db_transaction();
+    try {
+      // If our entity has no id, then we need to give it a
+      // time of creation.
+      if (empty($entity->id)) {
+        $entity->created = time();
+        $invocation = 'entity_insert';
+      }
+      else {
+        $invocation = 'entity_update';
+        $pkeys = array('id');
+      }
 
-    // Invoke hook_entity_presave().
-    module_invoke_all('entity_presave', $entity, $entity->type);
+      // Invoke hook_entity_presave().
+      module_invoke_all('entity_presave', $entity, $entity->type);
 
-    // Write out the entity record.
-    $record = array(
-      'cvterm_id' => $entity->cvterm_id,
-      'type'      => $entity->type,
-      'bundle'    => $entity->bundle,
-      'title'     => $entity->title,
-      'uid'       => $user->uid,
-      'created'   => $entity->created,
-      'changed'   => time(),
-    );
-    if ($invocation == 'entity_update') {
-      $record['id'] = $entity->id;
-    }
-    $success = drupal_write_record('tripal_entity', $record, $pkeys);
-    if ($success == SAVED_NEW) {
-      $entity->id = $record['id'];
-    }
+      // Write out the entity record.
+      $record = array(
+        'cvterm_id' => $entity->cvterm_id,
+        'type'      => $entity->type,
+        'bundle'    => $entity->bundle,
+        'title'     => $entity->title,
+        'uid'       => $user->uid,
+        'created'   => $entity->created,
+        'changed'   => time(),
+      );
+      if ($invocation == 'entity_update') {
+        $record['id'] = $entity->id;
+      }
+      $success = drupal_write_record('tripal_entity', $record, $pkeys);
+      if ($success == SAVED_NEW) {
+        $entity->id = $record['id'];
+      }
 
-    // Now we need to either insert or update the fields which are
-    // attached to this entity. We use the same primary_keys logic
-    // to determine whether to update or insert, and which hook we
-    // need to invoke.
-    if ($invocation == 'entity_insert') {
-      field_attach_insert($entity->type, $entity);
-    }
-    else {
-      field_attach_update($entity->type, $entity);
-    }
+      // Now we need to either insert or update the fields which are
+      // attached to this entity. We use the same primary_keys logic
+      // to determine whether to update or insert, and which hook we
+      // need to invoke.
+      if ($invocation == 'entity_insert') {
+        field_attach_insert($entity->type, $entity);
+      }
+      else {
+        field_attach_update($entity->type, $entity);
+      }
 
-    // Invoke either hook_entity_update() or hook_entity_insert().
-    module_invoke_all('entity_postsave', $entity, $entity->type);
-    module_invoke_all($invocation, $entity, $entity->type);
+      // Invoke either hook_entity_update() or hook_entity_insert().
+      module_invoke_all('entity_postsave', $entity, $entity->type);
+      module_invoke_all($invocation, $entity, $entity->type);
 
-    return $entity;
+      return $entity;
+    }
+    catch (Exception $e) {
+      $transaction->rollback();
+      watchdog_exception('tripal_core', $e);
+      drupal_set_message("Could not create the entity.", "error");
+    }
   }
 }

+ 46 - 53
tripal_entities/includes/tripal_entities.field_storage.inc

@@ -32,52 +32,45 @@ function tripal_entities_field_storage_write($entity_type, $entity, $op, $fields
     $residues = $field_vals['feature__residues'];
     $field_vals['feature__md5checksum'] = $field_vals['feature__md5checksum'] ? md5($residues) : NULL;
   }
-  $transaction = db_transaction();
-  try {
-    switch ($op) {
-      case FIELD_STORAGE_INSERT:
-        // Use the cvterm_id to look up tables where this term is used
-        $sel_values = array(
-          'term_id' => array(
-            'cvterm_id' => $entity->cvterm_id,
-          ),
-        );
-        $term_usage = chado_generate_var('tripal_term_usage', $sel_values, array('return_array' => 1));
+dpm($field_vals);
+  switch ($op) {
+    case FIELD_STORAGE_INSERT:
+      // Use the cvterm_id to look up tables where this term is used
+      $sel_values = array(
+        'term_id' => array(
+          'cvterm_id' => $entity->cvterm_id,
+        ),
+      );
+      $term_usage = chado_generate_var('tripal_term_usage', $sel_values, array('return_array' => 1));
 
-        // For each table that uses this term, insert the field recursively
-        foreach ($term_usage as $usage) {
-          $data_table = $usage->data_table;
-          //$type_table = $usage->type_table;
-          $type_field = $usage->field;
-          tripal_entities_field_storage_write_recursive($entity_type, $entity,
-            $op, $field_vals, $data_table, $type_field);
-        }
-        break;
+      // For each table that uses this term, insert the field recursively
+      foreach ($term_usage as $usage) {
+        $data_table = $usage->data_table;
+        //$type_table = $usage->type_table;
+        $type_field = $usage->field;
+        tripal_entities_field_storage_write_recursive($entity_type, $entity,
+          $op, $field_vals, $data_table, $type_field);
+      }
+      break;
 
-      case FIELD_STORAGE_UPDATE :
+    case FIELD_STORAGE_UPDATE :
 
-        // Get the base table and record id for the fields of this entity.
-        $details = db_select('chado_entity', 'ce')
-          ->fields('ce')
-          ->condition('entity_id', $entity->id)
-          ->execute()
-          ->fetchObject();
-        $tablename = $details->data_table;
-        $type_field = $details->field;
-        $record_id = $details->record_id;
+      // Get the base table and record id for the fields of this entity.
+      $details = db_select('chado_entity', 'ce')
+        ->fields('ce')
+        ->condition('entity_id', $entity->id)
+        ->execute()
+        ->fetchObject();
+      $tablename = $details->data_table;
+      $type_field = $details->field;
+      $record_id = $details->record_id;
 
-        tripal_entities_field_storage_write_recursive($entity_type, $entity,
-          $op, $field_vals, $tablename, $type_field, $record_id);
-        if (!$details) {
-          // TODO: what to do if record is missing!
-        }
-        break;
-    }
-  }
-  catch (Exception $e) {
-    $transaction->rollback();
-    watchdog_exception('tripal_feature', $e);
-    drupal_set_message('Could not write record to Chado.  See recent logs', 'error');
+      tripal_entities_field_storage_write_recursive($entity_type, $entity,
+        $op, $field_vals, $tablename, $type_field, $record_id);
+      if (!$details) {
+        // TODO: what to do if record is missing!
+      }
+      break;
   }
 }
 
@@ -86,7 +79,7 @@ function tripal_entities_field_storage_write($entity_type, $entity, $op, $fields
  */
 function tripal_entities_field_storage_write_recursive($entity_type, $entity,
    $op, $field_vals, $tablename, $type_field = NULL, $record_id = NULL, $depth = 0) {
-
+  dpm($tablename);
   // Intialize the values array and $record_id;
   $values = array();
 
@@ -119,7 +112,7 @@ function tripal_entities_field_storage_write_recursive($entity_type, $entity,
       $fk_val = array_key_exists($fk_field_name, $field_vals) ? $field_vals[$fk_field_name] : NULL;
       $fk_val = tripal_entities_field_storage_write_recursive($entity_type,
         $entity, $op, $field_vals, $fk_table, NULL, $fk_val, $depth + 1);
-      if ($fk_val) {
+      if (!isset($fk_val) or $fk_value != '') {
         $values[$local_id] = $fk_val;
       }
     }
@@ -161,19 +154,19 @@ function tripal_entities_field_storage_write_recursive($entity_type, $entity,
   }
   // If we don't have an incoming record ID then this is an insert.
   if (!$record_id) {
-    // STEP 4: Before inserting, we want to make sure the record does not already exist
-    $existing = chado_select_record($tablename, array('*'), $values);
-    if(count($existing) > 0) {
-      $existing_record = $existing[0];
-      $record_id = $existing_record->$pkey_field;
-      return $record_id;
+    // STEP 3a: Before inserting, we want to make sure the record does not
+    // already exist.  Using the unique constraint check for a matching record.
+    $options = array('is_duplicate' => TRUE);
+    $is_duplicate = chado_select_record($tablename, array('*'), $values, $options);
+    if($is_duplicate) {
+      throw new Exception('Could not insert Chado record into table: "' . $tablename . '".');
     }
-    
-    // STEP 5: Insert the reocrd
+
+    // STEP 3b: Insert the reocrd
     // Insert the values array as a new record in the table.
     $record = chado_insert_record($tablename, $values);
     if ($record === FALSE) {
-      drupal_set_message('Could not insert Chado record into table, "$table".', 'error');
+      throw new Exception('Could not insert Chado record into table: "' . $tablename . '".');
     }
     $record_id = $record[$pkey_field];