Browse Source

Merge branch '7.x-2.x' of git.drupal.org:project/tripal into 7.x-2.x

Stephen Ficklin 9 years ago
parent
commit
0bd6d37113

+ 156 - 29
tripal_core/api/tripal_core.chado_nodes.api.inc

@@ -133,36 +133,36 @@ function chado_node_get_base_table($content_type, $module = FALSE) {
 
 }
 
-/** 
+/**
  * @section
  * Common Functionality for Properties, Dbxrefs and relationships chado node API
  */
 
 /**
  * Validate the Triggering element from a node form.
- * 
+ *
  * We are going to inspect the post to determine what PHP knows is the triggering
  * element and if it doesn't agree with Drupal then we are actually going to
  * change it in Drupal.
- * 
+ *
  * This fixes an obscure bug triggered when a property is added and then
  * a relationship removed, Drupal thinks the first property remove button was
  * clicked and instead removes a property (not a relationship) and renders the new
  * property table in the relationship table page space.
- * 
+ *
  * NOTE: Many Drupal issues state that this problem is solved if the #name
  * of the button is unique (which it is in our case) but we are still experiencing
  * incorrectly determined triggering elements so we need to handle it ourselves.
  */
 function chado_validate_node_form_triggering_element($form, &$form_state) {
-  
+
   // We are going to inspect the post to determine what PHP knows is the triggering
   // element and if it doesn't agree with Drupal then we are actually going to
   // change it in Drupal.
   if ($_POST['_triggering_element_name'] != $form_state['triggering_element']['#name']) {
     $form_state['triggering_element']['#name'] = $_POST['_triggering_element_name'];
   }
-  
+
 }
 
 /**
@@ -221,7 +221,7 @@ function chado_add_node_form_subtables_add_button_submit($form, &$form_state) {
         break;
     }
   }
-  
+
   // This is needed to ensure the form builder function is called for the node
   // form in order for any of these changes to be seen.
   $form_state['rebuild'] = TRUE;
@@ -230,28 +230,28 @@ function chado_add_node_form_subtables_add_button_submit($form, &$form_state) {
 /**
  * Validate Removing Subtables entries from the node forms.
  * Supported subtables: Properties, Relationships, Additional DBxrefs.
- * 
+ *
  * Since Removing isn't associated with any user input the only thing we
  * need to validate is that Drupal has determined the triggering element correctly.
  * That said, we will call each subtables associated validate function just incase
  * there is some case-specific validation we do not know of or have not anticipated.
- * 
+ *
  * @param array $form
  * @param array $form_state
  */
 function chado_add_node_form_subtables_remove_button_validate($form, &$form_state) {
- 
+
   // We need to validate the trigerring element since Drupal has known
   // issues determining this correctly when there are multiple buttons
   // with the same label.
   chado_validate_node_form_triggering_element($form, $form_state);
-  
+
   // Based on triggering element call the correct validation function
   // ASUMPTION #1: each of the buttons must have property, dbxref or relationship
   // as the first part of the #name to uniquely identify the subsection.
   if (preg_match('/^([a-z]+).*/', $form_state['triggering_element']['#name'], $matches)) {
     $subsection = $matches[1];
-    
+
       switch($subsection) {
       case 'properties':
         chado_add_node_form_properties_remove_button_validate($form, $form_state);
@@ -306,18 +306,18 @@ function chado_add_node_form_subtables_remove_button_submit($form, &$form_state)
  * @ingroup tripal_core
  */
 function chado_add_node_form_subtable_ajax_update($form, &$form_state) {
-  
+
   // We need to validate the trigerring element since Drupal has known
   // issues determining this correctly when there are multiple buttons
   // with the same label.
   chado_validate_node_form_triggering_element($form, $form_state);
-  
+
   // Based on triggering element render the correct part of the form.
   // ASUMPTION: each of the buttons must have property, dbxref or relationship
   // as the first part of the #name to uniquely identify the subsection.
   if (preg_match('/^([a-z]+).*/', $form_state['triggering_element']['#name'], $matches)) {
     $subsection = $matches[1];
-    
+
     switch($subsection) {
       case 'properties':
         return $form['properties']['property_table'];
@@ -561,7 +561,13 @@ function chado_node_sync_form($form, &$form_state) {
         "\"orphaned\".  This can occur if a node in Drupal is " .
         "deleted but the corresponding chado records is not and/or vice " .
         "versa. Click the button below to resolve these discrepancies.</p>"),
-    '#weight' => 1,
+    '#weight' => -10,
+  );
+  $form['cleanup']['cleanup_batch_size'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Batch Size'),
+      '#description' => t('The number of records to analyze together in a batch. If you are having memory issues you might want to decrease this number.'),
+      '#default_value' => variable_get('chado_node_api_cleanup_batch_size', 25000),
   );
   $form['cleanup']['button'] = array(
     '#type' => 'submit',
@@ -578,6 +584,26 @@ function chado_node_sync_form($form, &$form_state) {
   return $form;
 }
 
+/**
+ * Generic Sync Form Validate
+ *
+ * @ingroup tripal_core
+ */
+function chado_node_sync_form_validate($form, &$form_state) {
+
+  if (empty($form_state['values']['cleanup_batch_size'])) {
+    $form_state['values']['cleanup_batch_size'] = 25000;
+    drupal_set_message('You entered a Batch Size of 0 for Cleaning-up orphaned nodes. Since this is not valid, we reset it to the default of 25,000.', 'warning');
+  }
+  elseif (!is_numeric($form_state['values']['cleanup_batch_size'])) {
+    form_set_error('cleanup_batch_size', 'The batch size must be a postitive whole number.');
+  }
+  else {
+    // Round the value just to make sure.
+    $form_state['values']['cleanup_batch_size'] = abs(round($form_state['values']['cleanup_batch_size']));
+  }
+}
+
 /**
  * Generic Sync Form Submit
  *
@@ -648,7 +674,8 @@ function chado_node_sync_form_submit($form, $form_state) {
   if (preg_match('/^Clean up orphaned/', $form_state['values']['op'])) {
     $module = $form_state['chado_node_api']['hook_prefix'];
     $base_table = $form_state['chado_node_api']['base_table'];
-    $job_args = array($base_table);
+    $job_args = array($base_table, $form_state['values']['cleanup_batch_size']);
+    variable_set('chado_node_api_cleanup_batch_size', $form_state['values']['cleanup_batch_size']);
     tripal_add_job($form_state['values']['op'], $module, 'chado_cleanup_orphaned_nodes', $job_args, $user->uid);
   }
 }
@@ -875,6 +902,48 @@ function chado_node_sync_records($base_table, $max_sync = FALSE, $organism_id =
   }
 }
 
+/**
+ * This function is a wrapper for the chado_cleanup_orphaned_nodes function.
+ * It breaks up the work of chado_cleanup_orphaned_nodes into smaller pieces
+ * that are more managable for servers that may  have low php memory settings.
+ *
+ * @param $table
+ *   The name of the table that corresonds to the node type we want to clean up.
+ * @param $nentries
+ *   The number of entries to parse at one time (ie: the batch size).
+ * @param $job_id
+ *   This should be the job id from the Tripal jobs system.  This function
+ *   will update the job status using the provided job ID.
+ *
+ * @ingroup tripal_chado_node_api
+ */
+function chado_cleanup_orphaned_nodes($table, $nentries = 25000, $job_id = NULL) {
+  $count = 0;
+
+  // Find the total number of entries in the table.
+  $dsql = "SELECT COUNT(*) FROM {node} WHERE type = 'chado_" . $table . "'";
+  $clsql= "SELECT COUNT(*) FROM {chado_" . $table . "}";
+
+  // Find the number nodes of type chado_$table and find the number of entries
+  // in chado_$table; keep the larger of the two numbers.
+  $ndat = db_query($dsql);
+  $temp = $ndat->fetchObject();
+  $count =  $temp->count;
+  $cdat = db_query($clsql);
+  $temp = $cdat->fetchObject();
+  if(count < $temp->count) {
+    $count =  $temp->count;
+  }
+
+  $m = ceil($count / $nentries);
+  for($i = 0; $i < $m; $i++) {
+    $offset = ($nentries*$i)+1;
+    chado_cleanup_orphaned_nodes_part($table, $job_id, $nentries, $offset);
+  }
+
+  return '';
+}
+
 /**
  * This function will delete Drupal nodes for any sync'ed table (e.g.
  * feature, organism, analysis, stock, library) if the chado record has been
@@ -888,25 +957,19 @@ function chado_node_sync_records($base_table, $max_sync = FALSE, $organism_id =
  *
  * @ingroup tripal_chado_node_api
  */
-function chado_cleanup_orphaned_nodes($table, $job_id = NULL) {
+function chado_cleanup_orphaned_nodes_part($table, $job_id = NULL, $nentries, $offset) {
   $count = 0;
 
+  // Change this variable to TRUE to print debugging values for memory leaks.
+  $debug_memory_leak = FALSE;
+
   // build the SQL statments needed to check if nodes point to valid analyses
-  $dsql = "SELECT * FROM {node} WHERE type = 'chado_" . $table . "' order by nid";
+  $dsql = "SELECT * FROM {node} WHERE type = 'chado_" . $table . "' ORDER BY nid LIMIT $nentries OFFSET $offset";
   $nsql = "SELECT * FROM {node} WHERE nid = :nid";
   $csql = "SELECT * FROM {chado_" . $table . "} WHERE nid = :nid ";
-  $clsql= "SELECT * FROM {chado_" . $table . "}";
+  $clsql= "SELECT * FROM {chado_" . $table . "} ORDER BY nid LIMIT $nentries OFFSET $offset";
   $lsql = "SELECT * FROM {" . $table . "} where " . $table . "_id = :" . $table . "_id ";
 
-  // load into nodes array
-  print "Getting nodes\n";
-  $nodes = array();
-  $res = db_query($dsql);
-  foreach ($res as $node) {
-    $nodes[$count] = $node;
-    $count++;
-  }
-
   // load the chado_$table into an array
   print "Getting chado_$table\n";
   $cnodes = array();
@@ -915,6 +978,14 @@ function chado_cleanup_orphaned_nodes($table, $job_id = NULL) {
     $cnodes[$count] = $node;
     $count++;
   }
+
+  // Free $res.
+  $mu = ($debug_memory_leak) ? memory_get_usage() : 0;
+  $res = NULL;
+  if ($debug_memory_leak) {
+    print "\tFreeing res: " . ($mu - memory_get_usage()) ." bytes\n";
+  }
+
   $interval = intval($count * 0.01);
   if ($interval < 1) {
     $interval = 1;
@@ -954,11 +1025,50 @@ function chado_cleanup_orphaned_nodes($table, $job_id = NULL) {
     }
     $i++;
   }
+
+  // Freeing up various resources: $cnodes, $node, $record, and $results.
+  $mu = ($debug_memory_leak) ? memory_get_usage() : 0;
+  $cnodes = NULL;
+  if ($debug_memory_leak) {
+    print "\tFreeing cnodes: " . ($mu - memory_get_usage()) ." bytes\n";
+  }
+  $mu = ($debug_memory_leak) ? memory_get_usage() : 0;
+  $results = NULL;
+  if ($debug_memory_leak) {
+    print "\tFreeing results: " . ($mu - memory_get_usage()) ." bytes\n";
+  }
+  $mu = ($debug_memory_leak) ? memory_get_usage() : 0;
+  $node = NULL;
+  if ($debug_memory_leak) {
+    print "\tFreeing node: " . ($mu - memory_get_usage()) ." bytes\n";
+  }
+  $mu = ($debug_memory_leak) ? memory_get_usage() : 0;
+  $record = NULL;
+  if ($debug_memory_leak) {
+    print "\tFreeing record: " . ($mu - memory_get_usage()) ." bytes\n";
+  }
+
   print "\t$deleted chado_$table entries missing either a node or chado entry.\n";
 
   // iterate through all of the nodes and delete those that don't
   // have a corresponding entry in chado_$table
   $deleted = 0;
+  // load into nodes array
+  print "Getting nodes\n";
+  $nodes = array();
+  $res = db_query($dsql);
+  foreach ($res as $node) {
+    $nodes[$count] = $node;
+    $count++;
+  }
+
+  // Free $res.
+  $mu = ($debug_memory_leak) ? memory_get_usage() : 0;
+  $res = NULL;
+  if ($debug_memory_leak) {
+    print "\tFreeing res:\n" . ($mu - memory_get_usage()) ." bytes\n";
+  }
+
   foreach ($nodes as $node) {
 
     // update the job status every 1% libraries
@@ -984,6 +1094,23 @@ function chado_cleanup_orphaned_nodes($table, $job_id = NULL) {
     }
     $i++;
   }
+  // // Freeing up various resources: $results, $link and $nodes
+  $mu = ($debug_memory_leak) ? memory_get_usage() : 0;
+  $results = NULL;
+  if ($debug_memory_leak) {
+    print "\tFreeing results: " . ($mu - memory_get_usage()) . " bytes\n";
+  }
+  $mu = ($debug_memory_leak) ? memory_get_usage() : 0;
+  $link = NULL;
+  if ($debug_memory_leak) {
+    print "\tFreeing link: " . ($mu - memory_get_usage()) . " bytes\n";
+  }
+  $mu = ($debug_memory_leak) ? memory_get_usage() : 0;
+  $nodes = NULL;
+  if ($debug_memory_leak) {
+    print "\tFreeing nodes: " . ($mu - memory_get_usage()) ." bytes\n";
+  }
+
   print "\t$deleted nodes did not have corresponding chado_$table entries.\n";
 
   return '';

+ 28 - 14
tripal_core/api/tripal_core.chado_nodes.relationships.api.inc

@@ -300,14 +300,14 @@ function chado_add_node_form_relationships(&$form, &$form_state, $details) {
     ),
   );
 
-  $instructions = 'Relationships should be read like a sentence ([subject] [type] 
-    [object]) in order to determine their direction and thus their meaning. When 
-    adding a relationship, it is easiest to first select the type of relationship you would 
+  $instructions = 'Relationships should be read like a sentence ([subject] [type]
+    [object]) in order to determine their direction and thus their meaning. When
+    adding a relationship, it is easiest to first select the type of relationship you would
     like to enter and then select whether the current %nodetype is the subject
-    or object (based on which "sentence" makes sense). Finally enter the other 
-    %nodetype in the remaining text box (making sure to select from the 
-    autocomplete drop-down) before clicking "Add". To remove incorrect relationships, click the 
-    "Remove" button. Note: you cannot edit previously added relationships 
+    or object (based on which "sentence" makes sense). Finally enter the other
+    %nodetype in the remaining text box (making sure to select from the
+    autocomplete drop-down) before clicking "Add". To remove incorrect relationships, click the
+    "Remove" button. Note: you cannot edit previously added relationships
     but instead need to remove and re-add them.';
   $form['relationships']['descrip'] = array(
     '#type' => 'item',
@@ -321,7 +321,8 @@ function chado_add_node_form_relationships(&$form, &$form_state, $details) {
     '#tree' => TRUE,
     '#prefix' => '<div id="tripal-generic-edit-relationships-table">',
     '#suffix' => '</div>',
-    '#theme' => 'chado_node_relationships_form_table'
+    '#theme' => 'chado_node_relationships_form_table',
+    '#weight' => 5
   );
 
   // Add defaults into form_state to be used elsewhere
@@ -420,13 +421,24 @@ function chado_add_node_form_relationships(&$form, &$form_state, $details) {
     if (array_key_exists($relationship->type_id, $type_options)) {
       $num_relationships++;
 
+      $type_class = str_replace(array(' ','_'), '-', $relationship->type_name);
+      $current_class = 'current-unknown';
+      if ($details['base_key_value']) {
+        if ($relationship->object_id == $details['base_key_value']) {
+          $current_class = 'current-object';
+        }
+        elseif ($relationship->subject_id == $details['base_key_value']) {
+          $current_class = 'current-subject';
+        }
+      }
+
       $form['relationships']['relationship_table'][$relationship->type_id]['#type'] = 'markup';
       $form['relationships']['relationship_table'][$relationship->type_id]['#type'] = '';
 
       $form['relationships']['relationship_table'][$relationship->type_id][$relationship->relationship_id]['#type'] = 'markup';
       $form['relationships']['relationship_table'][$relationship->type_id][$relationship->relationship_id]['#value'] = '';
       $form['relationships']['relationship_table'][$relationship->type_id][$relationship->relationship_id]['#attributes'] = array(
-        'class' => array('relationship', 'saved')
+        'class' => array('relationship', 'saved', $type_class, $current_class)
       );
 
       // Determine whether this relationship is unsaved or not.
@@ -434,7 +446,7 @@ function chado_add_node_form_relationships(&$form, &$form_state, $details) {
       // saved yet we will have entered a TEMP###.
       if (preg_match('/^TEMP/', $relationship->relationship_id)) {
         $form['relationships']['relationship_table'][$relationship->type_id][$relationship->relationship_id]['#attributes'] = array(
-          'class' => array('relationship', 'unsaved')
+          'class' => array('relationship', 'unsaved', $type_class, $current_class)
         );
       }
 
@@ -577,7 +589,8 @@ function chado_add_node_form_relationships(&$form, &$form_state, $details) {
 
   $form['relationships']['admin_message'] = array(
     '#type' => 'markup',
-    '#markup' => $tripal_message
+    '#markup' => $tripal_message,
+    '#weight' => 10
   );
 }
 
@@ -590,7 +603,7 @@ function chado_add_node_form_relationships(&$form, &$form_state, $details) {
 function chado_add_node_form_relationships_add_button_validate($form, &$form_state) {
 
   $details = unserialize($form_state['values']['relationship_table']['details']);
-  
+
   // First deal with autocomplete fields.
   // Extract the base_id assuming '(###) NAME FIELD'.
   if (!empty($form_state['values']['relationship_table']['new']['subject_name'])) {
@@ -630,8 +643,9 @@ function chado_add_node_form_relationships_add_button_validate($form, &$form_sta
     AND $form_state['values']['relationship_table']['new']['object_is_current']) {
 
     form_set_error('relationship_table][new][object_is_current', 'Only one member of the relationship may be
-      the current '.$details['nodetype'].'. This is specified by checking the "Current '.$details['nodetype'].'"
-      checkbox for either the subject or object.');
+      the current '.$details['nodetype'].' in order to avoid a circular relationship. If you really meant to
+      add a circular relationship then check the "Current '.$details['nodetype'].'" for one side of the
+      relationship and enter the current stock name via the autocomplete for the other side of the relationship.');
   }
   // If it was determined current via checkbox, we need to ensure the name
   // provided actually matches the current node.

+ 0 - 1
tripal_views/api/tripal_views.api.inc

@@ -650,7 +650,6 @@ function tripal_add_views_integration($defn_array, $setup_id = FALSE) {
     $view_record['setup_id'] = $setup_id;
   }
   if ($defn_array['type'] == 'mview') {
-    // D7 TODO: Check DBTNG changes work
     $mview = db_query("SELECT mview_id FROM {tripal_mviews} WHERE mv_table=:table", array(':table' => $defn_array['table']));
     $mview = $mview->fetchObject();
     $view_record['mview_id'] = $mview->mview_id;

+ 25 - 1
tripal_views/includes/tripal_views_integration.inc

@@ -31,6 +31,16 @@ function tripal_views_integrate_all_chado_tables() {
   // First integrate all of the Chado tables. Those that are base tables
   // get special treatment.
   $tables = chado_get_table_names(TRUE);
+
+  // Some chado tables might have been created via the Tripal Custom Tables
+  // or Tripal Materialized Views interfaces. We need to ensure that the
+  // corresponding mview_id and table_id are associated with these tables.
+  // @TODO: Add some way to show which integrations are for custom tables.
+  //$custom_tables = chado_get_custom_table_names();
+  $mview_tables = chado_get_mview_table_names();
+
+  // Hardcode a list of base tables since there isn't really a programatic way
+  // to determine which tables in the chado schema should be base tables.
   $base_tables = array(
     'acquisition', 'analysis', 'assay', 'biomaterial', 'contact', 'cv', 'cvterm',
     'db', 'dbxref', 'environment', 'expression', 'feature', 'featuremap', 'genotype',
@@ -39,15 +49,29 @@ function tripal_views_integrate_all_chado_tables() {
     'project', 'protocol', 'pub', 'stock', 'study', 'synonym'
   );
 
+  // For each chado table, generate an integration array, keeping the above
+  // details in mind, and save that integration with Tripal Views through the API.
   foreach ($tables as $tablename) {
     $priority = 10;
     if (!tripal_is_table_integrated($tablename, $priority)) {
-      if (in_array($tablename, $base_tables)) {
+
+      // Assuming that we have a default chado table, genereate an integration
+      // array describing it's Tripal Views integration.
+      if (in_array($tablename, $base_tables) OR in_array($tablename, $mview_tables)) {
         $table_integration_array = tripal_views_get_integration_array_for_chado_table($tablename, TRUE, $priority);
       }
       else {
         $table_integration_array = tripal_views_get_integration_array_for_chado_table($tablename, FALSE, $priority);
       }
+
+      // Check to see if this table is a Materialized view and if it is,
+      // treat it specially :).
+      if (in_array($tablename, $mview_tables)) {
+        $table_integration_array['type'] = 'mview';
+      }
+
+      // As long as we were able to generate an integration array,
+      // Integrate It!
       if ($table_integration_array) {
         tripal_add_views_integration($table_integration_array);
       }

+ 23 - 20
tripal_views/includes/tripal_views_integration_UI.inc

@@ -306,7 +306,7 @@ function tripal_views_integration_form($form, &$form_state) {
   $chado_tables = array_merge(array('Select'), $chado_tables);
   $default = '';
   if ($setup_id) {
-    $default = (!$setup_obj->mview_id) ? $setup_obj->table_name : '';
+    $default = ($setup_obj->table_name) ? $setup_obj->table_name : '';
   }
   $form['base_table_type']['table_name'] = array(
     '#title' => t('Chado/Custom Table'),
@@ -326,7 +326,6 @@ function tripal_views_integration_form($form, &$form_state) {
 
 
   // build the form element that lists the materialized views
-  // D7 TODO: Check DBTNG changes work
   $query = db_query("SELECT mview_id, name FROM {tripal_mviews} WHERE mv_schema is NULL or mv_schema = '' ORDER BY name");
   $mview_tables = array();
   $mview_tables['0'] = 'Select';
@@ -334,24 +333,29 @@ function tripal_views_integration_form($form, &$form_state) {
     $mview_tables[$mview->mview_id] = $mview->name;
   }
   $default = '';
-  if ($setup_id && isset($setup_obj->mview_id)) {
+  $legacy_mview = FALSE;
+  if ($setup_id && !empty($setup_obj->mview_id)) {
     $default = $setup_obj->mview_id;
   }
-  $form['base_table_type']['mview_id'] = array(
-    '#title' => t('Legacy Materialized View'),
-    '#type' => 'select',
-    '#options' => $mview_tables,
-    '#description' => 'Which materialized view to use.',
-    '#default_value' => $default,
-    '#ajax' => array(
-       //D6: 'path' => 'tripal/views-integration/ajax/view_setup_table',
-       'callback' => 'tripal_views_integration_ajax_view_setup_table',
-       'wrapper' => 'tripal-views-integration-form',
-       'effect' => 'fade',
-       'event' => 'change',
-       'method' => 'replace',
-    ),
-  );
+  if (isset($mview_tables[$setup_obj->mview_id])) {
+    $legacy_mview = TRUE;
+
+    $form['base_table_type']['mview_id'] = array(
+      '#title' => t('Legacy Materialized View'),
+      '#type' => 'select',
+      '#options' => $mview_tables,
+      '#description' => 'Which materialized view to use.',
+      '#default_value' => $default,
+      '#ajax' => array(
+         //D6: 'path' => 'tripal/views-integration/ajax/view_setup_table',
+         'callback' => 'tripal_views_integration_ajax_view_setup_table',
+         'wrapper' => 'tripal-views-integration-form',
+         'effect' => 'fade',
+         'event' => 'change',
+         'method' => 'replace',
+      ),
+    );
+  }
 
   $form['views_type'] = array(
     '#type' => 'fieldset',
@@ -470,8 +474,7 @@ function tripal_views_integration_form($form, &$form_state) {
     // get the columns in this materialized view.  They are separated by commas
     // where the first word is the column name and the rest is the type
     $columns = array();
-    if ($mview_id) {
-      // D7 TODO: Check DBTNG changes work
+    if ($legacy_mview) {
       $sql = "SELECT mv_specs FROM {tripal_mviews} WHERE mview_id = :id";
       $mview = db_query($sql, array(':id' => $mview_id));
       $mview = $mview->fetchObject();

+ 7 - 0
tripal_views/tripal_views.views.inc

@@ -165,6 +165,7 @@ function tripal_views_views_data() {
     // POPULATE THE BASE TABLE NAME AND FIELDS
     // If an $mview_id is given then get the materialized view info,
     // otherwise get the Chado table info
+    $legacy_mview = FALSE;
     if ($mview_id) {
 
       // get the base table name from the materialized view
@@ -174,6 +175,12 @@ function tripal_views_views_data() {
       $mview_table = $mview_table->fetchObject();
       $base_table = $mview_table->name;
 
+      if (!empty($mview_table->mv_specs)) {
+        $legacy_mview = TRUE;
+      }
+    }
+
+    if ($legacy_mview) {
       // get the columns in this materialized view.  They are separated by commas
       // where the first word is the column name and the rest is the type
       $columns = explode(",", $mview_table->mv_specs);