Browse Source

Added support for Tripal variables by adding a new API. Added limit and offset to chado_select_record()

Ficklin 10 years ago
parent
commit
a5feceb743

+ 26 - 2
tripal_core/api/tripal_core.chado_nodes.api.inc

@@ -455,8 +455,32 @@ function chado_node_sync_form_submit($form, $form_state) {
 }
 
 /**
- * Actual Sync Function. Works on a group of records
- *
+ * Generic function for syncing records in Chado with Drupal nodes.
+ * 
+ * @param $base_table
+ *   The name of the Chado table containing the record that should be synced
+ * @param $max_sync
+ *   Optional: A numeric value to indicate the maximum number of records to sync. 
+ * @param $organism_id
+ *   Optional: Limit the list of records to be synced to only those that
+ *   are associated with this organism_id. If the record is not assocaited
+ *   with an organism then this field is not needed.
+ * @param $types
+ *   Optional: Limit the list of records to be synced to only those that
+ *   match the types listed in this array. 
+ * @param $ids
+ *   Optional:  Limit the list of records to bye synced to only those whose
+ *   primary key value matches the ID provided in this array.
+ * @param $linking_table
+ *   Optional: Tripal maintains "linking" tables in the Drupal schema
+ *   to link Drupal nodes with Chado records.  By default these tables
+ *   are named as 'chado_' . $base_table.  But if for some reason the
+ *   linking table is not named in this way then it can be provided by this
+ *   argument.
+ * @param $job_id
+ *   Optional. Used by the Trpial Jobs system when running this function
+ *   as a job. It is not needed othewise.
+ * 
  * @ingroup tripal_chado_node_api
  */
 function chado_node_sync_records($base_table, $max_sync = FALSE, $organism_id = FALSE,

+ 11 - 1
tripal_core/api/tripal_core.chado_query.api.inc

@@ -929,6 +929,8 @@ function chado_delete_record($table, $match, $options = NULL) {
  *     unique integer to differentiate between pagers when more than one
  *     appear on a page.  The 'element' should start with zero and increment by
  *     one for each pager.
+ *  -limit:  Specifies the number of records to return.
+ *  -offset:  Indicates the number of records to skip before returning records.
  *
  * @return
  *  An array of results, FALSE if the query was not executed
@@ -1339,7 +1341,7 @@ function chado_select_record($table, $columns, $values, $options = NULL) {
     $sql = drupal_substr($sql, 0, -4);  // get rid of the trailing 'AND '
   } // end if (empty($where)){ } else {
 
-  // Finally add any ordering of the results to the SQL statement.
+  // Add any ordering of the results to the SQL statement.
   if (count($options['order_by']) > 0) {
     $sql .= " ORDER BY ";
     foreach ($options['order_by'] as $field => $dir) {
@@ -1347,6 +1349,14 @@ function chado_select_record($table, $columns, $values, $options = NULL) {
     }
     $sql = drupal_substr($sql, 0, -2);  // get rid of the trailing ', '
   }
+  
+  // Limit the records returned
+  if (array_key_exists('limit', $options) and is_numeric($options['limit'])) {
+    $sql .= " LIMIT " . $options['limit'];
+    if (array_key_exists('offset', $options) and is_numeric($options['offset'])) {
+      $sql .= " OFFSET " . $options['offset'];
+    }
+  }
 
   // if the caller has requested the SQL rather than the results then do so.
   if ($options['return_sql'] == TRUE) {

+ 220 - 0
tripal_core/api/tripal_core.tripal_variables.api.inc

@@ -0,0 +1,220 @@
+<?php
+/**
+ * @file
+ * Provides an application programming interface (API) for managing variables 
+ * associated with Tripal managed Drupal nodes/
+ */
+
+/**
+ * @defgroup tripal_variables_api Tripal Variables API
+ * @ingroup tripal_core_api
+ * @{
+ * Provides an application programming interface (API) for managing variables 
+ * associated with Tripal managed Drupal nodes. The Tripal Variables API 
+ * supports storing any type of variable such as a property or setting that 
+ * should be associated with a Tripal managed Drupal node.  Variables are
+ * meant to store non-biological information only. All biological data should be 
+ * housed in the Chado tables. Be aware that any data stored as a Tripal 
+ * Variable will not be made visible through services such as Tripal Web 
+ * Services and therefore can be a good place to hide application specific 
+ * settings
+ * @}
+ *
+ */
+
+/**
+ * Adds a new variable name.
+ * 
+ * @param $name
+ *   The name of the variable
+ * @param $description
+ *   The description for the variable
+ * @return 
+ *   A record object containg the variable that was added if successful. 
+ */
+function tripal_insert_variable($name, $description) {
+  $name = trim($name);
+  if (!$name) {
+    tripal_report_error('tripal_core', TRIPAL_ERROR,
+        'Must have a variable name when adding a new Tripal Variable.', array());
+    return NULL;
+  }
+  if (!$description) {
+    tripal_report_error('tripal_core', TRIPAL_ERROR,
+        'Must have a description when adding a new Tripal Variable.', array());
+    return NULL;
+  }
+  
+  // Make sure the variable is not a duplicate. If so, then just select
+  // it and return the variable_id
+  $variable = tripal_get_variable($name);
+  if ($variable) {
+    return $variable;
+  }
+  else {
+    db_insert('tripal_variables')
+      ->fields(array(
+        'name' => $name,
+        'description' => $description,
+      ))
+      ->execute();
+    return tripal_get_variable($name);
+  }
+}
+
+/**
+ * Retrieves the variable name record.
+ * 
+ * @param $name
+ *   The name of the variable to retrieve
+ * @return 
+ *   A record object containg the variable.
+ */
+function tripal_get_variable($name) {
+  return db_select('tripal_variables', 'v')
+    ->fields('v')
+    ->condition('name', $name)
+    ->execute()
+    ->fetchObject();
+}
+
+/**
+ * Associates a variable and it's value to a node.
+ * 
+ * If a variable is already associated more with a node then the rank value
+ * is used to differentiate them.  By default the rank is set to 0 and can
+ * be manually set by using the $rank argument.  But, if left unspecified
+ * the next available rank will automatically be used.
+ * 
+ * If the variable does not exist then it will be added automatically to 
+ * prevent errors. However, modules developers should always add their 
+ * variables first before using. If the variable already exists then it
+ * will simply be re-used. 
+ * 
+ * @param $nid
+ *   The node ID.
+ * @param $name
+ *   The name of the variable to associated with the node.
+ * @param $value
+ *   The value of the variable.
+ * @param $rank
+ *   The rank of the value. Default to zero.  
+ * 
+ * @return TRUE|FALSE
+ *   Returns TRUE if the variable was associated with the node and false if 
+ *   a failure occured.
+ */
+function tripal_add_node_variable($nid, $name, $value, $rank = 0) {
+  
+  // Make sure the variable exists. To prevent unwanted errors from 
+  // umet dependencies (e.g. modules using other modules' variables) the variable
+  // will be created automatically if it is missing.
+  $variable = tripal_get_variable($name);
+  if (!$variable) {
+    $variable = tripal_insert_variable($name, "Added automatically. Please describe this variable.");
+  }
+  
+  // Is the variable already associated with this node? If so, then find the
+  // next avilable rank. If the $update_existing variable is true then just
+  // update the record.
+  $values = tripal_get_node_variables($nid, $name);
+  if (count($values) > 0) {
+    // Get the max rank and increment the rank to the next highest value.
+    $max_rank = 0;
+    foreach ($values as $value) {
+      // If the user has specified a rank then we want ot honor that. If the
+      // rank is already used then don't continue.
+      if ($rank > 0 and $rank == $value->rank) {
+        tripal_report_error('tripal_core', TRIPAL_ERROR,
+            "The rank for the term, '$term', is already used for node $nid. " .
+            "Cannot add the variable.", array());
+        return FALSE;
+      }
+      if ($value->rank > $max_rank) {
+        $max_rank = $value->rank;
+      }
+    }
+    $rank = $max_rank++;
+  }
+  
+  // Add the new variable.
+  $node_variable_id = db_insert('tripal_node_variables')
+    ->fields(array(
+      'variable_id' => $variable->variable_id,
+      'nid' => $nid,
+      'value' => $value,
+      'rank' => $rank
+     ))
+     ->execute();
+  return $node_variable_id;
+}
+ 
+/**
+ * Returns one or more variables assigned to a node.
+ * 
+ * An array is returned containing an object for each variable assigned 
+ * to a term that matches the criteria.  If a name and rank are provided then
+ * the variables returned must match.
+ * 
+ * @param $nid
+ *   The node ID
+ * @param $name
+ *   Optional.  The name of the variable.
+ * @param $rank
+ *   Optional.  The rank of the variable to retreive.
+ * @return
+ *   An array of variable objects.
+ */
+function tripal_get_node_variables($nid, $name = '', $rank = '') {
+  $variables = array();
+  if (!$nid) {
+    return $variables;
+  }
+  $query = db_select('tripal_node_variables', 'tnv')
+    ->fields('tnv')
+    ->condition('nid', $nid, '=');
+  if ($name) {
+    $variable = tripal_get_variable($name);
+    $query->condition('variable_id', $variable->variable_id, '=');
+  }
+  if ($rank) {
+    $query->condition('rank', $rank, '=');
+  }
+  $results = $query->execute();
+  
+  // Build the  variables array and return it.
+  while($variable = $results->fetchObject()) {
+    $variables[] = $variable;
+  }
+  return $variables;
+}
+
+/**
+ * Removes variables assigned to a node.
+ * 
+ * @param $nid
+ *   The node ID
+ * @param $name
+ *   Optional.  The name of the variable.
+ * @param $rank
+ *   Optional.  The rank of the variable to retreive.
+ *   
+ * @return 
+ *   Return TRUE if deletion is successful, FALSE otherwise.
+ */
+function tripal_delete_node_variables($nid, $name = '', $rank = '') {
+  if (!$nid) {
+    return FALSE;
+  }
+
+  $query = db_delete('tripal_node_variables')
+    ->condition('nid', $nid, '=');
+  if ($name) {
+    $variable = tripal_get_variable($name);
+    $query->condition('variable_id', $variable->variable_id, '=');
+  }
+  if ($rank) {
+    $query->condition('rank', $rank, '=');
+  }
+  return $query->execute();
+}

+ 130 - 11
tripal_core/tripal_core.install

@@ -84,23 +84,27 @@ function tripal_core_get_schemas() {
   $schema = array();
 
   // get all the various schema parts and join them together
-  $temp = tripal_core_jobs_schema();
+  $temp = tripal_core_get_jobs_schema();
   foreach ($temp as $table => $arr) {
     $schema[$table] = $arr;
   }
-  $temp = tripal_core_mviews_schema();
+  $temp = tripal_core_get_mviews_schema();
   foreach ($temp as $table => $arr) {
     $schema[$table] = $arr;
   }
-  $temp = tripal_core_custom_tables_schema();
+  $temp = tripal_core_get_custom_tables_schema();
   foreach ($temp as $table => $arr) {
     $schema[$table] = $arr;
   }
-  $temp = tripal_core_tripal_token_schema();
+  $temp = tripal_core_get_tripal_token_schema();
   foreach ($temp as $table => $arr) {
     $schema[$table] = $arr;
   }
-  $temp = tripal_core_tripal_toc_schema();
+  $temp = tripal_core_get_tripal_toc_schema();
+  foreach ($temp as $table => $arr) {
+    $schema[$table] = $arr;
+  }
+  $temp = tripal_core_get_tripal_vars_schema();
   foreach ($temp as $table => $arr) {
     $schema[$table] = $arr;
   }
@@ -114,7 +118,7 @@ function tripal_core_get_schemas() {
  *
  * @ingroup tripal_core
  */
-function tripal_core_mviews_schema() {
+function tripal_core_get_mviews_schema() {
   $schema = array();
 
   $schema['tripal_mviews'] = array(
@@ -201,7 +205,7 @@ function tripal_core_mviews_schema() {
  *
  * @ingroup tripal_core
  */
-function tripal_core_jobs_schema() {
+function tripal_core_get_jobs_schema() {
   $schema = array();
   $schema['tripal_jobs'] = array(
     'fields' => array(
@@ -312,7 +316,7 @@ function tripal_core_jobs_schema() {
  *
  * @ingroup tripal_core
  */
-function tripal_core_custom_tables_schema() {
+function tripal_core_get_custom_tables_schema() {
   $schema = array();
   $schema['tripal_custom_tables'] = array(
     'fields' => array(
@@ -352,7 +356,7 @@ function tripal_core_custom_tables_schema() {
   return $schema;
 }
 
-function tripal_core_tripal_token_schema() {
+function tripal_core_get_tripal_token_schema() {
   $schema = array();
   $schema['tripal_token_formats'] = array(
     'fields' => array(
@@ -393,7 +397,7 @@ function tripal_core_tripal_token_schema() {
  * 
  * 
  */
-function tripal_core_tripal_toc_schema() {
+function tripal_core_get_tripal_toc_schema() {
   $schema = array();
   $schema['tripal_toc'] = array(
     'fields' => array(
@@ -445,6 +449,105 @@ function tripal_core_tripal_toc_schema() {
   return $schema;
 }
 
+/**
+ * 
+ */
+function tripal_core_get_tripal_vars_schema() {
+  $schema = array();
+  $schema['tripal_variables'] = array(
+    'description' => 'This table houses a list of unique variable names that ' .
+      'can be used in the tripal_node_variables table.',
+    'fields' => array(
+      'variable_id' => array (
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'name' => array(
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+      ),
+      'description' => array(
+        'type' => 'text',
+        'not null' => TRUE,
+      ),
+    ),
+    'primary key' => array (
+        0 => 'variable_id',
+    ),
+    'unique keys' => array (
+      'tripal_variables_c1' => array (
+        0 => 'name',
+      ),
+    ),
+    'indexes' => array (
+      'tripal_variable_names_idx1' => array (
+        0 => 'variable_id',
+      ),
+    ),
+  );
+  
+  $schema['tripal_node_variables'] = array(
+    'description' => 'This table is used for storing any type of variable such as ' .
+      'a property or setting that should be associated with a Tripal managed Drupal node.  This table is '.
+      'meant to store non-biological information only. All biological data should be housed ' .
+      'in the Chado tables. Be aware that any data stored here will not be made visible ' .
+      'through services such as Tripal Web Services and therefore can be a good place to ' .
+      'hide application specific settings.',
+    'fields' => array (
+      'node_variable_id' => array (
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'nid' => array (
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'variable_id' => array (
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array (
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array (
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'primary key' => array (
+      0 => 'node_variable_id',
+    ),
+    'unique keys' => array (
+      'tripal_node_variables_c1' => array (
+        0 => 'nid',
+        1 => 'variable_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array (
+      'tripal_node_variables_idx1' => array (
+        0 => 'node_variable_id',
+      ),
+      'tripal_node_variables_idx2' => array (
+        0 => 'variable_id',
+      ),
+    ),
+    'foreign keys' => array (
+      'tripal_terms' => array (
+        'table' => 'tripal_variables',
+        'columns' => array (
+          'variable_id' => 'variable_id',
+        ),
+      ),
+    ),
+  );
+  
+  return $schema;
+}
+
 /**
  * Adds an mview_id column to the tripal_custom_tables table and makes an assocation between the mview and the custom table
  *
@@ -545,5 +648,21 @@ function tripal_core_update_7203() {
     throw new DrupalUpdateException('Could not add tripal_toc table: '. $error);
     
   }
-  
+}
+
+/**
+ * Adds the tripal_variable_terms and a tripal_node_variables tables
+ */
+function tripal_core_update_7204() {
+  try {
+    $schema = drupal_get_schema_unprocessed('tripal_core', 'tripal_variables');
+    db_create_table('tripal_variables', $schema);
+    $schema = drupal_get_schema_unprocessed('tripal_core', 'tripal_node_variables');
+    db_create_table('tripal_node_variables', $schema);
+  }
+  catch (Exception $e) {
+    $error = $e->getMessage();
+    throw new DrupalUpdateException('Could not add new tables table: '. $error);
+
+  }
 }

+ 1 - 0
tripal_core/tripal_core.module

@@ -33,6 +33,7 @@ require_once 'api/tripal_core.mviews.api.inc';
 require_once 'api/tripal_core.files.api.inc';
 require_once 'api/tripal_core.jobs.api.inc';
 require_once 'api/tripal_core.tripal.api.inc';
+require_once 'api/tripal_core.tripal_variables.api.inc';
 
 require_once 'api/tripal_core.DEPRECATED.inc';
 

+ 4 - 0
tripal_organism/api/tripal_organism.api.inc

@@ -182,6 +182,10 @@ function tripal_get_organism_select_options($syncd_only = TRUE) {
  */
 function tripal_get_organism_image_url($organism) {
   $url = '';
+  
+  if (!is_object($organism)) {
+    return NULL;
+  }
 
   // Get the organism's node
   $nid = chado_get_nid_from_id('organism', $organism->organism_id);