Browse Source

Fixed bug in core API that caused problem with the bulk loader when a duplicate record existed. The tripal_core_chado_select wasn't checking all unique constraints. Some tables have more than one

spficklin 12 years ago
parent
commit
d2e6f50f5c

+ 5 - 6
tripal_bulk_loader/tripal_bulk_loader.loader.inc

@@ -496,17 +496,16 @@ function process_data_array_for_line($priority, &$data, &$default_data, $addt) {
   // Check that template required fields are present. if a required field is 
   // missing and this
   // is an optional record then just return. otherwise raise an error
-  $skip_optional = 0;
   foreach ($table_data['required'] as $field => $required) {
     if ($required) {
       // check if the field has no value (or array is empty)
-      if (!isset($values[$field]) or (is_array($values[$field]) and count($values[$field]) == 0)){
+      if (!isset($values[$field]) or 
+          (is_array($values[$field]) and count($values[$field]) == 0)){
         // check if the record is optional.  For backwards compatiblity we need to
         // check if the 'mode' is set to 'optional'
         if ($table_data['optional'] or preg_match('/optional/', $table_data['mode']) or 
             $table_data['select_optional'])  {
             
-          $skip_optional = 1;
           // set the values array to be empty since we all required fields are
           // optional and we can't do a select/insert so we don't want to keep
           // the values if this record is used in a later FK relationship.
@@ -526,8 +525,8 @@ function process_data_array_for_line($priority, &$data, &$default_data, $addt) {
   // for an insert, check that all database required fields are present in the values array
   // we check for 'optional' in the mode for backwards compatibility. The 'optional' 
   // mode used to be a type of insert
-  if (!$skip_optional and (preg_match('/insert/', $table_data['mode']) or 
-       preg_match('/optional/', $table_data['mode']))) {
+  if (preg_match('/insert/', $table_data['mode']) or 
+      preg_match('/optional/', $table_data['mode'])) {
     // Check all database table required fields are set
     $fields = $table_desc['fields'];
     foreach ($fields as $field => $def) { 	
@@ -570,7 +569,7 @@ function process_data_array_for_line($priority, &$data, &$default_data, $addt) {
   if (preg_match('/insert_unique/', $table_data['mode']) or 
       (array_key_exists('select_if_duplicate', $table_data) and 
        $table_data['select_if_duplicate'] == 1)) {
-    $options = array('use_unique' => TRUE);
+    $options = array('is_duplicate' => TRUE);
     $duplicate = tripal_core_chado_select($table, array_keys($table_desc['fields']), $values, $options); 
     // if this is a duplicate then substitute the values in the table_data array so
     // that for future records that my depend on this one, they can get the values 

+ 35 - 38
tripal_core/api/tripal_core.api.inc

@@ -859,15 +859,9 @@ function tripal_core_chado_delete($table, $match) {
  *     default if the statement is not prepared it will be automatically.
  *     However to avoid this check, which requires a database query you can
  *     set this value to true and the check will not be performed.
- *  - use_unique: TRUE or FALSE.  This will alter the values array provided
- *     to the function and remove fields not in
- *     a unique constraint.  This is useful before an insert to check if
- *     another record exists with the same unique constraint (but possible differences
- *     in the other fields) and cause a duplicate insert error.  If a field
- *     in the unique constraint is missing from the values then the function
- *     will return false.  If the table has a primary key, the resulting
- *     record will only have the pkey field. If there is no primary key the
- *     resulting record will have the unique constraint fields.
+ *  - is_duplicate: TRUE or FALSE.  Checks the values submited to see if
+ *     they violoate any of the unique constraints. If so, the record
+ *     is returned, if not, FALSE is returned.
  *
  *
  * @return
@@ -937,8 +931,8 @@ function tripal_core_chado_select($table, $columns, $values, $options = NULL) {
   if (!array_key_exists('statement_name',$options)) {
     $options['statement_name'] = FALSE;
   }
-  if (!array_key_exists('use_unique',$options)) {
-    $options['use_unique'] = FALSE;
+  if (!array_key_exists('is_duplicate',$options)) {
+    $options['is_duplicate'] = FALSE;
   }
 
   // if this is a prepared statement check to see if it has already been prepared
@@ -974,54 +968,58 @@ function tripal_core_chado_select($table, $columns, $values, $options = NULL) {
 
   // if the 'use_unique' option is turned on then we want
   // to remove all but unique keys
-  if ($options['use_unique'] and array_key_exists('unique keys', $table_desc)) {
+  if ($options['is_duplicate'] and array_key_exists('unique keys', $table_desc)) {
     $ukeys = $table_desc['unique keys'];
-    $new_values = array();
-    $new_columns = array();
-    $uq_sname = "uq_" . $table . "_";
 
-    // include the primary key in the results returned
-    $has_pkey = 0;
-    if (array_key_exists('primary key', $table_desc)){
-      $has_pkey = 1;
-      $pkeys = $table_desc['primary key'];
-      foreach ($pkeys as $index => $key) {
-        array_push($new_columns, $key);
-      }
-    }
-    // iterate through the unique fields and reset the values and columns
+    // iterate through the unique constraints and reset the values and columns
     // arrays to only include these fields
     foreach ($ukeys as $cname => $fields) {
+      $new_values = array();
+      $new_columns = array();
+      $new_options = array();
+      $uq_sname = "uq_" . $table . "_";
+      $has_pkey = 0;
+      
+      
+      // include the primary key in the results returned
+	    if (array_key_exists('primary key', $table_desc)){
+	      $has_pkey = 1;
+	      $pkeys = $table_desc['primary key'];
+	      foreach ($pkeys as $index => $key) {
+	        array_push($new_columns, $key);
+	      }
+	    }
+	    
       foreach ($fields as $field) {
         if (array_key_exists($field, $values)) {
           $new_values[$field] = $values[$field];
           $uq_sname .= substr($field, 0, 2);
           // if there is no primary key then use the unique contraint fields
           if (!$has_pkey) {
-            array_push($new_columns,$field);
+            array_push($new_columns, $field);
           }
         }
-        elseif (array_key_exists('default',$table_desc['fields'][$field])) {
+        elseif (array_key_exists('default', $table_desc['fields'][$field])) {
           $new_values[$field] = $table_desc['fields'][$field]['default'];
           $uq_sname .= substr($field, 0, 2);
           if (!$has_pkey){
-            array_push($new_columns,$field);
+            array_push($new_columns, $field);
           }
         }
         else {
           return FALSE;
         }
       }
+      $new_options['statement_name'] = $uq_sname;
+      $results = tripal_core_chado_select($table, $new_columns, $new_values, $new_options);
+      // if we have a duplicate record then return the results
+			if (count($results) > 0) {
+        return $results;
+      } 
     }
-    // reset the values and columns
-    $values = $new_values;
-    $columns = $new_columns;
-
-    // set the new statement name
-    $options['statement_name'] = $uq_sname;
+    return FALSE;
   }
 
-
   foreach ($values as $field => $value) {
     $select[] = $field;
     if (is_array($value)) {
@@ -1183,7 +1181,6 @@ function tripal_core_chado_select($table, $columns, $values, $options = NULL) {
       $sql = drupal_substr($sql, 0, -2);  // get rid of the trailing ', '
       $psql = drupal_substr($psql, 0, -2);  // get rid of the trailing ', '
     }
-
     // finish constructing the prepared SQL statement
     $psql =  "PREPARE " . $options['statement_name'] . " (" . implode(', ', $idatatypes) . ") AS " . $psql;
 
@@ -1213,8 +1210,8 @@ function tripal_core_chado_select($table, $columns, $values, $options = NULL) {
   }
   else {
     $resource = chado_query($sql, $args);
-  }
-
+  } 
+  
   // format results into an array
   $results = array();
   while ($r = db_fetch_object($resource)) {

+ 2 - 2
tripal_views/views/handlers/tripal_views_handler_filter_select_string.inc

@@ -185,12 +185,12 @@ class tripal_views_handler_filter_select_string extends chado_views_handler_filt
 
     // filter the aggregates
     if ($this->options['agg']['aggregates_with']) {
-      $this::query_restrict_curr_table_records();
+      $this->query_restrict_curr_table_records();
     }
 
     // filter the base table
     if ($this->options['agg']['records_with']) {
-      $this::query_restrict_base_records();
+      $this->query_restrict_base_records();
     }