Преглед изворни кода

Merge pull request #1 from almasaeed2010/7.x-2.x

Add Execute Now Function to Tripal Jobs
Abdullah Almsaeed пре 8 година
родитељ
комит
66994a6d40
100 измењених фајлова са 37327 додато и 1948 уклоњено
  1. 0 0
      LICENSE.txt
  2. 4 4
      tripal_analysis/includes/tripal_analysis.chado_node.inc
  3. 1 1
      tripal_analysis/tripal_analysis.info
  4. 9 22
      tripal_analysis/tripal_analysis.install
  5. 1 1
      tripal_bulk_loader/tripal_bulk_loader.info
  6. 4 4
      tripal_bulk_loader/tripal_bulk_loader.module
  7. 1 1
      tripal_contact/includes/tripal_contact.chado_node.inc
  8. 1 1
      tripal_contact/tripal_contact.info
  9. 61 101
      tripal_contact/tripal_contact.install
  10. 219 0
      tripal_core/api/generate_chado_schema_file.php
  11. 0 161
      tripal_core/api/get_FKs.php
  12. 1 1
      tripal_core/api/tripal_core.DEPRECATED.api.inc
  13. 5 2
      tripal_core/api/tripal_core.chado_general.api.inc
  14. 14 16
      tripal_core/api/tripal_core.chado_nodes.api.inc
  15. 5 2
      tripal_core/api/tripal_core.chado_nodes.relationships.api.inc
  16. 121 11
      tripal_core/api/tripal_core.chado_nodes.title_and_path.api.inc
  17. 126 11
      tripal_core/api/tripal_core.chado_query.api.inc
  18. 119 14
      tripal_core/api/tripal_core.chado_schema.api.inc
  19. 162 74
      tripal_core/api/tripal_core.chado_variables.api.inc
  20. 4 2
      tripal_core/api/tripal_core.custom_tables.api.inc
  21. 2 2
      tripal_core/api/tripal_core.files.api.inc
  22. 45 14
      tripal_core/api/tripal_core.jobs.api.inc
  23. 1 1
      tripal_core/api/tripal_core.mviews.api.inc
  24. 14 14
      tripal_core/api/tripal_core.schema_v1.2.api.inc
  25. 18249 0
      tripal_core/api/tripal_core.schema_v1.3.api.inc
  26. 21 11
      tripal_core/api/tripal_core.tripal.api.inc
  27. 8835 0
      tripal_core/chado_schema/default_schema-1.2-1.3-diff.sql
  28. 2751 0
      tripal_core/chado_schema/default_schema-1.3.sql
  29. 3 207
      tripal_core/chado_schema/initialize-1.2.sql
  30. 32 0
      tripal_core/chado_schema/initialize-1.3.sql
  31. 515 120
      tripal_core/includes/tripal_core.chado_install.inc
  32. 1 1
      tripal_core/includes/tripal_core.custom_tables.inc
  33. 5 1
      tripal_core/includes/tripal_core.jobs.inc
  34. 439 0
      tripal_core/includes/tripal_core.search.inc
  35. 27 6
      tripal_core/includes/tripal_core.toc.inc
  36. 2 3
      tripal_core/tripal_core.info
  37. 177 4
      tripal_core/tripal_core.module
  38. 2 2
      tripal_core/tripal_core.views.inc
  39. 100 4
      tripal_core/tripal_core.views_default.inc
  40. 259 204
      tripal_cv/api/tripal_cv.api.inc
  41. 44 0
      tripal_cv/api/tripal_cv.schema.api.inc
  42. 236 0
      tripal_cv/files/legacy_ro.obo
  43. 1 5
      tripal_cv/includes/tripal_cv.cvterm_form.inc
  44. 4 18
      tripal_cv/includes/tripal_cv.obo_loader.inc
  45. 1 1
      tripal_cv/tripal_cv.info
  46. 51 8
      tripal_cv/tripal_cv.install
  47. 1 1
      tripal_cv/tripal_cv.module
  48. 8 6
      tripal_db/api/tripal_db.api.inc
  49. 1 1
      tripal_db/tripal_db.info
  50. 1 1
      tripal_db/tripal_db.views_default.inc
  51. 1 1
      tripal_example/includes/tripal_example.chado_node.inc
  52. 1 1
      tripal_example/tripal_example.info
  53. 158 153
      tripal_feature/api/tripal_feature.api.inc
  54. 5 9
      tripal_feature/includes/tripal_feature.chado_node.inc
  55. 43 26
      tripal_feature/includes/tripal_feature.fasta_loader.inc
  56. 94 17
      tripal_feature/includes/tripal_feature.gff_loader.inc
  57. 239 208
      tripal_feature/includes/tripal_feature.seq_extract.inc
  58. 18 20
      tripal_feature/theme/templates/tripal_feature_help.tpl.php
  59. 6 1
      tripal_feature/theme/templates/tripal_organism_feature_browser.tpl.php
  60. 6 1
      tripal_feature/theme/tripal_feature.theme.inc
  61. 10 3
      tripal_feature/tripal_feature.drush.inc
  62. 1 1
      tripal_feature/tripal_feature.info
  63. 2 0
      tripal_feature/tripal_feature.install
  64. 41 31
      tripal_feature/tripal_feature.module
  65. 2 2
      tripal_featuremap/includes/tripal_featuremap.chado_node.inc
  66. 23 18
      tripal_featuremap/theme/templates/tripal_feature_featurepos.tpl.php
  67. 27 22
      tripal_featuremap/theme/templates/tripal_featuremap_featurepos.tpl.php
  68. 1 1
      tripal_featuremap/tripal_featuremap.info
  69. 30 30
      tripal_featuremap/tripal_featuremap.install
  70. 38 33
      tripal_genetic/theme/templates/tripal_feature_genotypes.tpl.php
  71. 32 27
      tripal_genetic/theme/templates/tripal_stock_genotypes.tpl.php
  72. 1 1
      tripal_genetic/tripal_genetic.info
  73. 42 30
      tripal_library/includes/tripal_library.chado_node.inc
  74. 6 1
      tripal_library/theme/templates/tripal_library_features.tpl.php
  75. 1 1
      tripal_library/theme/templates/tripal_organism_libraries.tpl.php
  76. 1 1
      tripal_library/tripal_library.info
  77. 43 81
      tripal_library/tripal_library.install
  78. 35 30
      tripal_natural_diversity/theme/templates/tripal_feature_nd_genotypes.tpl.php
  79. 44 39
      tripal_natural_diversity/theme/templates/tripal_stock_nd_genotypes.tpl.php
  80. 41 36
      tripal_natural_diversity/theme/templates/tripal_stock_nd_phenotypes.tpl.php
  81. 1 1
      tripal_natural_diversity/tripal_natural_diversity.info
  82. 173 36
      tripal_organism/includes/tripal_organism.chado_node.inc
  83. 53 17
      tripal_organism/theme/templates/tripal_organism_base.tpl.php
  84. 1 1
      tripal_organism/tripal_organism.info
  85. 26 2
      tripal_organism/tripal_organism.install
  86. 1 1
      tripal_organism/tripal_organism.module
  87. 1 1
      tripal_phenotype/tripal_phenotype.info
  88. 528 0
      tripal_phylogeny/api/tripal_phylogeny.api.inc
  89. 331 0
      tripal_phylogeny/includes/parsers/tripal_phylogeny.newick_parser.inc
  90. 320 0
      tripal_phylogeny/includes/tripal_phylogeny.admin.inc
  91. 782 0
      tripal_phylogeny/includes/tripal_phylogeny.chado_node.inc
  92. 326 0
      tripal_phylogeny/includes/tripal_phylogeny.import_tree.inc
  93. 411 0
      tripal_phylogeny/includes/tripal_phylogeny.taxonomy.inc
  94. 0 0
      tripal_phylogeny/theme/css/tripal_phylogeny.css
  95. BIN
      tripal_phylogeny/theme/images/ajax-loader.gif
  96. 402 0
      tripal_phylogeny/theme/js/d3.phylogram.js
  97. 130 0
      tripal_phylogeny/theme/js/tripal_phylogeny.js
  98. 80 0
      tripal_phylogeny/theme/templates/tripal_phylogeny_analysis.tpl.php
  99. 72 0
      tripal_phylogeny/theme/templates/tripal_phylogeny_base.tpl.php
  100. 11 0
      tripal_phylogeny/theme/templates/tripal_phylogeny_help.tpl.php

+ 0 - 0
gpl-2.0.txt → LICENSE.txt


+ 4 - 4
tripal_analysis/includes/tripal_analysis.chado_node.inc

@@ -164,14 +164,14 @@ function chado_analysis_form($node, &$form_state) {
   );
   $form['program']= array(
     '#type' => 'textfield',
-    '#title' => t('Program, Pipeline Name or Method Name'),
+    '#title' => t('Program, Pipeline or Method Name'),
     '#required' => TRUE,
     '#default_value' => $program,
     '#description' => t("Program name, e.g. blastx, blastp, sim4, genscan. If the analysis was not derived from a software package, provide a very brief description of the pipeline or method."),
   );
   $form['programversion']= array(
     '#type' => 'textfield',
-    '#title' => t('Program, Pipeline  or Method version'),
+    '#title' => t('Program, Pipeline  or Method Version'),
     '#required' => TRUE,
     '#default_value' => $programversion,
     '#description' => t("Version description, e.g. TBLASTX 2.0MP-WashU [09-Nov-2000]. Enter 'n/a' if no version is available or applicable."),
@@ -441,7 +441,7 @@ function chado_analysis_insert($node) {
     );
     $analysis = chado_insert_record('analysis', $values);
     if (!$analysis) {
-      drupal_set_message(t('Unable to add analysis.', 'warning'));
+      drupal_set_message(t('Unable to add analysis.'), 'warning');
       tripal_report_error('tripal_analysis', TRIPAL_ERROR, 'Insert analysis: Unable to create analysis where values:%values',
         array('%values' => print_r($values, TRUE)));
       return;
@@ -618,7 +618,7 @@ function chado_analysis_load($nodes) {
  *
  * @ingroup tripal_analysis
  */
-function chado_analysis_node_access($node, $op, $account) {
+function tripal_analysis_node_access($node, $op, $account) {
 
   $node_type = $node;
   if (is_object($node)) {

+ 1 - 1
tripal_analysis/tripal_analysis.info

@@ -3,7 +3,7 @@ description = Supports the companalyses tables of Chado by providing pages for v
 core = 7.x
 project = tripal
 package = Tripal
-version = 7.x-2.1-beta2
+version = 7.x-2.1
 configure = admin/tripal/chado/tripal_analysis/configuration
 
 dependencies[] = tripal_core

+ 9 - 22
tripal_analysis/tripal_analysis.install

@@ -85,7 +85,7 @@ function tripal_analysis_create_analysisfeatureprop() {
 
   // Create analysisfeatureprop table in chado.  This is needed for Chado
   // version 1.11, the table exists in Chado 1.2.
-  if (!db_table_exists('chado.analysisfeatureprop')) {
+  if (!chado_table_exists('analysisfeatureprop')) {
     $sql = "
       CREATE TABLE {analysisfeatureprop} (
         analysisfeatureprop_id SERIAL PRIMARY KEY,
@@ -257,10 +257,12 @@ function tripal_analysis_add_mview_analysis_organism() {
     'description' => $comment,
     'fields' => array(
       'analysis_id' => array(
+        'size' => 'big',
         'type' => 'int',
         'not null' => TRUE,
       ),
       'organism_id' => array(
+        'size' => 'big',
         'type' => 'int',
         'not null' => TRUE,
       ),
@@ -298,28 +300,13 @@ function tripal_analysis_update_7200() {
   // site upgrade when the tripal_core module is disabled.
   module_load_include('module', 'tripal_core', 'tripal_core');
   tripal_core_import_api();
+  module_load_include('inc', 'tripal_cv', 'api/tripal_cv.api');
 
-  // set the analysis_property as default
+  // Set the analysis_property as default.
   try {
-    $cv_id = db_query("SELECT cv_id FROM chado.cv WHERE name = 'analysis_property'")->fetchField();
-
-    // Add in the default vocabulary.
-    // If a record already exists then don't change it.
-    $cdi = db_select('tripal_cv_defaults', 't')
-      ->fields('t', array('cv_default_id'))
-      ->condition('table_name', 'analysisprop')
-      ->condition('field_name', 'type_id')
-      ->execute()
-      ->fetchField();
-
-    if (!$cdi) {
-      db_insert('tripal_cv_defaults')
-        ->fields(array(
-          'table_name' => 'analysisprop',
-          'field_name' => 'type_id',
-          'cv_id' => $cv_id
-        ))
-        ->execute();
+    $is_set = tripal_get_default_cv('analysisprop', 'type_id');
+    if (!$is_set) {
+      tripal_set_default_cv('analysisprop','type_id', 'analysis_property');
     }
   }
   catch (\PDOException $e) {
@@ -422,4 +409,4 @@ function tripal_analysis_update_7201() {
       ->condition('name', $view_name)
       ->execute();
   }
-}
+}

+ 1 - 1
tripal_bulk_loader/tripal_bulk_loader.info

@@ -3,7 +3,7 @@ description = Supports the construction of templates for customizable uploading
 core = 7.x
 project = tripal
 package = Tripal
-version = 7.x-2.1-beta2
+version = 7.x-2.1
 
 dependencies[] = tripal_core
 dependencies[] = tripal_views

+ 4 - 4
tripal_bulk_loader/tripal_bulk_loader.module

@@ -404,8 +404,8 @@ function tripal_bulk_loader_progess_file_get_progress($job_id, $update_progress
     return (object) array();
   }
 
-  $num_lines = trim(`wc --lines < $filename`);
-  $num_records = trim(`grep -o "." $filename | wc --lines`);
+  $num_lines = trim(shell_exec('wc --lines < ' . escapeshellarg($filename)));
+  $num_records = trim(shell_exec('grep -o "." ' . escapeshellarg($filename) . ' | wc --lines'));
 
   $job = db_query("SELECT j.*, b.file, b.file_has_header, c.num as num_constant_sets
                               FROM {tripal_jobs} j
@@ -423,7 +423,7 @@ function tripal_bulk_loader_progess_file_get_progress($job_id, $update_progress
     if ($job->num_constant_sets != $num_constant_sets_loaded) {
 
       // total lines in input file
-      $total_lines = trim(`wc --lines < $job->file`);
+      $total_lines = trim(shell_exec('wc --lines < ' . escapeshellarg($job->file)));
       if ($job->file_has_header) {
         $total_lines--;
       }
@@ -460,7 +460,7 @@ function tripal_bulk_loader_progess_file_get_progress($job_id, $update_progress
  * @params $callback
  *   The callback passed into tripal_add_job()
  * @param $args
- *   The arguements passed into tripal_add_job()
+ *   The arguments passed into tripal_add_job()
  * @return
  *   An array where keys are the human readable headers describing each arguement
  *   and the value is the aguement passed in after formatting

+ 1 - 1
tripal_contact/includes/tripal_contact.chado_node.inc

@@ -317,7 +317,7 @@ function chado_contact_validate($node, $form, &$form_state) {
  *
  * @ingroup tripal_contact
  */
-function chado_contact_node_access($node, $op, $account ) {
+function tripal_contact_node_access($node, $op, $account ) {
 
   $node_type = $node;
   if (is_object($node)) {

+ 1 - 1
tripal_contact/tripal_contact.info

@@ -3,7 +3,7 @@ description = Supports the contact tables of Chado by providing pages for viewin
 core = 7.x
 project = tripal
 package = Tripal
-version = 7.x-2.1-beta2
+version = 7.x-2.1
 
 dependencies[] = tripal_core
 dependencies[] = tripal_views

+ 61 - 101
tripal_contact/tripal_contact.install

@@ -247,51 +247,31 @@ function tripal_contact_update_7200() {
   module_load_include('inc', 'tripal_cv', 'api/tripal_cv.api');
 
 
-  // add the contact_type CV
+  // Add the contact_type CV
   try {
-    $cv_id = db_query("SELECT cv_id FROM chado.cv WHERE name = 'tripal_contact'")->fetchField();
-    if (!$cv_id) {
-      // add the vocabulary
-      $cv_id = db_insert('chado.cv')
-      ->fields(array(
-        'name' => 'tripal_contact',
-        'definition' => 'A heirarchical set of terms for describing a contact. It is intended to be used as the default vocabularies in Tripal for contact types and contact properties.'
-      ))
-      ->execute();
-    }
-
-    // make this CV the defaults for the contact properties and contact types
-    // If a record already exists then don't change it.
-    $cdi = db_select('tripal_cv_defaults', 't')
-      ->fields('t', array('cv_default_id'))
-      ->condition('table_name', 'contact')
-      ->condition('field_name', 'type_id')
-      ->execute()
-      ->fetchField();
-    if (!$cdi) {
-      db_insert('tripal_cv_defaults')
-        ->fields(array(
-           'table_name' => 'contact',
-           'field_name' => 'type_id',
-           'cv_id' => $cv_id
-         ))
-        ->execute();
+    // First we add the cv.
+    // Notice that tripal_insert_cv() will only add it if it doesn't exist already.
+    $cv = tripal_insert_cv(
+      'tripal_contact',
+      'A heirarchical set of terms for describing a contact. It is intended to be used as the default vocabularies in Tripal for contact types and contact properties.'
+    );
+    if ($cv) {
+      $cv_id = $cv->cv_id;
+
+      // Set as Default CV for contact types.
+      $is_set = tripal_get_default_cv('contact', 'type_id');
+      if (!$is_set) {
+        tripal_set_default_cv('contact','type_id', 'tripal_contact', $cv_id);
+      }
+
+      // Set as Default CV for contact properties.
+      $is_set = tripal_get_default_cv('contactprop', 'type_id');
+      if (!$is_set) {
+        tripal_set_default_cv('contactprop','type_id', 'tripal_contact', $cv_id);
+      }
     }
-    $cdi = db_select('tripal_cv_defaults', 't')
-      ->fields('t', array('cv_default_id'))
-      ->condition('table_name', 'contactprop')
-      ->condition('field_name', 'type_id')
-      ->execute()
-      ->fetchField();
-
-    if (!$cdi) {
-      db_insert('tripal_cv_defaults')
-        ->fields(array(
-          'table_name' => 'contactprop',
-          'field_name' => 'type_id',
-          'cv_id' => $cv_id
-        ))
-        ->execute();
+    else {
+      throw new DrupalUpdateException('Failed to add tripal_contact vocabulary.');
     }
   }
   catch (\PDOException $e) {
@@ -300,70 +280,50 @@ function tripal_contact_update_7200() {
   }
 
 
-  // add the contact_relationship CV
+  // Add the contact_relationship CV
   try {
-    $cv_id = db_query("SELECT cv_id FROM chado.cv WHERE name = 'contact_relationship'")->fetchField();
-    if (!$cv_id) {
-      // add the vocabulary
-      $cv_id = db_insert('chado.cv')
-      ->fields(array(
-        'name' => 'contact_relationship',
-        'definition' => 'Contains types of relationships between contacts.'
-      ))
-      ->execute();
+    // First we add the cv.
+    // Notice that tripal_insert_cv() will only add it if it doesn't exist already.
+    $cv = tripal_insert_cv(
+      'contact_relationship',
+      'Contains types of relationships between contacts.'
+    );
+    if ($cv) {
+      $cv_id = $cv->cv_id;
+
+      // Set as Default CV for contact relationships.
+      $is_set = tripal_get_default_cv('contact_relationship', 'type_id');
+      if (!$is_set) {
+        tripal_set_default_cv('contact_relationship','type_id', 'contact_relationship', $cv_id);
+      }
     }
-    $cdi = db_select('tripal_cv_defaults', 't')
-      ->fields('t', array('cv_default_id'))
-      ->condition('table_name', 'contact_relationship')
-      ->condition('field_name', 'type_id')
-      ->execute()
-      ->fetchField();
-    if (!$cdi) {
-      // add the default
-      db_insert('tripal_cv_defaults')
-        ->fields(array(
-          'table_name' => 'contact_relationship',
-          'field_name' => 'type_id',
-          'cv_id' => $cv_id
-          ))
-        ->execute();
+    else {
+      throw new DrupalUpdateException('Failed to add contact_relationship vocabulary.');
     }
   }
   catch (\PDOException $e) {
     $error = $e->getMessage();
-    throw new DrupalUpdateException('Failed to add contact_type vocabulary: '. $error);
+    throw new DrupalUpdateException('Failed to add contact_relationship vocabulary: '. $error);
   }
 
-  // add the contact_type CV
+  // Add the contact_type CV (not default).
   try {
-    $cv_id = db_query("SELECT cv_id FROM chado.cv WHERE name = 'contact_type'")->fetchField();
-    if (!$cv_id) {
-      // add the vocabulary
-      $cv_id = db_insert('chado.cv')
-      ->fields(array(
-        'name' => 'contact_type',
-        'definition' => 'Contains types of contacts. This can be used if the tripal_contact vocabulary (which is default for contacts in Tripal) is not desired.'
-      ))
-      ->execute();
-    }
+    $cv = tripal_insert_cv(
+      'contact_type',
+      'Contains types of contacts. This can be used if the tripal_contact vocabulary (which is default for contacts in Tripal) is not desired.'
+    );
   }
   catch (\PDOException $e) {
     $error = $e->getMessage();
     throw new DrupalUpdateException('Failed to add contact_type vocabulary: '. $error);
   }
 
-  // add the contact_property CV
+  // Add the contact_property CV (not default).
   try {
-    $cv_id = db_query("SELECT cv_id FROM chado.cv WHERE name = 'contact_property'")->fetchField();
-    if (!$cv_id) {
-      // add the vocabulary
-      $cv_id = db_insert('chado.cv')
-      ->fields(array(
-        'name' => 'contact_property',
-        'definition' => 'Contains properties for contacts. This can be used if the tripal_contact vocabulary (which is default for contacts in Tripal) is not desired.'
-      ))
-      ->execute();
-    }
+    $cv = tripal_insert_cv(
+      'contact_property',
+      'Contains properties for contacts. This can be used if the tripal_contact vocabulary (which is default for contacts in Tripal) is not desired.'
+    );
   }
   catch (\PDOException $e) {
     $error = $e->getMessage();
@@ -407,25 +367,25 @@ function tripal_contact_update_7201() {
   try {
     $fkey_exists = db_query('SELECT TRUE FROM pg_constraint WHERE conname = :constraint', array(':constraint' => 'contactprop_type_id_fkey'))->fetchField();
     if ($fkey_exists) {
-      db_query('
-        ALTER TABLE chado.contactprop
+      chado_query('
+        ALTER TABLE {contactprop}
         DROP CONSTRAINT contactprop_type_id_fkey CASCADE
       ');
-      db_query('
-        ALTER TABLE chado.contactprop
+      chado_query('
+        ALTER TABLE {contactprop}
         DROP CONSTRAINT contactprop_contact_id_fkey CASCADE
       ');
     }
-    db_query('
-      ALTER TABLE chado.contactprop
+    chado_query('
+      ALTER TABLE {contactprop}
       ADD CONSTRAINT contactprop_type_id_fkey
-      FOREIGN KEY (type_id) REFERENCES chado.cvterm (cvterm_id)
+      FOREIGN KEY (type_id) REFERENCES {cvterm} (cvterm_id)
       ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED
     ');
-    db_query('
-      ALTER TABLE chado.contactprop
+    chado_query('
+      ALTER TABLE {contactprop}
       ADD CONSTRAINT contactprop_contact_id_fkey
-      FOREIGN KEY (contact_id) REFERENCES chado.contact (contact_id)
+      FOREIGN KEY (contact_id) REFERENCES {contact} (contact_id)
       ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED
     ');
   }

+ 219 - 0
tripal_core/api/generate_chado_schema_file.php

@@ -0,0 +1,219 @@
+<?php
+/**
+ * @file
+ *
+ * This script will generate the schema file for the Tripal API for an
+ * installation of Chado. To use the script you must install the version of
+ * Chado desired using Tripal. Next install and enable the 'schema' module
+ * from the Drupal module respository.  Finally, add a new 'chado'
+ * entry in the $databases variable of the settings.php file. For
+ * example:
+ *
+ * @code
+ *'chado' => array(
+    'default' => array(
+      'database' => 'd7x_t2x_c13',
+      'username' => 'chado',
+      'password' => 'testing123',
+      'host' => 'localhost',
+      'port' => '',
+      'driver' => 'pgsql',
+      'prefix' => '',
+    ),
+  ),
+ * @endcode
+ *
+ * This script requires a single argument (-v) which is the Chado version.
+ * Redirect output into a new file as desired.
+ *
+ * Example usage in drupal directory root:
+ *
+ * php ./sites/all/modules/tripal/tripal_core/api/generate_chado_schema_file.php -v 1.11 > \
+ *   ./sites/all/modules/tripal/tripal_core/api/tripal_core.schema_v1.11.api.inc.new
+ *
+ * php ./sites/all/modules/tripal/tripal_core/api/generate_chado_schema_file.php -v 1.2 > \
+ *   ./sites/all/modules/tripal/tripal_core/api/tripal_core.schema_v1.2.api.inc.new
+ *
+ * php ./sites/all/modules/tripal/tripal_core/api/generate_chado_schema_file.php -v 1.3 > \
+ *   ./sites/all/modules/tripal/tripal_core/api/tripal_core.schema_v1.3.api.inc.new
+ */
+
+$arguments = getopt("v:");
+
+if (isset($arguments['v'])) {
+  $drupal_base_url = parse_url('http://www.example.com');
+  $_SERVER['HTTP_HOST'] = $drupal_base_url['host'];
+  $_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'] = $_SERVER['PHP_SELF'];
+  $_SERVER['REMOTE_ADDR'] = NULL;
+  $_SERVER['REQUEST_METHOD'] = NULL;
+
+  define('DRUPAL_ROOT', getcwd());
+
+  require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
+  drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
+
+  $version = $arguments['v'];
+  $safe_version = preg_replace('/\./', '_', $version);
+
+  print("<?php \n" .
+    "/**\n" .
+    " * @file\n" .
+    " * Describes the chado tables in version $version\n" .
+    " */\n" .
+    "\n" .
+    "/**\n" .
+    " * @defgroup tripal_schema_v" . $safe_version . "_api Chado v" . $version . " Schema API\n" .
+    " * @ingroup tripal_chado_schema_api\n" .
+    " * @{\n" .
+    " * Provides an application programming interface (API) for describing Chado\n" .
+    " * tables. This API consists of a set of functions, one for each table in Chado.\n" .
+    " * Each function simply returns a Drupal style array that defines the table.\n" .
+    " *\n" .
+    " * Because Drupal does not handle foreign key (FK) relationships, which are\n" .
+    " * needed to for Tripal Views, they have been added to the schema defintitions\n" .
+    " * below.\n" .
+    " *\n" .
+    " * The functions provided in this documentation should not be called as is,\n" .
+    " * but if you need the Drupal-style array definition for any table, use the\n" .
+    " * following function call:\n" .
+    " *\n" .
+    " *   \$table_desc = chado_get_schema(\$table)\n" .
+    " *\n" .
+    " * where the variable \$table contains the name of the table you want to\n" .
+    " * retireve.  The chado_get_schema function determines the appropriate version\n" .
+    " * of Chado and uses the Drupal hook infrastructure to call the appropriate\n" .
+    " * hook function to retrieve the table schema.\n" .
+    " *\n" .
+    " * If you need to augment these schema definitions within your own module,\n" .
+    " * you need to implement the hook_chado_schema_v" . $safe_version . "_[table name]() hook where\n" .
+    " * [table name] is the name of the chado table whose schema definition you\n" .
+    " * want to augment.\n" .
+    " * @}\n" .
+    " */\n"
+  );
+
+  // The SQL for retreiving details about a table.
+  $fksql ="
+    SELECT
+        tc.constraint_name, tc.table_name, kcu.column_name,
+        ccu.table_name AS foreign_table_name,
+        ccu.column_name AS foreign_column_name
+    FROM
+        information_schema.table_constraints AS tc
+        JOIN information_schema.key_column_usage AS kcu ON tc.constraint_name = kcu.constraint_name
+        JOIN information_schema.constraint_column_usage AS ccu ON ccu.constraint_name = tc.constraint_name
+    WHERE constraint_type = 'FOREIGN KEY' AND tc.table_name=:table_name
+  ";
+
+  // Iterate through the tables of Chado and use the Schema module to
+  // generate a schema array for each table.
+  $sql = "
+    SELECT table_name
+    FROM information_schema.tables
+    WHERE
+      table_schema = 'chado' AND
+      table_type = 'BASE TABLE' AND
+      table_name NOT like 'tripal%'
+    ORDER BY table_name
+  ";
+  $result = db_query($sql);
+  $table_schemas = array();
+  $referring = array();
+  while ($table = $result->fetchField()) {
+
+    // Get the schema for each table.
+    $schema = schema_dbobject('chado')->inspect(NULL, $table);
+    $schema = $schema[$table];
+
+    // Get the foreign keys and add them to the array.
+    $fks = db_query($fksql, array(':table_name' => $table));
+    $schema['foreign keys'] = array();
+    foreach ($fks as $fk) {
+      $schema['foreign keys'][$fk->foreign_table_name]['table'] = $fk->foreign_table_name;
+      $schema['foreign keys'][$fk->foreign_table_name]['columns'][$fk->column_name] = $fk->foreign_column_name;
+      $reffering[$fk->foreign_table_name][] = $table;
+    }
+
+    // Add a table and description key to the top.
+    $schema = array('table' => $table) + $schema;
+    $schema = array('description' => '') + $schema;
+
+    // Fix the datetime fields and add a description field.
+    foreach ($schema['fields'] as $fname => $details) {
+      if ($schema['fields'][$fname]['type'] == "timestamp without time zone") {
+        $schema['fields'][$fname]['type'] = 'datetime';
+      }
+      $schema['fields'][$fname]['description'] = '';
+    }
+
+    // Remove the 'name' key.
+    unset($schema['name']);
+
+    $table_schemas[$table] = $schema;
+  }
+
+  // Now iterate through the tables now that we have all the referring info
+  // and generate the function strings.
+  foreach ($table_schemas as $table => $schema) {
+
+    $schema['referring_tables'] = array();
+    if (count($reffering[$table]) > 0) {
+      $schema['referring_tables'] = array_unique($reffering[$table]);
+    }
+
+    // Reformat the array to be more legible.
+    $arr = var_export($schema, 1);
+    // Move array( to previous line.
+    $arr = preg_replace("/\n\s+array/","array", $arr);
+    // Add indentation.
+    $arr = preg_replace("/\n/","\n  ", $arr);
+    $arr = preg_replace("/true/","TRUE", $arr);
+    $arr = preg_replace("/false/","FALSE", $arr);
+    $arr = preg_replace("/array \(/","array(", $arr);
+
+    print (
+      "/**\n" .
+      " * Implements hook_chado_schema_v" . $safe_version . "_" . $table . "()\n" .
+      " * \n" .
+      " * Purpose: To describe the structure of '$table' to tripal\n" .
+      " * @see chado_insert_record()\n" .
+      " * @see chado_update_record()\n" .
+      " * @see chado_select_record()\n" .
+      " * @see chado_generate_var()\n" .
+      " * @see chado_expan_var()\n" .
+      " *\n" .
+      " * @return\n" .
+      " *    An array describing the '$table' table\n" .
+      " *\n" .
+      " * @ingroup tripal_chado_v" . $version . "_schema_api\n" .
+      " *\n" .
+      " */\n" .
+      "function tripal_core_chado_schema_v" . $safe_version . "_" . $table . "() {\n" .
+      "  \$description = $arr; \n " .
+      "  return \$description;\n" .
+      "}\n"
+    );
+  }
+  // Finally add the tables function for this version.
+  $table_list = '';
+  foreach ($table_schemas as $table => $schema) {
+    $table_list .= "    '$table',\n";
+  }
+  print (
+    "/**\n" .
+    " * Lists the table names in the v" . $version . " chado schema\n" .
+    " *\n" .
+    " * @return\n" .
+    " *    An array containing all of the table names\n" .
+    " *\n" .
+    " * @ingroup tripal_chado_v" . $version . "_schema_api\n" .
+    " *\n" .
+    " */\n" .
+    "function tripal_core_chado_get_v" . $safe_version . "_tables() {\n" .
+    "  \$tables = array(\n" .
+    "$table_list" .
+    "  );\n" .
+    "  return \$tables;\n" .
+    "}\n"
+  );
+}

+ 0 - 161
tripal_core/api/get_FKs.php

@@ -1,161 +0,0 @@
-<?php
-/**
- * @file
- * This script will add FK relatinsions to an existing schema API array for each
- * Chado table.  It requires Chado is installed in a 'chado' schema of
- * the drupal database.  It also requires existing schema hooks for
- * version of Chado.  The goal is to use the output of this script to
- * update the existing schema hooks.  Redirect the output of this script to
- * a file and then replace the existing schema API include file (e.g.
- * tripal_core.schema_v1.2.api.inc).  Be sure to check it before replacing
- *
- * This script requires a single argument (-v) which is the Chado version.
- *
- * Example usage in drupal directory root:
- *
- * php ./sites/all/modules/tripal/tripal_core/api/get_FKs.php -v 1.11 > \
- *   ./sites/all/modules/tripal/tripal_core/apitripal_core.schema_v1.11.api.inc.new
- *
- * php ./sites/all/modules/tripal/tripal_core/api/get_FKs.php -v 1.2 > \
- *   ./sites/all/modules/tripal/tripal_core/api/tripal_core.schema_v1.2.api.inc.new
- */
-
-$arguments = getopt("v:");
-
-if (isset($arguments['v'])) {
-  $drupal_base_url = parse_url('http://www.example.com');
-  $_SERVER['HTTP_HOST'] = $drupal_base_url['host'];
-  $_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'] = $_SERVER['PHP_SELF'];
-  $_SERVER['REMOTE_ADDR'] = NULL;
-  $_SERVER['REQUEST_METHOD'] = NULL;
-
-  require_once 'includes/bootstrap.inc';
-  drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
-
-  $version = $arguments['v'];
-  get_chado_fk_relationships($version);
-}
-
-/**
- * Builds the FK relationships array in the database.
- * 
- * This function does the actual work of determining the foreign key 
- * relationships from the database and creating the schema file.
- */
-function get_chado_fk_relationships($version) {
-
-  // convert the version to a form suitable for function names
-  $v = $version;
-  $v = preg_replace("/\./","_",$v);
-
-  $tables = chado_get_table_names();
-  $sql ="
-    SELECT
-        tc.constraint_name, tc.table_name, kcu.column_name,
-        ccu.table_name AS foreign_table_name,
-        ccu.column_name AS foreign_column_name
-    FROM
-        information_schema.table_constraints AS tc
-        JOIN information_schema.key_column_usage AS kcu ON tc.constraint_name = kcu.constraint_name
-        JOIN information_schema.constraint_column_usage AS ccu ON ccu.constraint_name = tc.constraint_name
-    WHERE constraint_type = 'FOREIGN KEY' AND tc.table_name=:table_name
-  ";
-
-  // iterate through the tables and get the foreign keys
-  print "<?php
-/* @file: This file contains default schema definitions for all chado v$version tables
- *        to be used by other function. Specifically these functions are used
- *        by the tripal_core select/insert/update API functions and by
- *        the Tripal Views module.
- *
- *        These schema definitions can be augmented by another modules
- *        (specifically to add missing definitions) by implementing
- *        hook_chado_schema_v" . $v . "_<table name>().
- *
- * @defgroup tripal_schema_api Core Module Schema API
- * @{
- * Provides an application programming interface (API) for describing Chado tables.
- * This API consists of a set of functions, one for each table in Chado.  Each
- * function simply returns a Drupal style array that defines the table.
- *
- * Because Drupal 6 does not handle foreign key (FK) relationships, however FK
- * relationships are needed to for Tripal Views.  Therefore, FK relationships
- * have been added to the schema defintitions below.
- *
- * The functions provided in this documentation should not be called as is, but if you need
- * the Drupal-style array definition for any table, use the following function
- * call:
- *
- *   \$table_desc = chado_get_schema(\$table)
- *
- * where the variable \$table contains the name of the table you want to
- * retireve.  The chado_get_schema function determines the appropriate version of
- * Chado and uses the Drupal hook infrastructure to call the appropriate
- * hook function to retrieve the table schema.
- *
- * @}
- * @ingroup tripal_api
- */
-";
-  $referring = array();
-  $tables_def = array();
-  foreach ($tables as $table) {
-
-    // get the existing table array
-    $table_arr = chado_get_schema($table);
-
-    if (empty($table_arr)) {
-       print "ERROR: empty table definition $table\n";
-       continue;
-    }
-
-    // add the table name to the array
-    $table_arr['table'] = $table;
-
-    // get the foreign keys and add them to the array
-    $fks = db_query($sql, array(':table_name' => $table));
-    foreach ($fks as $fk) {
-      $table_arr['foreign keys'][$fk->foreign_table_name]['table'] = $fk->foreign_table_name;
-      $table_arr['foreign keys'][$fk->foreign_table_name]['columns'][$fk->column_name] = $fk->foreign_column_name;
-      $reffering[$fk->foreign_table_name][] = $table;
-    }
-    $tables_def[] = $table_arr;
-  }
-
-  // now add in the referring tables and print
-  foreach ($tables_def as $table_arr) {
-    $table = $table_arr['table'];
-
-    // add in the referring tables
-    $table_referring = array_unique($reffering[$table]);
-    $table_arr['referring_tables'] = $table_referring;
-
-    // reformat the array to be more legible
-    $arr = var_export($table_arr, 1);
-    $arr = preg_replace("/\n\s+array/","array", $arr); // move array( to previous line
-    $arr = preg_replace("/\n/","\n  ", $arr); // add indentation
-    $arr = preg_replace("/true/","TRUE", $arr); // add indentation
-    $arr = preg_replace("/false/","FALSE", $arr); // add indentation
-    $arr = preg_replace("/array \(/","array(", $arr); // add indentation
-
-      // print out the new Schema API function for this table
-print "/**
- * Implements hook_chado_schema_v".$v."_".$table."()
- * Purpose: To describe the structure of '$table' to tripal
- * @see chado_insert_record()
- * @see chado_update_record()
- * @see chado_select_record()
- *
- * @return
- *    An array describing the '$table' table
- *
- * @ingroup tripal_chado_v".$version."_schema_api
- *
- */
-function tripal_core_chado_schema_v".$v."_".$table."() {
-  \$description =  $arr;
-  return \$description;
-}
-";
-  }
-}

+ 1 - 1
tripal_core/api/tripal_core.DEPRECATED.api.inc

@@ -915,7 +915,7 @@ function tripal_core_delete_property_by_id($basetable, $property_id) {
     'tripal_deprecated',
     TRIPAL_NOTICE,
     "DEPRECATED: %old_function has been replaced with %new_function. This requires manual
-      intervention since the arguements for the two functions are different.
+      intervention since the arguments for the two functions are different.
       Please update your code.",
     array(
       '%old_function'=>'tripal_core_delete_property_by_id',

+ 5 - 2
tripal_core/api/tripal_core.chado_general.api.inc

@@ -66,12 +66,15 @@ function chado_set_active($dbname = 'default') {
   }
 
   $previous_db = $active_db = $GLOBALS['chado_active_db'];
-  $search_path = 'public';
+  $search_path = tripal_get_schema_name('drupal');
 
   // Change only if 'chado' has been specified.
+  // Notice that we leave the active_db set as chado but use the possibly user-altered
+  // schema name for the actual search path. This is to keep outward facing mentions of
+  // chado as "chado" while still allowing the user to alter the schema name used.
   if ($dbname == 'chado') {
     $active_db = 'chado';
-    $search_path = 'chado,public';
+    $search_path = tripal_get_schema_name('chado') . ',' . tripal_get_schema_name('drupal');
   }
 
   $settings = array(

+ 14 - 16
tripal_core/api/tripal_core.chado_nodes.api.inc

@@ -1077,10 +1077,8 @@ function chado_cleanup_orphaned_nodes_part($table, $job_id = NULL, $nentries,
   $clsql= "
     SELECT *
     FROM {" . $linking_table . "} LT
-      INNER JOIN {node} N ON N.nid = LT.nid
-    WHERE N.type = :node_type
     ORDER BY LT.nid LIMIT $nentries OFFSET $offset";
-  $res = db_query($clsql, array(':node_type' => $node_type));
+  $res = db_query($clsql);
   foreach ($res as $node) {
     $cnodes[$count] = $node;
     $count++;
@@ -1095,40 +1093,40 @@ function chado_cleanup_orphaned_nodes_part($table, $job_id = NULL, $nentries,
     if ($interval < 1) {
       $interval = 1;
     }
-    foreach ($cnodes as $nid) {
+    foreach ($cnodes as $linker) {
       // Update the job status every 1% analyses
       if ($job_id and $i % $interval == 0) {
         $percent = sprintf("%.2f", ($i / $count) * 100);
         tripal_set_job_progress($job_id, intval($percent));
-        print "Percent complete: $percent%. Memory: " . number_format(memory_get_usage()) . " bytes.\r";
+        print "Percent complete: $percent%. Memory: " . number_format(memory_get_usage()) . " bytes.\n";
       }
 
       // See if the node exits, if not remove the entry from linking table table.
-      $nsql = "SELECT * FROM {node} WHERE nid = :nid";
-      $results = db_query($nsql, array(':nid' => $nid->nid));
+      $nsql = "SELECT * FROM {node} WHERE nid = :nid AND type = :node_type";
+      $results = db_query($nsql, array(':nid' => $linker->nid, ':node_type' => $node_type));
       $node = $results->fetchObject();
       if (!$node) {
         $deleted++;
-        db_query("DELETE FROM {" . $linking_table . "} WHERE nid = :nid", array(':nid' => $nid->nid));
-        //print "$linking_table missing node.... DELETING: $nid->nid\n";
+        db_query("DELETE FROM {" . $linking_table . "} WHERE nid = :nid", array(':nid' => $linker->nid));
+        //print "$linking_table missing node.... DELETING where nid=".$linker->nid." $linking_table entry.\n";
       }
 
       // Does record in chado exists, if not remove entry from $linking_table.
       $table_id = $table . "_id";
-      $lsql = "SELECT * FROM {" . $table . "} where " . $table . "_id = :" . $table . "_id";
-      $results = chado_query($lsql, array(":" . $table . "_id" => $nid->$table_id));
+      $lsql = "SELECT * FROM {" . $table . "} where " . $table_id . " = :chado_id";
+      $results = chado_query($lsql, array(":chado_id" => $linker->$table_id));
       $record = $results->fetchObject();
       if (!$record) {
         $deleted++;
-        $sql = "DELETE FROM {" . $linking_table . "} WHERE " . $table . "_id = :" . $table . "_id";
-        db_query($sql, array(":" . $table . "_id" => $nid->$table_id));
-        //print "$linking_table missing $table.... DELETING entry.\n";
+        $sql = "DELETE FROM {" . $linking_table . "} WHERE " . $table_id . " = :chado_id";
+        db_query($sql, array(":chado_id" => $linker->$table_id));
+        //print "$linking_table missing $table.... DELETING where $table_id=".$linker->$table_id." $linking_table entry.\n";
       }
       $i++;
     }
     $percent = sprintf("%.2f", ($i / $count) * 100);
     tripal_set_job_progress($job_id, intval($percent));
-    print "Percent complete: $percent%. Memory: " . number_format(memory_get_usage()) . " bytes.\r";
+    print "Percent complete: $percent%. Memory: " . number_format(memory_get_usage()) . " bytes.\n";
   }
   print "\nDeleted $deleted record(s) from $linking_table missing either a node or chado entry.\n";
 
@@ -1249,7 +1247,7 @@ function hook_chado_node_sync_form($form, &$form_state) {
  *
  * Allows you to use this function as your own submit.
  *
- * This might be necessary if you want to add additional arguements to the
+ * This might be necessary if you want to add additional arguments to the
  * tripal job or to call your own sync'ing function if the generic
  * chado_node_sync_records() is not sufficient.
  *

+ 5 - 2
tripal_core/api/tripal_core.chado_nodes.relationships.api.inc

@@ -1046,7 +1046,10 @@ function chado_add_node_form_relationships_name_to_id_callback($base_table, $nam
 
   $base_key = $base_table.'_id';
 
-  $query = db_select('chado.'.$base_table, 'b')
+  // determine the chado schema.
+  $chado = tripal_get_schema_name('chado');
+
+  $query = db_select($chado.'.'.$base_table, 'b')
     ->fields('b', array($base_key, $name_field))
     ->condition($name_field, '%' . db_like($string) . '%', 'LIKE');
 
@@ -1065,4 +1068,4 @@ function chado_add_node_form_relationships_name_to_id_callback($base_table, $nam
 
   // return for JS
   drupal_json_output($matches);
-}
+}

+ 121 - 11
tripal_core/api/tripal_core.chado_nodes.title_and_path.api.inc

@@ -1138,6 +1138,60 @@ function chado_node_get_token_format($application, $content_type, $options = arr
   }
 }
 
+/**
+ * Generate a Readable but not necessarily unique format based on a given primary
+ * key token.
+ *
+ * For example, given the token [feature.type_id>cvterm.cvterm_id] you don't
+ * want the actual id indexed but instead would want the term name, [feature.type_id>cvterm.name]
+ */
+function chado_node_get_readable_format($token) {
+
+  // First, lets break down the token into it's parts.
+  // 1. Remove containing brackets.
+  $parts = str_replace(array('[',']'),'',$token);
+  // 2. Break into table clauses.
+  $parts = explode('>',$parts);
+  // 3. Break each table clause into table & field.
+  foreach ($parts as $k => $v) {
+    $parts[$k] = explode('.', $v);
+    if (sizeof($parts[$k]) == 1) {
+      $parts[$k] = explode(':', $v);
+    }
+  }
+  $last_k = $k;
+
+  // Now, we want to find readable fields for the last table specified in the token.
+  // (ie: for cvterm in [feature.type_id>cvterm.cvterm_id])
+  $table = $parts[$last_k][0];
+  $format = array();
+  if ($table == 'organism') {
+    $format[] = preg_replace('/(\w+)\]$/', 'genus]', $token);
+    $format[] = preg_replace('/(\w+)\]$/', 'species]', $token);
+    $format[] = preg_replace('/(\w+)\]$/', 'common_name]', $token);
+    $format = $format[0] . ' ' . $format[1] . ' (' . $format[2] . ')';
+  }
+  elseif ($table == 'dbxref') {
+    $format[] = preg_replace('/(\w+)\]$/', 'accession]', $token);
+    $format[] = preg_replace('/(\w+)\]$/', 'db_id>db.name]', $token);
+    $format = $format[0] . ' (' . $format[1] . ')';
+  }
+  else {
+    $schema = chado_get_schema($table);
+    foreach ($schema['fields'] as $field_name => $details) {
+      if (preg_match('/name/',$field_name)) {
+        $format[] = preg_replace('/(\w+)\]$/', $field_name.']', $token);
+      }
+    }
+    $format = implode(', ',$format);
+  }
+  if (empty($format)) {
+    return FALSE;
+  }
+
+  return $format;
+}
+
 /**
  * Generate the unique constraint for a given base table using the
  * Chado Schema API definition
@@ -1304,12 +1358,14 @@ function chado_node_generate_tokens($base_table, $token_prefix = FALSE, $locatio
  * @return
  *   The value of the token
  */
-function chado_get_token_value($token_info, $node) {
+function chado_get_token_value($token_info, $node, $options = array()) {
 
   $token = $token_info['token'];
   $table = $token_info['table'];
   $var = $node;
 
+  $supress_errors = (isset($options['supress_errors'])) ? $options['supress_errors'] : FALSE;
+
   // Iterate through each portion of the location string. An example string
   // might be:  stock > type_id > name.
   $location = explode('>', $token_info['location']);
@@ -1325,11 +1381,13 @@ function chado_get_token_value($token_info, $node) {
         $var = $var->$index;
       }
       else {
-        tripal_report_error('chado_node_api', TRIPAL_WARNING,
-          'Tokens: Unable to determine the value of %token. Things went awry when trying ' .
-          'to access \'%index\' for the following: \'%var\'.',
-          array('%token' => $token, '%index' => $index, '%var' => print_r($var,TRUE))
-        );
+        if (!$supress_errors) {
+          tripal_report_error('chado_node_api', TRIPAL_WARNING,
+            'Tokens: Unable to determine the value of %token. Things went awry when trying ' .
+            'to access \'%index\' for the following: \'%var\'.',
+            array('%token' => $token, '%index' => $index, '%var' => print_r($var,TRUE))
+          );
+        }
         return '';
       }
     }
@@ -1339,11 +1397,13 @@ function chado_get_token_value($token_info, $node) {
       $var = $var[$index];
     }
     else {
-      tripal_report_error('chado_node_api', TRIPAL_WARNING,
-        'Tokens: Unable to determine the value of %token. Things went awry when trying ' .
-        'to access \'%index\' for the following: \'%var\'.',
-        array('%token' => $token, '%index' => $index, '%var' => print_r($var,TRUE))
-      );
+      if (!$supress_errors) {
+        tripal_report_error('chado_node_api', TRIPAL_WARNING,
+          'Tokens: Unable to determine the value of %token. Things went awry when trying ' .
+          'to access \'%index\' for the following: \'%var\'.',
+          array('%token' => $token, '%index' => $index, '%var' => print_r($var,TRUE))
+        );
+      }
       return '';
     }
   }
@@ -1388,6 +1448,56 @@ function chado_node_format_tokens($tokens) {
   return theme_table($table);
 }
 
+/**
+ * Returns the "location" as specified in the token information based on the token.
+ */
+function chado_node_get_location_from_token($token) {
+
+  if (is_array($token) and isset($token['location'])) {
+    return $token['location'];
+  }
+  // If we have been given the token as a string, we can still determine the location
+  // but it takes more work...
+  // First, lets clarify what the location is: the location shows which keys in which
+  // order need to be travelled in order to access the value. For example, the token
+  // [feature.organism_id>organism.genus] would have a location of
+  // feature > organism_id > genus to show that the value is at
+  // $node->feature->organism->genus.
+  elseif (is_string($token)) {
+
+    // First, lets break down the token into it's parts.
+    // 1. Remove containing brackets.
+    $parts = str_replace(array('[',']'),'',$token);
+    // 2. Break into table clauses.
+    $parts = explode('>',$parts);
+    // 3. Break each table clause into table & field.
+    foreach ($parts as $k => $v) {
+      $parts[$k] = explode('.', $v);
+      if (sizeof($parts[$k]) == 1) {
+        $parts[$k] = explode(':', $v);
+      }
+    }
+
+    // This is a base level field that is not a foreign key.
+    if (sizeof($parts) == 1 AND sizeof($parts[0]) == 2) {
+      return $parts[0][0] . ' > ' . $parts[0][1];
+    }
+    // Darn, we have at least one foreign key...
+    elseif (sizeof($parts) > 1 AND sizeof($parts[0]) == 2) {
+      $location = $parts[0][0] . ' > ' . $parts[0][1];
+      foreach ($parts as $k => $p) {
+        if ($k != 0 AND isset($p[1])) {
+          $location .= ' > ' . $p[1];
+        }
+      }
+      return $location;
+    }
+    else {
+      return FALSE;
+    }
+  }
+}
+
 /**
  * This sorts tokens first by depth (ie: stock.* is before stock.*>subtable.*) and
  * then alphabetically within a level (ie: stock.name comes before stock.type_id)

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

@@ -299,11 +299,12 @@ function chado_insert_record($table, $values, $options = array()) {
 
   // get the table description
   $table_desc = chado_get_schema($table);
-  if (empty($table_desc)) {
+  if (!$table_desc) {
     tripal_report_error('tripal_core', TRIPAL_WARNING,
       'chado_insert_record; There is no table description for !table_name',
       array('!table_name' => $table), array('print' => $print_errors)
     );
+    return FALSE;
   }
 
   // iterate through the values array and create a new 'insert_values' array
@@ -803,6 +804,8 @@ function chado_update_record($table, $match, $values, $options = NULL) {
  */
 function chado_delete_record($table, $match, $options = NULL) {
 
+  $print_errors = (isset($options['print_errors'])) ? $options['print_errors'] : FALSE;
+
   if (!is_array($match)) {
     tripal_report_error('tripal_core', TRIPAL_ERROR,
       'Cannot pass non array as values for matching.', array());
@@ -826,7 +829,7 @@ function chado_delete_record($table, $match, $options = NULL) {
   $table_desc = chado_get_schema($table);
   $fields = $table_desc['fields'];
   if (empty($table_desc)) {
-    tripal_report_error('tripal_core', TRIPAL_WARNING,
+    chado_delete_record('tripal_core', TRIPAL_WARNING,
       'chado_insert_record; There is no table description for !table_name',
       array('!table_name' => $table), array('print' => $print_errors)
     );
@@ -1080,11 +1083,12 @@ function chado_select_record($table, $columns, $values, $options = NULL) {
 
   // Get the table description.
   $table_desc = chado_get_schema($table);
-  if (empty($table_desc)) {
-    tripal_report_error('tripal_core', TRIPAL_WARNING,
+  if (!is_array($table_desc)) {
+    tripal_report_error('tripal_chado', TRIPAL_WARNING,
       'chado_insert_record; There is no table description for !table_name',
       array('!table_name' => $table), array('print' => $print_errors)
     );
+    return FALSE;
   }
 
   $select = '';
@@ -1487,7 +1491,7 @@ function chado_select_record_check_value_type(&$op, &$value, $type) {
  * @ingroup tripal_chado_query_api
  */
 function chado_query($sql, $args = array()) {
-  $is_local = $GLOBALS["chado_is_local"];
+  $is_local = isset($GLOBALS["chado_is_local"]) && $GLOBALS["chado_is_local"];
 
   // Args should be an array
   if (!is_array($args)) {
@@ -1508,17 +1512,28 @@ function chado_query($sql, $args = array()) {
     // Prefix the tables with their correct schema.
     // Chado tables should be enclosed in curly brackets (ie: {feature} )
     // and Drupal tables should be enclosed in square brackets (ie: [tripal_jobs] ).
-    // @todo: remove assumption that the chado schema is called 'chado' and the
-    // drupal schema is called 'public'.
-    $sql = preg_replace('/\{(.*?)\}/', 'chado.$1', $sql);
-    $sql = preg_replace('/\[(\w+)\]/', 'public.$1', $sql);
+    $chado_schema_name = tripal_get_schema_name('chado');
+    $drupal_schema_name = tripal_get_schema_name('drupal');
+    $sql = preg_replace('/\{(.*?)\}/', $chado_schema_name.'.$1', $sql);
+    $sql = preg_replace('/\[(\w+)\]/', $drupal_schema_name.'.$1', $sql);
+
+    // Add an alter hook to allow module developers to change the query right before it's
+    // executed. Since all queriying of chado by Tripal eventually goes through this
+    // function, we only need to provide an alter hook at this point in order to ensure
+    // developers have complete control over the query being executed. For example,
+    // a module developer might want to remove schema prefixing from queries and rely
+    // on the search path. This alter hook would allow them to do that by implementing
+    // mymodule_chado_query_alter($sql, $args) and using a regular expression to remove
+    // table prefixing from the query.
+    // @see hook_chado_query_alter().
+    drupal_alter('chado_query', $sql, $args);
 
     // The featureloc table has some indexes that use function that call other
     // functions and those calls do not reference a schema, therefore, any
     // tables with featureloc must automaticaly have the chado schema set as
     // active to find.
-    if (preg_match('/chado.featureloc/i', $sql) or preg_match('/chado.feature/i', $sql)) {
-      $previous_db = chado_set_active('chado') ;
+    if (preg_match('/'.$chado_schema_name.'.featureloc/i', $sql) or preg_match('/'.$chado_schema_name.'.feature/i', $sql)) {
+      $previous_db = chado_set_active('chado');
       $results = db_query($sql, $args);
       chado_set_active($previous_db);
     }
@@ -1550,6 +1565,42 @@ function chado_query($sql, $args = array()) {
   return $results;
 }
 
+/**
+ * This hook provides a way for module developers to alter any/all queries on the chado
+ * schema by Tripal.
+ *
+ * Example: a module developer might want to remove schema prefixing from queries and rely
+ * on the search path. This alter hook would allow them to do that by implementing
+ * mymodule_chado_query_alter($sql, $args) and using a regular expression to remove
+ * table prefixing from the query.
+ *
+ * @param $sql
+ *    A string describing the SQL query to be executed by Tripal. All parameters should be
+ *    indicated by :tokens with values being in the $args array and all tables should
+ *    be prefixed with the schema name described in tripal_get_schema_name().
+ * @param $args
+ *    An array of arguments where the key is the token used in $sql (for example, :value)
+ *    and the value is the value you would like substituted in.
+ */
+function hook_chado_query_alter(&$sql, &$args) {
+
+  // The following code is an example of how this alter function might be used.
+  // Say you would like only a portion of node => feature connections available
+  // for a period of time or under a specific condition. To "hide" the other connections
+  // you might create a temporary view of the chado_feature table that only includes
+  // the connections you would like to be available. In order to ensure this view
+  // is used rather than the original chado_feature table you could alter all Tripal
+  // queries referring to chado_feature to instead refer to your view.
+  if (preg_match('/(\w+)\.chado_feature/', $sql, $matches)) {
+
+      $sql = str_replace(
+        $matches[1] . '.chado_feature',
+        'chado_feature_view',
+        $sql
+      );
+  }
+}
+
 /**
  * Use this function instead of pager_query() when selecting a
  * subset of records from a Chado table.
@@ -1607,6 +1658,7 @@ function chado_pager_query($query, $args, $limit, $element, $count_query = '') {
   $results = chado_query($query, $args);
   return $results;
 }
+
 /**
  * A function to retrieve the total number of records for a pager that
  * was generated using the chado_pager_query() function
@@ -1747,3 +1799,66 @@ function chado_schema_get_foreign_key($table_desc, $field, $values, $options = N
 
   return array();
 }
+
+/**
+ * Retrieve the name of the PostgreSQL schema housing Chado or Drupal.
+ *
+ * @param $schema
+ *   Wehter you want the schema name for 'chado' or 'drupal'. Chado is the default.
+ * @return
+ *   The name of the PostgreSQL schema housing the $schema specified.
+ */
+function tripal_get_schema_name($schema = 'chado') {
+
+  // First we will set our default. This is what will be returned in most cases.
+  if ($schema == 'chado') {
+    $schema_name = 'chado';
+  }
+  else {
+    $schema_name = 'public';
+  }
+
+  // There are cases where modules or admin might need to change the default
+  // names for the schema. Thus we provide an alter hook here to allow
+  // the names to be changed and ensure that schema names are never hardcoded
+  // directly into queries.
+  $context = array('schema' => $schema);
+  drupal_alter('tripal_get_schema_name', $schema_name, $context);
+
+  return $schema_name;
+}
+
+/**
+ * Alter the name of the schema housing Chado and/or Drupal.
+ *
+ * This example implementation shows a solution for the case where your chado database
+ * was well established in the "public" schema and you added Drupal later in a
+ * "drupal" schema. Please note that this has not been tested and while we can ensure
+ * that Tripal will work as expected, we have no control over whether Drupal is
+ * compatible with not being in the public schema. That's why we recommened the
+ * organization we have (ie: Chado in a "chado" schema and Drupal in the "public schema).
+ *
+ * @param $schema_name
+ *   The current name of the schema as known by Tripal. This is likely the default
+ *   set in tripal_get_schema_name() but in the case of multiple alter hooks, it might
+ *   be different.
+ * @param $context
+ *   This is an array of items to provide context.
+ *     - schema: this is the schema that was passed to tripal_get_schema_name() and will
+ *       be either "chado" or "drupal". This should be used to determine you are changing
+ *       the name of the correct schema.
+ */
+function hook_tripal_get_schema_name_alter($schema_name, $context) {
+
+  // First we check which schema was passed to chado_get_schema().
+  // Notice that we do not use $schema_name since it may already have
+  // been altered by another module.
+  if ($context['schema'] == 'chado') {
+    $schema_name = 'public';
+  }
+  // Notice that we use elseif to capture the second case rather than else. This
+  // avoids the assumption that there is only one chado and one drupal schema.
+  elseif ($context['schema'] == 'drupal') {
+    $schema_name = 'drupal';
+  }
+}

+ 119 - 14
tripal_core/api/tripal_core.chado_schema.api.inc

@@ -26,12 +26,15 @@
  */
 
 /**
- * Check that any given Chado table exists.  This function
- * is necessary because Drupa's db_table_exists will not
+ * Check that any given Chado table exists.
+ *
+ * This function is necessary because Drupal's db_table_exists will not
  * look in any other schema but the one were Drupal is installed
  *
+ * @param $table
+ *   The name of the chado table whose existence should be checked.
  * @return
- *   TRUE/FALSE depending upon whether it exists
+ *   TRUE if the table exists in the chado schema and FALSE if it does not.
  *
  * @ingroup tripal_chado_schema_api
  */
@@ -45,10 +48,15 @@ function chado_table_exists($table) {
     FROM information_schema.tables
     WHERE
       table_name = :table_name AND
-      table_schema = 'chado' AND
-      table_catalog = '$default_db'
+      table_schema = :chado AND
+      table_catalog = :default_db
   ";
-  $results = db_query($sql, array(':table_name' => $table));
+  $args = array(
+    ':table_name' => $table,
+    ':chado' => tripal_get_schema_name('chado'),
+    ':default_db' => $default_db
+  );
+  $results = db_query($sql, $args);
   $exists = $results->fetchObject();
   if (!$exists) {
     return FALSE;
@@ -56,6 +64,89 @@ function chado_table_exists($table) {
   return TRUE;
 }
 
+/**
+ * Check that any given column in a Chado table exists.
+ *
+ * This function is necessary because Drupal's db_field_exists() will not
+ * look in any other schema but the one were Drupal is installed
+ *
+ * @param $table
+ *   The name of the chado table.
+ * @param $column
+ *   The name of the column in the chado table.
+
+ * @return
+ *   TRUE if the column exists for the table in the chado schema and
+ *   FALSE if it does not.
+ *
+ * @ingroup tripal_chado_schema_api
+ */
+function chado_column_exists($table, $column) {
+  global $databases;
+
+  $default_db = $databases['default']['default']['database'];
+
+  $sql = "
+    SELECT 1
+    FROM information_schema.columns
+    WHERE
+      table_name = :table_name AND
+      column_name = :column_name AND
+      table_schema = :chado AND
+      table_catalog = :default_db
+  ";
+  $args = array(
+    ':table_name' => $table,
+    ':column_name' => $column,
+    ':chado' => tripal_get_schema_name('chado'),
+    ':default_db' => $default_db
+  );
+  $results = db_query($sql, $args);
+  $exists = $results->fetchField();
+  if (!$exists) {
+    return FALSE;
+  }
+  return TRUE;
+}
+
+/**
+ * Check that any given column in a Chado table exists.
+ *
+ * This function is necessary because Drupal's db_field_exists() will not
+ * look in any other schema but the one were Drupal is installed
+ *
+ * @param sequence
+ *   The name of the sequence
+ * @return
+ *   TRUE if the seqeuence exists in the chado schema and FALSE if it does not.
+ *
+ * @ingroup tripal_chado_schema_api
+ */
+function chado_sequence_exists($sequence) {
+  global $databases;
+
+  $default_db = $databases['default']['default']['database'];
+
+  $sql = "
+    SELECT 1
+    FROM information_schema.sequences
+    WHERE
+      sequence_name = :sequence_name AND
+      sequence_schema = :sequence_schema AND
+      sequence_catalog = :sequence_catalog
+  ";
+  $args = array(
+    ':sequence_name' => $sequence,
+    ':sequence_schema' => tripal_get_schema_name('chado'),
+    ':sequence_catalog' => $default_db
+  );
+  $results = db_query($sql, $args);
+  $exists = $results->fetchField();
+  if (!$exists) {
+    return FALSE;
+  }
+  return TRUE;
+}
 /**
  * A Chado-aware replacement for the db_index_exists() function.
  *
@@ -71,7 +162,11 @@ function chado_index_exists($table, $name) {
 
   $default_db = $databases['default']['default']['database'];
 
-  $sql = "SELECT 1 as exists FROM pg_indexes WHERE indexname = :indexname";
+  $sql = "
+      SELECT 1 as exists
+      FROM pg_indexes
+      WHERE indexname = :indexname
+  ";
 
   $result = db_query($sql, array(':indexname' => $indexname));
   $exists = $result->fetchObject();
@@ -152,9 +247,9 @@ function chado_is_local() {
     FROM pg_namespace
     WHERE
       has_schema_privilege(nspname, 'USAGE') AND
-      nspname = 'chado'
+      nspname = :chado
   ";
-  $results = db_query($sql);
+  $results = db_query($sql, array(':chado' => tripal_get_schema_name('chado')));
   $name = $results->fetchObject();
   if ($name) {
     variable_set('chado_schema_exists', FALSE);
@@ -178,7 +273,7 @@ function chado_is_installed() {
   global $databases;
 
   // first check if chado is in the $databases variable of the settings.php file
-  if (array_key_exists('chado', $databases)) {
+  if (array_key_exists(tripal_get_schema_name('chado'), $databases)) {
     return TRUE;
   }
 
@@ -220,7 +315,7 @@ function chado_get_version($exact = FALSE, $warn_if_unsupported = FALSE) {
   if (!$chado_exists) {
     // if it's not in the drupal database check to see if it's specified in the $db_url
     // in the settings.php
-    if (!array_key_exists('chado', $databases)) {
+    if (!array_key_exists(tripal_get_schema_name('chado'), $databases)) {
       // if it's not in the drupal database or specified in the $db_url then
       // return uninstalled as the version
       return 'not installed';
@@ -232,7 +327,8 @@ function chado_get_version($exact = FALSE, $warn_if_unsupported = FALSE) {
   }
   else {
     $is_local = 1;
-    $prop_exists = db_table_exists('chado.chadoprop');
+    // @todo we need a chado aware db_table_exists.
+    $prop_exists = db_table_exists(tripal_get_schema_name('chado').'.chadoprop');
   }
 
   // if the table doesn't exist then we don't know what version but we know
@@ -289,7 +385,10 @@ function chado_get_version($exact = FALSE, $warn_if_unsupported = FALSE) {
   if (preg_match('/^1\.2\d+$/', $effective_version)) {
     $effective_version = "1.2";
   }
-  if ($warn_if_unsupported and ($effective_version != 1.11 and $effective_version != 1.2 and $effective_version != 'not installed')) {
+  else if (preg_match('/^1\.3\d+$/', $effective_version)) {
+    $effective_version = "1.3";
+  }
+  if ($warn_if_unsupported and ($effective_version < 1.11 and $effective_version != 'not installed')) {
     drupal_set_message(t("WARNING: The currently installed version of Chado, v$exact_version, is not fully compatible with Tripal."), 'warning');
   }
   // if the callee has requested the exact version then return it
@@ -321,6 +420,12 @@ function chado_get_table_names($include_custom = NULL) {
   $v = $GLOBALS["chado_version"];
 
   $tables = array();
+  if ($v == '1.3') {
+    $tables_v1_3 = tripal_core_chado_get_v1_3_tables();
+    foreach ($tables_v1_3 as $table) {
+      $tables[$table] = $table;
+    }
+  }
   if ($v == '1.2') {
     $tables_v1_2 = tripal_core_chado_get_v1_2_tables();
     foreach ($tables_v1_2 as $table) {
@@ -412,4 +517,4 @@ function chado_get_custom_table_schema($table) {
   else {
     return unserialize($custom->schema);
   }
-}
+}

+ 162 - 74
tripal_core/api/tripal_core.chado_variables.api.inc

@@ -5,12 +5,80 @@
  */
 
 /**
- * Generates an array containing the full details of a record(s) in chado. The
- * returned array differs from the array returned by chado_select_record as all foreign key
- * relationships have been followed and those data are also included. The array
- * returned by this function can be used with chado_expand_var function to add
- * additional FK relationships that were not included because they were not
- * a one-to-one mapping or for fields that were excluded such as large text fields.
+ * Generates an object containing the full details of a record(s) in Chado.
+ *
+ * The object returned contains key/value pairs where the keys are the fields
+ * in the Chado table.
+ *
+ * The returned object differs from the array returned by chado_select_record()
+ * as all foreign key relationships in the Chado table have been followed and
+ * those data are also included. This function automatically excludes some
+ * fields and tables. Fields that are extremely long, such as text fields are
+ * automatically excluded to prevent long page loads.  Linking tables that have
+ * a many-to-one relationship with the record are also excluded. Use the
+ * chado_expand_var() to manually add in excluded fields and data from linker
+ * tables.
+ *
+ * Example Usage:
+ * @code
+ *   $values = array(
+ *     'name' => 'Medtr4g030710'
+ *   );
+ *   $feature = chado_generate_var('feature', $values);
+ * @endcode
+ *
+ * The $values array passed to this fucntion can be of the same format used
+ * by the chado_select_record() function.
+ *
+ * If a field is a foreign key then its value is an object that contains
+ * key/value pairs for that record.  The following code provides examples
+ * for retrieving values associated with the record, either as columns in the
+ * original Chado table or as columns in linked records through foreign keys:
+ * @code
+ *   // Get the feature name.
+ *   $name = $feature->name;
+ *   // Get the feature unique name.
+ *   $uniquename = $feature->uniquename;
+ *   // Get the feature type. Because the type name is obtained via
+ *   // a foreign key with the cvterm table, the objects are nested
+ *   // and we can follow the foreign key fields to retrieve those values
+ *   $type = $feature->type_id->name;
+ *   // Get the name of the vocabulary.
+ *   $cv = $feature->type_id->cv_id->name;
+ *   // Get the vocabulary id.
+ *   $cv_id = $feature->type_id->cv_id->cv_id;
+ * @endcode
+ *
+ *
+ * This will return an object if there is only one feature with the name
+ * Medtr4g030710 or it will return an array of feature objects if more than one
+ * feature has that name.
+ *
+ * Note to Module Designers: Fields can be excluded by default from these
+ * objects by implementing one of the following hooks:
+ *  - hook_exclude_field_from_tablename_by_default (where tablename is the
+ *    name of the table): This hook allows you to add fields to be excluded
+ *    on a per table basis. Simply implement this hook to return an array of
+ *    fields to be excluded. The following example will ensure that
+ *    feature.residues is excluded from a feature object by default:
+ *    @code
+ *      mymodule_exclude_field_from_feature_by_default() {
+ *        return array('residues' => TRUE);
+ *      }
+ *    @endcode
+ *  - hook_exclude_type_by_default:
+ *      This hook allows you to exclude fields using conditional. This
+ *      function should return an array of postgresql types mapped to criteria.
+ *      If the field types of any table match the criteria then the field
+ *      is excluded. Tokens available in criteria are &gt;field_value&lt;
+ *      and &gt;field_name&lt;. The following example will exclude all text
+ *      fields with a length > 50. Thus if $feature.residues is longer than
+ *      50 it will be excluded, otherwise it will be added.
+ *      @code
+ *        mymodule_exclude_type_by_default() {
+ *          return array('text' => 'length(&gt;field_value&lt; ) > 50');
+ *        }
+ *      @endcode
  *
  *
  * @param $table
@@ -26,16 +94,16 @@
  *   Additionally,  These options are available for this function:
  *   -return_array:
  *     can be provided to force the function to always return an array. Default
- *     behavior is to return a single record if only one record exists or to return
- *     an array if multiple records exist.
+ *     behavior is to return a single record if only one record exists or to
+ *     return an array if multiple records exist.
  *  - include_fk:
  *     an array of FK relationships to follow. By default, the
  *     chado_select_record function will follow all FK relationships but this
- *     may generate more queries then is desired slowing down this function call when
- *     there are lots of FK relationships to follow.  Provide an array specifying the
- *     fields to include.  For example, if expanding a property table (e.g. featureprop)
- *     and you want the CV and accession but do not want the DB the following
- *     array would work:
+ *     may generate more queries then is desired slowing down this function
+ *     call when there are lots of FK relationships to follow.  Provide an
+ *     array specifying the fields to include.  For example, if expanding a
+ *     property table (e.g. featureprop) and you want the CV and accession
+ *     but do not want the DB the following array would work:
  *
  *        $table_options =  array(
  *          'include_fk' => array(
@@ -58,41 +126,9 @@
  *     one for each pager.
  * @return
  *   Either an object (if only one record was selected from the base table)
- *   or an array of objects (if more than one record was selected from the base table).
- *   If the option 'return_array' is provided the function always returns an array.
- *
- * Example Usage:
- * @code
-   $values = array(
-     'name' => 'Medtr4g030710'
-   );
-   $features = chado_generate_var('feature', $values);
- * @endcode
- * This will return an object if there is only one feature with the name Medtr4g030710 or it will
- * return an array of feature objects if more than one feature has that name.
- *
- * Note to Module Designers: Fields can be excluded by default from these objects by implementing
- * one of the following hooks:
- *  - hook_exclude_field_from_tablename_by_default (where tablename is the name of the table):
- *      This hook allows you to add fields to be excluded on a per table basis. Simply implement
- *      this hook to return an array of fields to be excluded. For example:
- * @code
-   mymodule_exclude_field_from_feature_by_default() {
-     return array('residues' => TRUE);
-   }
- * @endcode
- *      will ensure that feature.residues is ecluded from a feature object by default.
- *  - hook_exclude_type_by_default:
- *      This hook allows you to exclude fields from all tables that are of a given postgresql field
- *      type. Simply implement this hook to return an array of postgresql types mapped to criteria.
- *      Then all fields of that type where the criteria supplied returns TRUE will be excluded from
- *      any table. Tokens available in criteria are &gt;field_value&lt;  and &gt;field_name&lt; . For example:
- * @code
-   mymodule_exclude_type_by_default() {
-     return array('text' => 'length(&gt;field_value&lt; ) > 50');
-   }
- * @endcode
- *      will exclude all text fields with a length > 50. Thus if $feature.residues is longer than 50 *      it will be excluded, otherwise it will be added.
+ *   or an array of objects (if more than one record was selected from the
+ *   base table). If the option 'return_array' is provided the function
+ *   always returns an array.
  *
  * @ingroup tripal_chado_query_api
  */
@@ -405,11 +441,78 @@ function chado_generate_var($table, $values, $base_options = array()) {
 }
 
 /**
- * Retrieves fields/tables/nodes that were excluded by default from a variable and adds them
+ * Retrieves fields, or tables that were excluded by default from a variable.
+ *
+ * The chado_generate_var() function automatically excldue some
+ * fields and tables  from the default form of a variable. Fields that are
+ * extremely long, such as text fields are automatically excluded to prevent
+ * long page loads.  Linking tables that have a many-to-one relationship with
+ * the record are also excluded.  This function allows for custom expansion
+ * of the record created by chado_generate_var() by specifyin the field and
+ * tables that should be added.
+ *
+ * Example Usage:
+ * @code
+ *  // Get a chado object to be expanded
+ *  $values = array(
+ *    'name' => 'Medtr4g030710'
+ *  );
+ *  $features = chado_generate_var('feature', $values);
+ *  // Expand the feature.residues field
+ *  $feature = chado_expand_var($feature, 'field', 'feature.residues');
+ *  // Expand the feature properties (featureprop table)
+ *  $feature = chado_expand_var($feature, 'table', 'featureprop');
+ * @endcode
+ *
+ * If a field is requested, it's value is added where it normally is expected
+ * in the record.  If a table is requested then a new key/value element is
+ * added to the record. The key is the table's name and the value is an
+ * array of records (of the same type created by chado_generate_var()). For
+ * example, expanding a 'feature' record to include a 'pub' record via the
+ * 'feature_pub' table.  The following provides a simple example for how
+ * the 'feature_pub' table is added.
+ *
+ * @code
+ * array(
+ *   'feature_id' => 1
+ *   'name' => 'blah',
+ *   'uniquename' => 'blah',
+ *   ....
+ *   'feature_pub => array(
+ *      [pub object],
+ *      [pub object],
+ *      [pub object],
+ *      [pub object],
+ *   )
+ * )
+ * @endcode
+ *
+ * where [pub object] is a record of a publication as created by
+ * chado_generate_var().
  *
- * This function exists to allow chado_generate_var() to excldue some
- * fields/tables/nodes from the default form of a variable without making it extremely difficult for
- * the tripal admin to get at these variables if he/she wants them.
+ * If the requested table has multiple foreign keys, such as the 'featureloc'
+ * or 'feature_genotype' tables, then an additional level is added to the
+ * array where the foreign key column names are added.  An example feature
+ * record with an expanded featureloc table is shown below:
+ *
+ * @code
+ * array(
+ *   'feature_id' => 1
+ *   'name' => 'blah',
+ *   'uniquename' => 'blah',
+ *   ....
+ *   'featureloc => array(
+ *      'srcfeature_id' => array(
+ *        [feature object],
+ *        ...
+ *      )
+ *      'feature_id' => array(
+ *        [feature object],
+ *        ...
+ *      )
+ *   )
+ * )
+ * @endcode
  *
  * @param $object
  *   This must be an object generated using chado_generate_var()
@@ -431,16 +534,16 @@ function chado_generate_var($table, $values, $base_options = array()) {
  *   - return_array:
  *     Additionally,  The option 'return_array' can be provided to force
  *     the function to expand tables as an array. Default behavior is to expand
- *     a table as single record if only one record exists or to expand as an array if
- *     multiple records exist.
+ *     a table as single record if only one record exists or to expand as an
+ *     array if multiple records exist.
  *   - include_fk:
  *     an array of FK relationships to follow. By default, the
  *     chado_expand_var function will follow all FK relationships but this
- *     may generate more queries then is desired slowing down this function call when
- *     there are lots of FK relationships to follow.  Provide an array specifying the
- *     fields to include.  For example, if expanding a property table (e.g. featureprop)
- *     and you want the CV and accession but do not want the DB the following
- *     array would work:
+ *     may generate more queries then is desired slowing down this function call
+ *     when there are lots of FK relationships to follow.  Provide an array
+ *     specifying the fields to include.  For example, if expanding a property
+ *     table (e.g. featureprop) and you want the CV and accession but do not
+ *     want the DB the following array would work:
  *        $table_options =  array(
  *          'include_fk' => array(
  *            'type_id' => array(
@@ -449,7 +552,6 @@ function chado_generate_var($table, $values, $base_options = array()) {
  *            )
  *          )
  *        );
- *
  *     The above array will expand the 'type_id' of the property table but only
  *     further expand the cv_id and the dbxref_id and will go no further.
  *   - pager:
@@ -473,20 +575,6 @@ function chado_generate_var($table, $values, $base_options = array()) {
  *   If the type is a table and it has already been expanded no changes is made to the
  *   returned object
  *
- * Example Usage:
- * @code
-   // Get a chado object to be expanded
-   $values = array(
-     'name' => 'Medtr4g030710'
-   );
-   $features = chado_generate_var('feature', $values);
-   // Expand the organism node
-   $feature = chado_expand_var($feature, 'node', 'organism');
-   // Expand the feature.residues field
-   $feature = chado_expand_var($feature, 'field', 'feature.residues');
-   // Expand the feature properties (featureprop table)
-   $feature = chado_expand_var($feature, 'table', 'featureprop');
- * @endcode
  *
  * @ingroup tripal_chado_query_api
  */

+ 4 - 2
tripal_core/api/tripal_core.custom_tables.api.inc

@@ -122,6 +122,8 @@ function chado_create_custom_table($table, $schema, $skip_if_exists = 1, $mview_
   global $databases;
   $created = 0;
   $recreated = 0;
+  $chado_schema = tripal_get_schema_name('chado');
+  $chado_dot = $chado_schema . '.';
 
   $transaction = db_transaction();
   try {
@@ -135,7 +137,7 @@ function chado_create_custom_table($table, $schema, $skip_if_exists = 1, $mview_
 
     // if the table does not exist then create it
     if (!$exists) {
-      $ret = db_create_table('chado.' . $table, $schema);
+      $ret = db_create_table($chado_dot . $table, $schema);
       $created = 1;
     }
 
@@ -150,7 +152,7 @@ function chado_create_custom_table($table, $schema, $skip_if_exists = 1, $mview_
       if (array_key_exists('referring_tables', $new_schema)) {
         unset($new_schema['referring_tables']);
       }
-      db_create_table('chado.' . $table, $new_schema);
+      db_create_table($chado_dot . $table, $new_schema);
       $recreated = 1;
     }
 

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

@@ -89,7 +89,7 @@ function tripal_get_files_dir($module_name = FALSE) {
     $data_dir .= "/$module_name";
 
     // Make sure the directory exists.
-    tripal_create_files_dir($module_name, "/$module_name");
+    tripal_create_files_dir($module_name);
 
   }
 
@@ -120,7 +120,7 @@ function tripal_get_files_stream($module_name = FALSE) {
     $stream .= "/$module_name";
 
     // Make sure the directory exists.
-    tripal_create_files_dir($module_name, "/$module_name");
+    tripal_create_files_dir($module_name);
   }
 
   return $stream;

+ 45 - 14
tripal_core/api/tripal_core.jobs.api.inc

@@ -73,17 +73,21 @@ function tripal_add_job($job_name, $modulename, $callback, $arguments, $uid, $pr
     $args = serialize($arguments);
   }
 
-  $record = new stdClass();
-  $record->job_name = $job_name;
-  $record->modulename = $modulename;
-  $record->callback = $callback;
-  $record->status = 'Waiting';
-  $record->submit_date = REQUEST_TIME;
-  $record->uid = $uid;
-  $record->priority = $priority;  # the lower the number the higher the priority
-  $record->arguments = $args;
-
-  if (drupal_write_record('tripal_jobs', $record)) {
+  $job_id = db_insert('tripal_jobs')
+    ->fields(array(
+      'job_name' => $job_name,
+      'modulename' => $modulename,
+      'callback' => $callback,
+      'status' => 'Waiting',
+      'submit_date' => REQUEST_TIME,
+      'uid' => $uid,
+      # The lower the number the higher the priority.
+      'priority' => $priority,
+      'arguments' => $args,
+    ))
+    ->execute();
+
+  if ($job_id) {
     drupal_set_message(t("Job '%job_name' submitted.", array('%job_name' => $job_name)));
     if (user_access('administer tripal')) {
       $jobs_url = url("admin/tripal/tripal_jobs");
@@ -95,10 +99,10 @@ function tripal_add_job($job_name, $modulename, $callback, $arguments, $uid, $pr
     }
   }
   else {
-    drupal_set_message(t("Failed to add job %job_name.", array('%job_name' => $job_name)), 'error');
+    drupal_set_message(t("Failed to add job: %job_name.", array('%job_name' => $job_name)), 'error');
   }
 
-  return $record->job_id;
+  return $job_id;
 }
 
 /**
@@ -138,7 +142,7 @@ function tripal_is_job_running() {
           "WHERE TJ.end_time IS NULL and NOT TJ.start_time IS NULL ";
   $jobs = db_query($sql);
   foreach ($jobs as $job) {
-    $status = `ps -p $job->pid -o pid=`;
+    $status = shell_exec('ps -p ' . escapeshellarg($job->pid) . ' -o pid=');
     if ($job->pid && $status) {
       // the job is still running so let it go
       // we return 1 to indicate that a job is running
@@ -273,6 +277,33 @@ function tripal_cancel_job($job_id, $redirect = TRUE) {
   }
 }
 
+
+/**
+ * Execute a specific Tripal Job.
+ *
+ * @param $job_id
+ *          The job id to be exeuted
+ * @param bool $redirect [optional]
+ *          Whether to redirect to the job page or not
+ */
+function tripal_execute_job($job_id, $redirect = TRUE) {
+  $sql = "SELECT * FROM {tripal_jobs} WHERE job_id = :job_id";
+  $results = db_query($sql, array(':job_id' => $job_id));
+  $job = $results->fetchObject();
+
+  // set the end time for this job
+  if ($job->start_time == 0 and $job->end_time == 0) {
+    tripal_launch_job(1, $job_id);
+  }
+  else {
+    drupal_set_message(t("Job %job_id cannot be executed. It has already finished.", array('%job_id' => $job_id)));
+  }
+
+  if ($redirect) {
+    drupal_goto("admin/tripal/tripal_jobs/view/$job_id");
+  }
+}
+
 /**
  * A function used to manually launch all queued tripal jobs
  *

+ 1 - 1
tripal_core/api/tripal_core.mviews.api.inc

@@ -400,7 +400,7 @@ function tripal_delete_mview($mview_id) {
   db_query($sql);
 
   // does the table already exist?
-  $mview_exists = db_table_exists('chado.' . $mview->mv_table);
+  $mview_exists = chado_table_exists($mview->mv_table);
 
   // drop the table from chado if it exists
   if ($mview_exists) {

+ 14 - 14
tripal_core/api/tripal_core.schema_v1.2.api.inc

@@ -2316,13 +2316,13 @@ function tripal_core_chado_schema_v1_2_cell_line_synonym() {
         'description' => '',
         'type' => 'boolean',
         'not null' => TRUE,
-        'default' => 'als',
+        'default' => FALSE,
       ),
       'is_internal' => array(
         'description' => '',
         'type' => 'boolean',
         'not null' => TRUE,
-        'default' => 'als',
+        'default' => FALSE,
       ),
     ),
     'primary key' => array(
@@ -4877,13 +4877,13 @@ function tripal_core_chado_schema_v1_2_feature() {
         'description' => '',
         'type' => 'boolean',
         'not null' => TRUE,
-        'default' => 'als',
+        'default' => FALSE,
       ),
       'is_obsolete' => array(
         'description' => '',
         'type' => 'boolean',
         'not null' => TRUE,
-        'default' => 'als',
+        'default' => FALSE,
       ),
       'timeaccessioned' => array(
         'description' => '',
@@ -5010,7 +5010,7 @@ function tripal_core_chado_schema_v1_2_feature_cvterm() {
         'description' => '',
         'type' => 'boolean',
         'not null' => TRUE,
-        'default' => 'als',
+        'default' => FALSE,
       ),
       'rank' => array(
         'description' => '',
@@ -6206,13 +6206,13 @@ function tripal_core_chado_schema_v1_2_feature_synonym() {
         'description' => '',
         'type' => 'boolean',
         'not null' => TRUE,
-        'default' => 'als',
+        'default' => FALSE,
       ),
       'is_internal' => array(
         'description' => '',
         'type' => 'boolean',
         'not null' => TRUE,
-        'default' => 'als',
+        'default' => FALSE,
       ),
     ),
     'primary key' => array(
@@ -6302,7 +6302,7 @@ function tripal_core_chado_schema_v1_2_featureloc() {
         'description' => '',
         'type' => 'boolean',
         'not null' => TRUE,
-        'default' => 'als',
+        'default' => FALSE,
       ),
       'fmax' => array(
         'description' => '',
@@ -6313,7 +6313,7 @@ function tripal_core_chado_schema_v1_2_featureloc() {
         'description' => '',
         'type' => 'boolean',
         'not null' => TRUE,
-        'default' => 'als',
+        'default' => FALSE,
       ),
       'strand' => array(
         'description' => '',
@@ -7542,7 +7542,7 @@ function tripal_core_chado_schema_v1_2_library_synonym() {
         'description' => '',
         'type' => 'boolean',
         'not null' => TRUE,
-        'default' => 'als',
+        'default' => FALSE,
       ),
     ),
     'primary key' => array(
@@ -11236,7 +11236,7 @@ function tripal_core_chado_schema_v1_2_pub() {
         'description' => '',
         'type' => 'boolean',
         'not null' => FALSE,
-        'default' => 'als',
+        'default' => FALSE,
       ),
       'publisher' => array(
         'description' => '',
@@ -11508,7 +11508,7 @@ function tripal_core_chado_schema_v1_2_pubauthor() {
         'description' => '',
         'type' => 'boolean',
         'not null' => FALSE,
-        'default' => 'als',
+        'default' => FALSE,
       ),
       'surname' => array(
         'description' => '',
@@ -11970,7 +11970,7 @@ function tripal_core_chado_schema_v1_2_stock() {
         'description' => '',
         'type' => 'boolean',
         'not null' => TRUE,
-        'default' => 'als',
+        'default' => FALSE,
       ),
     ),
     'primary key' => array(
@@ -12075,7 +12075,7 @@ function tripal_core_chado_schema_v1_2_stock_cvterm() {
         'description' => '',
         'type' => 'boolean',
         'not null' => TRUE,
-        'default' => 'als',
+        'default' => FALSE,
       ),
       'rank' => array(
         'description' => '',

+ 18249 - 0
tripal_core/api/tripal_core.schema_v1.3.api.inc

@@ -0,0 +1,18249 @@
+<?php
+/**
+ * @file
+ * Describes the chado tables in version 1.3
+ */
+
+/**
+ * @defgroup tripal_schema_v1_3_api Chado v1.3 Schema API
+ * @ingroup tripal_chado_schema_api
+ * @{
+ * Provides an application programming interface (API) for describing Chado
+ * tables. This API consists of a set of functions, one for each table in Chado.
+ * Each function simply returns a Drupal style array that defines the table.
+ *
+ * Because Drupal does not handle foreign key (FK) relationships, which are
+ * needed to for Tripal Views, they have been added to the schema defintitions
+ * below.
+ *
+ * The functions provided in this documentation should not be called as is,
+ * but if you need the Drupal-style array definition for any table, use the
+ * following function call:
+ *
+ *   $table_desc = chado_get_schema($table)
+ *
+ * where the variable $table contains the name of the table you want to
+ * retireve.  The chado_get_schema function determines the appropriate version
+ * of Chado and uses the Drupal hook infrastructure to call the appropriate
+ * hook function to retrieve the table schema.
+ *
+ * If you need to augment these schema definitions within your own module,
+ * you need to implement the hook_chado_schema_v1_3_[table name]() hook where
+ * [table name] is the name of the chado table whose schema definition you
+ * want to augment.
+ * @}
+ */
+
+/**
+ * Implements hook_chado_schema_v1_3_acquisition()
+ *
+ * Purpose: To describe the structure of 'acquisition' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'acquisition' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_acquisition() {
+  $description = array(
+    'description' => '',
+    'table' => 'acquisition',
+    'fields' => array(
+      'acquisition_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'assay_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'protocol_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'channel_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'acquisitiondate' => array(
+        'size' => 'normal',
+        'type' => 'datetime',
+        'not null' => FALSE,
+        'default' => 'now()',
+      ),
+      'name' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'uri' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+    ),
+    'unique keys' => array(
+      'acquisition_c1' => array(
+        0 => 'name',
+      ),
+    ),
+    'indexes' => array(
+      'acquisition_idx1' => array(
+        0 => 'assay_id',
+      ),
+      'acquisition_idx2' => array(
+        0 => 'protocol_id',
+      ),
+      'acquisition_idx3' => array(
+        0 => 'channel_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'acquisition_id',
+    ),
+    'foreign keys' => array(
+      'assay' => array(
+        'table' => 'assay',
+        'columns' => array(
+          'assay_id' => 'assay_id',
+        ),
+      ),
+      'protocol' => array(
+        'table' => 'protocol',
+        'columns' => array(
+          'protocol_id' => 'protocol_id',
+        ),
+      ),
+      'channel' => array(
+        'table' => 'channel',
+        'columns' => array(
+          'channel_id' => 'channel_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'acquisitionprop',
+      1 => 'acquisition_relationship',
+      3 => 'quantification',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_acquisitionprop()
+ *
+ * Purpose: To describe the structure of 'acquisitionprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'acquisitionprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_acquisitionprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'acquisitionprop',
+    'fields' => array(
+      'acquisitionprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'acquisition_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'acquisitionprop_c1' => array(
+        0 => 'acquisition_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'acquisitionprop_idx1' => array(
+        0 => 'acquisition_id',
+      ),
+      'acquisitionprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'acquisitionprop_id',
+    ),
+    'foreign keys' => array(
+      'acquisition' => array(
+        'table' => 'acquisition',
+        'columns' => array(
+          'acquisition_id' => 'acquisition_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_acquisition_relationship()
+ *
+ * Purpose: To describe the structure of 'acquisition_relationship' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'acquisition_relationship' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_acquisition_relationship() {
+  $description = array(
+    'description' => '',
+    'table' => 'acquisition_relationship',
+    'fields' => array(
+      'acquisition_relationship_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'subject_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'object_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'acquisition_relationship_c1' => array(
+        0 => 'subject_id',
+        1 => 'object_id',
+        2 => 'type_id',
+        3 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'acquisition_relationship_idx1' => array(
+        0 => 'subject_id',
+      ),
+      'acquisition_relationship_idx2' => array(
+        0 => 'type_id',
+      ),
+      'acquisition_relationship_idx3' => array(
+        0 => 'object_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'acquisition_relationship_id',
+    ),
+    'foreign keys' => array(
+      'acquisition' => array(
+        'table' => 'acquisition',
+        'columns' => array(
+          'subject_id' => 'acquisition_id',
+          'object_id' => 'acquisition_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_analysis()
+ *
+ * Purpose: To describe the structure of 'analysis' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'analysis' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_analysis() {
+  $description = array(
+    'description' => '',
+    'table' => 'analysis',
+    'fields' => array(
+      'analysis_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'name' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => FALSE,
+      ),
+      'description' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'program' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => TRUE,
+      ),
+      'programversion' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => TRUE,
+      ),
+      'algorithm' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => FALSE,
+      ),
+      'sourcename' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => FALSE,
+      ),
+      'sourceversion' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => FALSE,
+      ),
+      'sourceuri' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'timeexecuted' => array(
+        'size' => 'normal',
+        'type' => 'datetime',
+        'not null' => TRUE,
+        'default' => 'now()',
+      ),
+    ),
+    'unique keys' => array(
+      'analysis_c1' => array(
+        0 => 'program',
+        1 => 'programversion',
+        2 => 'sourcename',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'analysis_id',
+    ),
+    'foreign keys' => array(
+    ),
+    'referring_tables' => array(
+      0 => 'analysis_cvterm',
+      1 => 'analysis_dbxref',
+      2 => 'analysisfeature',
+      3 => 'analysis_organism',
+      4 => 'analysisprop',
+      5 => 'analysis_pub',
+      6 => 'analysis_relationship',
+      8 => 'nd_experiment_analysis',
+      9 => 'phylotree',
+      10 => 'project_analysis',
+      11 => 'quantification',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_analysis_cvterm()
+ *
+ * Purpose: To describe the structure of 'analysis_cvterm' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'analysis_cvterm' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_analysis_cvterm() {
+  $description = array(
+    'description' => '',
+    'table' => 'analysis_cvterm',
+    'fields' => array(
+      'analysis_cvterm_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'analysis_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'cvterm_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'is_not' => array(
+        'size' => 'normal',
+        'type' => 'boolean',
+        'not null' => TRUE,
+        'default' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'analysis_cvterm_c1' => array(
+        0 => 'analysis_id',
+        1 => 'cvterm_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'analysis_cvterm_idx1' => array(
+        0 => 'analysis_id',
+      ),
+      'analysis_cvterm_idx2' => array(
+        0 => 'cvterm_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'analysis_cvterm_id',
+    ),
+    'foreign keys' => array(
+      'analysis' => array(
+        'table' => 'analysis',
+        'columns' => array(
+          'analysis_id' => 'analysis_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'cvterm_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_analysis_dbxref()
+ *
+ * Purpose: To describe the structure of 'analysis_dbxref' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'analysis_dbxref' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_analysis_dbxref() {
+  $description = array(
+    'description' => '',
+    'table' => 'analysis_dbxref',
+    'fields' => array(
+      'analysis_dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'analysis_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'is_current' => array(
+        'size' => 'normal',
+        'type' => 'boolean',
+        'not null' => TRUE,
+        'default' => 'ru',
+      ),
+    ),
+    'unique keys' => array(
+      'analysis_dbxref_c1' => array(
+        0 => 'analysis_id',
+        1 => 'dbxref_id',
+      ),
+    ),
+    'indexes' => array(
+      'analysis_dbxref_idx1' => array(
+        0 => 'analysis_id',
+      ),
+      'analysis_dbxref_idx2' => array(
+        0 => 'dbxref_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'analysis_dbxref_id',
+    ),
+    'foreign keys' => array(
+      'analysis' => array(
+        'table' => 'analysis',
+        'columns' => array(
+          'analysis_id' => 'analysis_id',
+        ),
+      ),
+      'dbxref' => array(
+        'table' => 'dbxref',
+        'columns' => array(
+          'dbxref_id' => 'dbxref_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_analysisfeature()
+ *
+ * Purpose: To describe the structure of 'analysisfeature' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'analysisfeature' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_analysisfeature() {
+  $description = array(
+    'description' => '',
+    'table' => 'analysisfeature',
+    'fields' => array(
+      'analysisfeature_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'feature_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'analysis_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'rawscore' => array(
+        'size' => 'big',
+        'type' => 'float',
+        'not null' => FALSE,
+      ),
+      'normscore' => array(
+        'size' => 'big',
+        'type' => 'float',
+        'not null' => FALSE,
+      ),
+      'significance' => array(
+        'size' => 'big',
+        'type' => 'float',
+        'not null' => FALSE,
+      ),
+      'identity' => array(
+        'size' => 'big',
+        'type' => 'float',
+        'not null' => FALSE,
+      ),
+    ),
+    'unique keys' => array(
+      'analysisfeature_c1' => array(
+        0 => 'feature_id',
+        1 => 'analysis_id',
+      ),
+    ),
+    'indexes' => array(
+      'analysisfeature_idx1' => array(
+        0 => 'feature_id',
+      ),
+      'analysisfeature_idx2' => array(
+        0 => 'analysis_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'analysisfeature_id',
+    ),
+    'foreign keys' => array(
+      'feature' => array(
+        'table' => 'feature',
+        'columns' => array(
+          'feature_id' => 'feature_id',
+        ),
+      ),
+      'analysis' => array(
+        'table' => 'analysis',
+        'columns' => array(
+          'analysis_id' => 'analysis_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'analysisfeatureprop',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_analysisfeatureprop()
+ *
+ * Purpose: To describe the structure of 'analysisfeatureprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'analysisfeatureprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_analysisfeatureprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'analysisfeatureprop',
+    'fields' => array(
+      'analysisfeatureprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'analysisfeature_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'analysisfeature_id_type_id_rank' => array(
+        0 => 'analysisfeature_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'analysisfeatureprop_idx1' => array(
+        0 => 'analysisfeature_id',
+      ),
+      'analysisfeatureprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'analysisfeatureprop_id',
+    ),
+    'foreign keys' => array(
+      'analysisfeature' => array(
+        'table' => 'analysisfeature',
+        'columns' => array(
+          'analysisfeature_id' => 'analysisfeature_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_analysis_organism()
+ *
+ * Purpose: To describe the structure of 'analysis_organism' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'analysis_organism' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_analysis_organism() {
+  $description = array(
+    'description' => '',
+    'table' => 'analysis_organism',
+    'fields' => array(
+      'analysis_id' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'organism_id' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'indexes' => array(
+      'networkmod_qtl_indx0' => array(
+        0 => 'analysis_id',
+      ),
+      'networkmod_qtl_indx1' => array(
+        0 => 'organism_id',
+      ),
+    ),
+    'foreign keys' => array(
+      'analysis' => array(
+        'table' => 'analysis',
+        'columns' => array(
+          'analysis_id' => 'analysis_id',
+        ),
+      ),
+      'organism' => array(
+        'table' => 'organism',
+        'columns' => array(
+          'organism_id' => 'organism_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_analysisprop()
+ *
+ * Purpose: To describe the structure of 'analysisprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'analysisprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_analysisprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'analysisprop',
+    'fields' => array(
+      'analysisprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'analysis_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'analysisprop_c1' => array(
+        0 => 'analysis_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'analysisprop_idx1' => array(
+        0 => 'analysis_id',
+      ),
+      'analysisprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'analysisprop_id',
+    ),
+    'foreign keys' => array(
+      'analysis' => array(
+        'table' => 'analysis',
+        'columns' => array(
+          'analysis_id' => 'analysis_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_analysis_pub()
+ *
+ * Purpose: To describe the structure of 'analysis_pub' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'analysis_pub' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_analysis_pub() {
+  $description = array(
+    'description' => '',
+    'table' => 'analysis_pub',
+    'fields' => array(
+      'analysis_pub_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'analysis_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'analysis_pub_c1' => array(
+        0 => 'analysis_id',
+        1 => 'pub_id',
+      ),
+    ),
+    'indexes' => array(
+      'analysis_pub_idx1' => array(
+        0 => 'analysis_id',
+      ),
+      'analysis_pub_idx2' => array(
+        0 => 'pub_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'analysis_pub_id',
+    ),
+    'foreign keys' => array(
+      'analysis' => array(
+        'table' => 'analysis',
+        'columns' => array(
+          'analysis_id' => 'analysis_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_analysis_relationship()
+ *
+ * Purpose: To describe the structure of 'analysis_relationship' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'analysis_relationship' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_analysis_relationship() {
+  $description = array(
+    'description' => '',
+    'table' => 'analysis_relationship',
+    'fields' => array(
+      'analysis_relationship_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'subject_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'object_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'analysis_relationship_c1' => array(
+        0 => 'subject_id',
+        1 => 'object_id',
+        2 => 'type_id',
+        3 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'analysis_relationship_idx1' => array(
+        0 => 'subject_id',
+      ),
+      'analysis_relationship_idx2' => array(
+        0 => 'object_id',
+      ),
+      'analysis_relationship_idx3' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'analysis_relationship_id',
+    ),
+    'foreign keys' => array(
+      'analysis' => array(
+        'table' => 'analysis',
+        'columns' => array(
+          'subject_id' => 'analysis_id',
+          'object_id' => 'analysis_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_arraydesign()
+ *
+ * Purpose: To describe the structure of 'arraydesign' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'arraydesign' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_arraydesign() {
+  $description = array(
+    'description' => '',
+    'table' => 'arraydesign',
+    'fields' => array(
+      'arraydesign_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'manufacturer_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'platformtype_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'substratetype_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'protocol_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'name' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => TRUE,
+      ),
+      'version' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'description' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'array_dimensions' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'element_dimensions' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'num_of_elements' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'num_array_columns' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'num_array_rows' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'num_grid_columns' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'num_grid_rows' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'num_sub_columns' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'num_sub_rows' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+    ),
+    'unique keys' => array(
+      'arraydesign_c1' => array(
+        0 => 'name',
+      ),
+    ),
+    'indexes' => array(
+      'arraydesign_idx1' => array(
+        0 => 'manufacturer_id',
+      ),
+      'arraydesign_idx2' => array(
+        0 => 'platformtype_id',
+      ),
+      'arraydesign_idx3' => array(
+        0 => 'substratetype_id',
+      ),
+      'arraydesign_idx4' => array(
+        0 => 'protocol_id',
+      ),
+      'arraydesign_idx5' => array(
+        0 => 'dbxref_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'arraydesign_id',
+    ),
+    'foreign keys' => array(
+      'contact' => array(
+        'table' => 'contact',
+        'columns' => array(
+          'manufacturer_id' => 'contact_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'platformtype_id' => 'cvterm_id',
+          'substratetype_id' => 'cvterm_id',
+        ),
+      ),
+      'protocol' => array(
+        'table' => 'protocol',
+        'columns' => array(
+          'protocol_id' => 'protocol_id',
+        ),
+      ),
+      'dbxref' => array(
+        'table' => 'dbxref',
+        'columns' => array(
+          'dbxref_id' => 'dbxref_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'arraydesignprop',
+      1 => 'assay',
+      2 => 'element',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_arraydesignprop()
+ *
+ * Purpose: To describe the structure of 'arraydesignprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'arraydesignprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_arraydesignprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'arraydesignprop',
+    'fields' => array(
+      'arraydesignprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'arraydesign_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'arraydesignprop_c1' => array(
+        0 => 'arraydesign_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'arraydesignprop_idx1' => array(
+        0 => 'arraydesign_id',
+      ),
+      'arraydesignprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'arraydesignprop_id',
+    ),
+    'foreign keys' => array(
+      'arraydesign' => array(
+        'table' => 'arraydesign',
+        'columns' => array(
+          'arraydesign_id' => 'arraydesign_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_assay()
+ *
+ * Purpose: To describe the structure of 'assay' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'assay' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_assay() {
+  $description = array(
+    'description' => '',
+    'table' => 'assay',
+    'fields' => array(
+      'assay_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'arraydesign_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'protocol_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'assaydate' => array(
+        'size' => 'normal',
+        'type' => 'datetime',
+        'not null' => FALSE,
+        'default' => 'now()',
+      ),
+      'arrayidentifier' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'arraybatchidentifier' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'operator_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'name' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'description' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+    ),
+    'unique keys' => array(
+      'assay_c1' => array(
+        0 => 'name',
+      ),
+    ),
+    'indexes' => array(
+      'assay_idx1' => array(
+        0 => 'arraydesign_id',
+      ),
+      'assay_idx2' => array(
+        0 => 'protocol_id',
+      ),
+      'assay_idx3' => array(
+        0 => 'operator_id',
+      ),
+      'assay_idx4' => array(
+        0 => 'dbxref_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'assay_id',
+    ),
+    'foreign keys' => array(
+      'arraydesign' => array(
+        'table' => 'arraydesign',
+        'columns' => array(
+          'arraydesign_id' => 'arraydesign_id',
+        ),
+      ),
+      'protocol' => array(
+        'table' => 'protocol',
+        'columns' => array(
+          'protocol_id' => 'protocol_id',
+        ),
+      ),
+      'contact' => array(
+        'table' => 'contact',
+        'columns' => array(
+          'operator_id' => 'contact_id',
+        ),
+      ),
+      'dbxref' => array(
+        'table' => 'dbxref',
+        'columns' => array(
+          'dbxref_id' => 'dbxref_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'acquisition',
+      1 => 'assay_biomaterial',
+      2 => 'assay_project',
+      3 => 'assayprop',
+      4 => 'control',
+      5 => 'study_assay',
+      6 => 'studyfactorvalue',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_assay_biomaterial()
+ *
+ * Purpose: To describe the structure of 'assay_biomaterial' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'assay_biomaterial' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_assay_biomaterial() {
+  $description = array(
+    'description' => '',
+    'table' => 'assay_biomaterial',
+    'fields' => array(
+      'assay_biomaterial_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'assay_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'biomaterial_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'channel_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'assay_biomaterial_c1' => array(
+        0 => 'assay_id',
+        1 => 'biomaterial_id',
+        2 => 'channel_id',
+        3 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'assay_biomaterial_idx1' => array(
+        0 => 'assay_id',
+      ),
+      'assay_biomaterial_idx2' => array(
+        0 => 'biomaterial_id',
+      ),
+      'assay_biomaterial_idx3' => array(
+        0 => 'channel_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'assay_biomaterial_id',
+    ),
+    'foreign keys' => array(
+      'assay' => array(
+        'table' => 'assay',
+        'columns' => array(
+          'assay_id' => 'assay_id',
+        ),
+      ),
+      'biomaterial' => array(
+        'table' => 'biomaterial',
+        'columns' => array(
+          'biomaterial_id' => 'biomaterial_id',
+        ),
+      ),
+      'channel' => array(
+        'table' => 'channel',
+        'columns' => array(
+          'channel_id' => 'channel_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_assay_project()
+ *
+ * Purpose: To describe the structure of 'assay_project' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'assay_project' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_assay_project() {
+  $description = array(
+    'description' => '',
+    'table' => 'assay_project',
+    'fields' => array(
+      'assay_project_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'assay_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'project_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'assay_project_c1' => array(
+        0 => 'assay_id',
+        1 => 'project_id',
+      ),
+    ),
+    'indexes' => array(
+      'assay_project_idx1' => array(
+        0 => 'assay_id',
+      ),
+      'assay_project_idx2' => array(
+        0 => 'project_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'assay_project_id',
+    ),
+    'foreign keys' => array(
+      'assay' => array(
+        'table' => 'assay',
+        'columns' => array(
+          'assay_id' => 'assay_id',
+        ),
+      ),
+      'project' => array(
+        'table' => 'project',
+        'columns' => array(
+          'project_id' => 'project_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_assayprop()
+ *
+ * Purpose: To describe the structure of 'assayprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'assayprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_assayprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'assayprop',
+    'fields' => array(
+      'assayprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'assay_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'assayprop_c1' => array(
+        0 => 'assay_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'assayprop_idx1' => array(
+        0 => 'assay_id',
+      ),
+      'assayprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'assayprop_id',
+    ),
+    'foreign keys' => array(
+      'assay' => array(
+        'table' => 'assay',
+        'columns' => array(
+          'assay_id' => 'assay_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_biomaterial()
+ *
+ * Purpose: To describe the structure of 'biomaterial' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'biomaterial' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_biomaterial() {
+  $description = array(
+    'description' => '',
+    'table' => 'biomaterial',
+    'fields' => array(
+      'biomaterial_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'taxon_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'biosourceprovider_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'name' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'description' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+    ),
+    'unique keys' => array(
+      'biomaterial_c1' => array(
+        0 => 'name',
+      ),
+    ),
+    'indexes' => array(
+      'biomaterial_idx1' => array(
+        0 => 'taxon_id',
+      ),
+      'biomaterial_idx2' => array(
+        0 => 'biosourceprovider_id',
+      ),
+      'biomaterial_idx3' => array(
+        0 => 'dbxref_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'biomaterial_id',
+    ),
+    'foreign keys' => array(
+      'organism' => array(
+        'table' => 'organism',
+        'columns' => array(
+          'taxon_id' => 'organism_id',
+        ),
+      ),
+      'contact' => array(
+        'table' => 'contact',
+        'columns' => array(
+          'biosourceprovider_id' => 'contact_id',
+        ),
+      ),
+      'dbxref' => array(
+        'table' => 'dbxref',
+        'columns' => array(
+          'dbxref_id' => 'dbxref_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'assay_biomaterial',
+      1 => 'biomaterial_dbxref',
+      2 => 'biomaterialprop',
+      3 => 'biomaterial_relationship',
+      5 => 'biomaterial_treatment',
+      6 => 'treatment',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_biomaterial_dbxref()
+ *
+ * Purpose: To describe the structure of 'biomaterial_dbxref' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'biomaterial_dbxref' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_biomaterial_dbxref() {
+  $description = array(
+    'description' => '',
+    'table' => 'biomaterial_dbxref',
+    'fields' => array(
+      'biomaterial_dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'biomaterial_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'biomaterial_dbxref_c1' => array(
+        0 => 'biomaterial_id',
+        1 => 'dbxref_id',
+      ),
+    ),
+    'indexes' => array(
+      'biomaterial_dbxref_idx1' => array(
+        0 => 'biomaterial_id',
+      ),
+      'biomaterial_dbxref_idx2' => array(
+        0 => 'dbxref_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'biomaterial_dbxref_id',
+    ),
+    'foreign keys' => array(
+      'biomaterial' => array(
+        'table' => 'biomaterial',
+        'columns' => array(
+          'biomaterial_id' => 'biomaterial_id',
+        ),
+      ),
+      'dbxref' => array(
+        'table' => 'dbxref',
+        'columns' => array(
+          'dbxref_id' => 'dbxref_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_biomaterialprop()
+ *
+ * Purpose: To describe the structure of 'biomaterialprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'biomaterialprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_biomaterialprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'biomaterialprop',
+    'fields' => array(
+      'biomaterialprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'biomaterial_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'biomaterialprop_c1' => array(
+        0 => 'biomaterial_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'biomaterialprop_idx1' => array(
+        0 => 'biomaterial_id',
+      ),
+      'biomaterialprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'biomaterialprop_id',
+    ),
+    'foreign keys' => array(
+      'biomaterial' => array(
+        'table' => 'biomaterial',
+        'columns' => array(
+          'biomaterial_id' => 'biomaterial_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_biomaterial_relationship()
+ *
+ * Purpose: To describe the structure of 'biomaterial_relationship' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'biomaterial_relationship' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_biomaterial_relationship() {
+  $description = array(
+    'description' => '',
+    'table' => 'biomaterial_relationship',
+    'fields' => array(
+      'biomaterial_relationship_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'subject_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'object_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'biomaterial_relationship_c1' => array(
+        0 => 'subject_id',
+        1 => 'object_id',
+        2 => 'type_id',
+      ),
+    ),
+    'indexes' => array(
+      'biomaterial_relationship_idx1' => array(
+        0 => 'subject_id',
+      ),
+      'biomaterial_relationship_idx2' => array(
+        0 => 'object_id',
+      ),
+      'biomaterial_relationship_idx3' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'biomaterial_relationship_id',
+    ),
+    'foreign keys' => array(
+      'biomaterial' => array(
+        'table' => 'biomaterial',
+        'columns' => array(
+          'subject_id' => 'biomaterial_id',
+          'object_id' => 'biomaterial_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_biomaterial_treatment()
+ *
+ * Purpose: To describe the structure of 'biomaterial_treatment' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'biomaterial_treatment' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_biomaterial_treatment() {
+  $description = array(
+    'description' => '',
+    'table' => 'biomaterial_treatment',
+    'fields' => array(
+      'biomaterial_treatment_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'biomaterial_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'treatment_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'unittype_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'float',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'biomaterial_treatment_c1' => array(
+        0 => 'biomaterial_id',
+        1 => 'treatment_id',
+      ),
+    ),
+    'indexes' => array(
+      'biomaterial_treatment_idx1' => array(
+        0 => 'biomaterial_id',
+      ),
+      'biomaterial_treatment_idx2' => array(
+        0 => 'treatment_id',
+      ),
+      'biomaterial_treatment_idx3' => array(
+        0 => 'unittype_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'biomaterial_treatment_id',
+    ),
+    'foreign keys' => array(
+      'biomaterial' => array(
+        'table' => 'biomaterial',
+        'columns' => array(
+          'biomaterial_id' => 'biomaterial_id',
+        ),
+      ),
+      'treatment' => array(
+        'table' => 'treatment',
+        'columns' => array(
+          'treatment_id' => 'treatment_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'unittype_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_cell_line()
+ *
+ * Purpose: To describe the structure of 'cell_line' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'cell_line' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_cell_line() {
+  $description = array(
+    'description' => '',
+    'table' => 'cell_line',
+    'fields' => array(
+      'cell_line_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'name' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => FALSE,
+      ),
+      'uniquename' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => TRUE,
+      ),
+      'organism_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'timeaccessioned' => array(
+        'size' => 'normal',
+        'type' => 'datetime',
+        'not null' => TRUE,
+        'default' => 'now()',
+      ),
+      'timelastmodified' => array(
+        'size' => 'normal',
+        'type' => 'datetime',
+        'not null' => TRUE,
+        'default' => 'now()',
+      ),
+    ),
+    'unique keys' => array(
+      'cell_line_c1' => array(
+        0 => 'uniquename',
+        1 => 'organism_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'cell_line_id',
+    ),
+    'foreign keys' => array(
+      'organism' => array(
+        'table' => 'organism',
+        'columns' => array(
+          'organism_id' => 'organism_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'cell_line_cvterm',
+      1 => 'cell_line_dbxref',
+      2 => 'cell_line_feature',
+      3 => 'cell_line_library',
+      4 => 'cell_lineprop',
+      5 => 'cell_line_pub',
+      6 => 'cell_line_relationship',
+      8 => 'cell_line_synonym',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_cell_line_cvterm()
+ *
+ * Purpose: To describe the structure of 'cell_line_cvterm' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'cell_line_cvterm' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_cell_line_cvterm() {
+  $description = array(
+    'description' => '',
+    'table' => 'cell_line_cvterm',
+    'fields' => array(
+      'cell_line_cvterm_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'cell_line_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'cvterm_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'cell_line_cvterm_c1' => array(
+        0 => 'cell_line_id',
+        1 => 'cvterm_id',
+        2 => 'pub_id',
+        3 => 'rank',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'cell_line_cvterm_id',
+    ),
+    'foreign keys' => array(
+      'cell_line' => array(
+        'table' => 'cell_line',
+        'columns' => array(
+          'cell_line_id' => 'cell_line_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'cvterm_id' => 'cvterm_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'cell_line_cvtermprop',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_cell_line_cvtermprop()
+ *
+ * Purpose: To describe the structure of 'cell_line_cvtermprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'cell_line_cvtermprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_cell_line_cvtermprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'cell_line_cvtermprop',
+    'fields' => array(
+      'cell_line_cvtermprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'cell_line_cvterm_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'cell_line_cvtermprop_c1' => array(
+        0 => 'cell_line_cvterm_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'cell_line_cvtermprop_id',
+    ),
+    'foreign keys' => array(
+      'cell_line_cvterm' => array(
+        'table' => 'cell_line_cvterm',
+        'columns' => array(
+          'cell_line_cvterm_id' => 'cell_line_cvterm_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_cell_line_dbxref()
+ *
+ * Purpose: To describe the structure of 'cell_line_dbxref' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'cell_line_dbxref' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_cell_line_dbxref() {
+  $description = array(
+    'description' => '',
+    'table' => 'cell_line_dbxref',
+    'fields' => array(
+      'cell_line_dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'cell_line_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'is_current' => array(
+        'size' => 'normal',
+        'type' => 'boolean',
+        'not null' => TRUE,
+        'default' => 'ru',
+      ),
+    ),
+    'unique keys' => array(
+      'cell_line_dbxref_c1' => array(
+        0 => 'cell_line_id',
+        1 => 'dbxref_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'cell_line_dbxref_id',
+    ),
+    'foreign keys' => array(
+      'cell_line' => array(
+        'table' => 'cell_line',
+        'columns' => array(
+          'cell_line_id' => 'cell_line_id',
+        ),
+      ),
+      'dbxref' => array(
+        'table' => 'dbxref',
+        'columns' => array(
+          'dbxref_id' => 'dbxref_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_cell_line_feature()
+ *
+ * Purpose: To describe the structure of 'cell_line_feature' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'cell_line_feature' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_cell_line_feature() {
+  $description = array(
+    'description' => '',
+    'table' => 'cell_line_feature',
+    'fields' => array(
+      'cell_line_feature_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'cell_line_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'feature_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'cell_line_feature_c1' => array(
+        0 => 'cell_line_id',
+        1 => 'feature_id',
+        2 => 'pub_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'cell_line_feature_id',
+    ),
+    'foreign keys' => array(
+      'cell_line' => array(
+        'table' => 'cell_line',
+        'columns' => array(
+          'cell_line_id' => 'cell_line_id',
+        ),
+      ),
+      'feature' => array(
+        'table' => 'feature',
+        'columns' => array(
+          'feature_id' => 'feature_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_cell_line_library()
+ *
+ * Purpose: To describe the structure of 'cell_line_library' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'cell_line_library' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_cell_line_library() {
+  $description = array(
+    'description' => '',
+    'table' => 'cell_line_library',
+    'fields' => array(
+      'cell_line_library_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'cell_line_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'library_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'cell_line_library_c1' => array(
+        0 => 'cell_line_id',
+        1 => 'library_id',
+        2 => 'pub_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'cell_line_library_id',
+    ),
+    'foreign keys' => array(
+      'cell_line' => array(
+        'table' => 'cell_line',
+        'columns' => array(
+          'cell_line_id' => 'cell_line_id',
+        ),
+      ),
+      'library' => array(
+        'table' => 'library',
+        'columns' => array(
+          'library_id' => 'library_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_cell_lineprop()
+ *
+ * Purpose: To describe the structure of 'cell_lineprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'cell_lineprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_cell_lineprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'cell_lineprop',
+    'fields' => array(
+      'cell_lineprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'cell_line_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'cell_lineprop_c1' => array(
+        0 => 'cell_line_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'cell_lineprop_id',
+    ),
+    'foreign keys' => array(
+      'cell_line' => array(
+        'table' => 'cell_line',
+        'columns' => array(
+          'cell_line_id' => 'cell_line_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'cell_lineprop_pub',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_cell_lineprop_pub()
+ *
+ * Purpose: To describe the structure of 'cell_lineprop_pub' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'cell_lineprop_pub' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_cell_lineprop_pub() {
+  $description = array(
+    'description' => '',
+    'table' => 'cell_lineprop_pub',
+    'fields' => array(
+      'cell_lineprop_pub_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'cell_lineprop_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'cell_lineprop_pub_c1' => array(
+        0 => 'cell_lineprop_id',
+        1 => 'pub_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'cell_lineprop_pub_id',
+    ),
+    'foreign keys' => array(
+      'cell_lineprop' => array(
+        'table' => 'cell_lineprop',
+        'columns' => array(
+          'cell_lineprop_id' => 'cell_lineprop_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_cell_line_pub()
+ *
+ * Purpose: To describe the structure of 'cell_line_pub' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'cell_line_pub' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_cell_line_pub() {
+  $description = array(
+    'description' => '',
+    'table' => 'cell_line_pub',
+    'fields' => array(
+      'cell_line_pub_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'cell_line_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'cell_line_pub_c1' => array(
+        0 => 'cell_line_id',
+        1 => 'pub_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'cell_line_pub_id',
+    ),
+    'foreign keys' => array(
+      'cell_line' => array(
+        'table' => 'cell_line',
+        'columns' => array(
+          'cell_line_id' => 'cell_line_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_cell_line_relationship()
+ *
+ * Purpose: To describe the structure of 'cell_line_relationship' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'cell_line_relationship' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_cell_line_relationship() {
+  $description = array(
+    'description' => '',
+    'table' => 'cell_line_relationship',
+    'fields' => array(
+      'cell_line_relationship_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'subject_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'object_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'cell_line_relationship_c1' => array(
+        0 => 'subject_id',
+        1 => 'object_id',
+        2 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'cell_line_relationship_id',
+    ),
+    'foreign keys' => array(
+      'cell_line' => array(
+        'table' => 'cell_line',
+        'columns' => array(
+          'subject_id' => 'cell_line_id',
+          'object_id' => 'cell_line_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_cell_line_synonym()
+ *
+ * Purpose: To describe the structure of 'cell_line_synonym' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'cell_line_synonym' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_cell_line_synonym() {
+  $description = array(
+    'description' => '',
+    'table' => 'cell_line_synonym',
+    'fields' => array(
+      'cell_line_synonym_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'cell_line_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'synonym_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'is_current' => array(
+        'size' => 'normal',
+        'type' => 'boolean',
+        'not null' => TRUE,
+        'default' => FALSE,
+      ),
+      'is_internal' => array(
+        'size' => 'normal',
+        'type' => 'boolean',
+        'not null' => TRUE,
+        'default' => FALSE,
+      ),
+    ),
+    'unique keys' => array(
+      'cell_line_synonym_c1' => array(
+        0 => 'synonym_id',
+        1 => 'cell_line_id',
+        2 => 'pub_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'cell_line_synonym_id',
+    ),
+    'foreign keys' => array(
+      'cell_line' => array(
+        'table' => 'cell_line',
+        'columns' => array(
+          'cell_line_id' => 'cell_line_id',
+        ),
+      ),
+      'synonym' => array(
+        'table' => 'synonym',
+        'columns' => array(
+          'synonym_id' => 'synonym_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_chadoprop()
+ *
+ * Purpose: To describe the structure of 'chadoprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'chadoprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_chadoprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'chadoprop',
+    'fields' => array(
+      'chadoprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'chadoprop_c1' => array(
+        0 => 'type_id',
+        1 => 'rank',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'chadoprop_id',
+    ),
+    'foreign keys' => array(
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_channel()
+ *
+ * Purpose: To describe the structure of 'channel' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'channel' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_channel() {
+  $description = array(
+    'description' => '',
+    'table' => 'channel',
+    'fields' => array(
+      'channel_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'name' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => TRUE,
+      ),
+      'definition' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'channel_c1' => array(
+        0 => 'name',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'channel_id',
+    ),
+    'foreign keys' => array(
+    ),
+    'referring_tables' => array(
+      0 => 'acquisition',
+      1 => 'assay_biomaterial',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_contact()
+ *
+ * Purpose: To describe the structure of 'contact' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'contact' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_contact() {
+  $description = array(
+    'description' => '',
+    'table' => 'contact',
+    'fields' => array(
+      'contact_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'name' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => TRUE,
+      ),
+      'description' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => FALSE,
+      ),
+    ),
+    'unique keys' => array(
+      'contact_c1' => array(
+        0 => 'name',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'contact_id',
+    ),
+    'indexes' => array(
+      'library_contact_idx2' => array(
+        0 => 'contact_id',
+      ),
+      'pubauthor_contact_idx2' => array(
+        0 => 'contact_id',
+      ),
+    ),
+    'foreign keys' => array(
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'arraydesign',
+      1 => 'assay',
+      2 => 'biomaterial',
+      3 => 'contactprop',
+      4 => 'contact_relationship',
+      6 => 'feature_contact',
+      7 => 'featuremap_contact',
+      8 => 'library_contact',
+      9 => 'nd_experiment_contact',
+      10 => 'project_contact',
+      11 => 'pubauthor_contact',
+      12 => 'quantification',
+      13 => 'stockcollection',
+      14 => 'study',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_contactprop()
+ *
+ * Purpose: To describe the structure of 'contactprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'contactprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_contactprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'contactprop',
+    'fields' => array(
+      'contactprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'contact_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'contactprop_c1' => array(
+        0 => 'contact_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'contactprop_idx1' => array(
+        0 => 'contact_id',
+      ),
+      'contactprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'contactprop_id',
+    ),
+    'foreign keys' => array(
+      'contact' => array(
+        'table' => 'contact',
+        'columns' => array(
+          'contact_id' => 'contact_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_contact_relationship()
+ *
+ * Purpose: To describe the structure of 'contact_relationship' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'contact_relationship' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_contact_relationship() {
+  $description = array(
+    'description' => '',
+    'table' => 'contact_relationship',
+    'fields' => array(
+      'contact_relationship_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'subject_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'object_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'contact_relationship_c1' => array(
+        0 => 'subject_id',
+        1 => 'object_id',
+        2 => 'type_id',
+      ),
+    ),
+    'indexes' => array(
+      'contact_relationship_idx1' => array(
+        0 => 'type_id',
+      ),
+      'contact_relationship_idx2' => array(
+        0 => 'subject_id',
+      ),
+      'contact_relationship_idx3' => array(
+        0 => 'object_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'contact_relationship_id',
+    ),
+    'foreign keys' => array(
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+      'contact' => array(
+        'table' => 'contact',
+        'columns' => array(
+          'subject_id' => 'contact_id',
+          'object_id' => 'contact_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_control()
+ *
+ * Purpose: To describe the structure of 'control' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'control' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_control() {
+  $description = array(
+    'description' => '',
+    'table' => 'control',
+    'fields' => array(
+      'control_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'assay_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'tableinfo_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'row_id' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'name' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'indexes' => array(
+      'control_idx1' => array(
+        0 => 'type_id',
+      ),
+      'control_idx2' => array(
+        0 => 'assay_id',
+      ),
+      'control_idx3' => array(
+        0 => 'tableinfo_id',
+      ),
+      'control_idx4' => array(
+        0 => 'row_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'control_id',
+    ),
+    'foreign keys' => array(
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+      'assay' => array(
+        'table' => 'assay',
+        'columns' => array(
+          'assay_id' => 'assay_id',
+        ),
+      ),
+      'tableinfo' => array(
+        'table' => 'tableinfo',
+        'columns' => array(
+          'tableinfo_id' => 'tableinfo_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_cv()
+ *
+ * Purpose: To describe the structure of 'cv' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'cv' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_cv() {
+  $description = array(
+    'description' => '',
+    'table' => 'cv',
+    'fields' => array(
+      'cv_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'name' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => TRUE,
+      ),
+      'definition' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+    ),
+    'unique keys' => array(
+      'cv_c1' => array(
+        0 => 'name',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'cv_id',
+    ),
+    'foreign keys' => array(
+    ),
+    'referring_tables' => array(
+      0 => 'cvprop',
+      1 => 'cvterm',
+      2 => 'cvtermpath',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_cvprop()
+ *
+ * Purpose: To describe the structure of 'cvprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'cvprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_cvprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'cvprop',
+    'fields' => array(
+      'cvprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'cv_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'cvprop_c1' => array(
+        0 => 'cv_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'cvprop_id',
+    ),
+    'foreign keys' => array(
+      'cv' => array(
+        'table' => 'cv',
+        'columns' => array(
+          'cv_id' => 'cv_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_cv_root_mview()
+ *
+ * Purpose: To describe the structure of 'cv_root_mview' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'cv_root_mview' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_cv_root_mview() {
+  $description = array(
+    'description' => '',
+    'table' => 'cv_root_mview',
+    'fields' => array(
+      'name' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => TRUE,
+      ),
+      'cvterm_id' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'cv_id' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'cv_name' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => TRUE,
+      ),
+    ),
+    'indexes' => array(
+      'cv_root_mview_indx1' => array(
+        0 => 'cvterm_id',
+      ),
+      'cv_root_mview_indx2' => array(
+        0 => 'cv_id',
+      ),
+    ),
+    'foreign keys' => array(
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_cvterm()
+ *
+ * Purpose: To describe the structure of 'cvterm' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'cvterm' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_cvterm() {
+  $description = array(
+    'description' => '',
+    'table' => 'cvterm',
+    'fields' => array(
+      'cvterm_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'cv_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'name' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '1024',
+        'not null' => TRUE,
+      ),
+      'definition' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'is_obsolete' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'is_relationshiptype' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'cvterm_c1' => array(
+        0 => 'name',
+        1 => 'cv_id',
+        2 => 'is_obsolete',
+      ),
+      'cvterm_c2' => array(
+        0 => 'dbxref_id',
+      ),
+    ),
+    'indexes' => array(
+      'cvterm_idx1' => array(
+        0 => 'cv_id',
+      ),
+      'cvterm_idx2' => array(
+        0 => 'name',
+      ),
+      'cvterm_idx3' => array(
+        0 => 'dbxref_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'cvterm_id',
+    ),
+    'foreign keys' => array(
+      'cv' => array(
+        'table' => 'cv',
+        'columns' => array(
+          'cv_id' => 'cv_id',
+        ),
+      ),
+      'dbxref' => array(
+        'table' => 'dbxref',
+        'columns' => array(
+          'dbxref_id' => 'dbxref_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'acquisitionprop',
+      1 => 'acquisition_relationship',
+      2 => 'analysis_cvterm',
+      3 => 'analysisfeatureprop',
+      4 => 'analysisprop',
+      5 => 'analysis_relationship',
+      6 => 'arraydesign',
+      8 => 'arraydesignprop',
+      9 => 'assayprop',
+      10 => 'biomaterialprop',
+      11 => 'biomaterial_relationship',
+      12 => 'biomaterial_treatment',
+      13 => 'cell_line_cvterm',
+      14 => 'cell_line_cvtermprop',
+      15 => 'cell_lineprop',
+      16 => 'cell_line_relationship',
+      17 => 'chadoprop',
+      18 => 'contact',
+      19 => 'contactprop',
+      20 => 'contact_relationship',
+      21 => 'control',
+      22 => 'cvprop',
+      23 => 'cvterm_dbxref',
+      24 => 'cvtermpath',
+      27 => 'cvtermprop',
+      29 => 'cvterm_relationship',
+      32 => 'cvtermsynonym',
+      34 => 'dbprop',
+      35 => 'dbxrefprop',
+      36 => 'element',
+      37 => 'element_relationship',
+      38 => 'elementresult_relationship',
+      39 => 'environment_cvterm',
+      40 => 'expression_cvterm',
+      42 => 'expression_cvtermprop',
+      43 => 'expressionprop',
+      44 => 'feature',
+      45 => 'feature_cvterm',
+      46 => 'feature_cvtermprop',
+      47 => 'feature_expressionprop',
+      48 => 'feature_genotype',
+      49 => 'featuremap',
+      50 => 'featuremapprop',
+      51 => 'featureposprop',
+      52 => 'featureprop',
+      53 => 'feature_pubprop',
+      54 => 'feature_relationship',
+      55 => 'feature_relationshipprop',
+      56 => 'genotype',
+      57 => 'genotypeprop',
+      58 => 'library',
+      59 => 'library_cvterm',
+      60 => 'library_expressionprop',
+      61 => 'library_featureprop',
+      62 => 'libraryprop',
+      63 => 'library_relationship',
+      64 => 'nd_experiment',
+      65 => 'nd_experiment_analysis',
+      66 => 'nd_experimentprop',
+      67 => 'nd_experiment_stock',
+      68 => 'nd_experiment_stockprop',
+      69 => 'nd_geolocationprop',
+      70 => 'nd_protocol',
+      71 => 'nd_protocolprop',
+      72 => 'nd_protocol_reagent',
+      73 => 'nd_reagent',
+      74 => 'nd_reagentprop',
+      75 => 'nd_reagent_relationship',
+      76 => 'organism',
+      77 => 'organism_cvterm',
+      78 => 'organism_cvtermprop',
+      79 => 'organismprop',
+      80 => 'organism_relationship',
+      81 => 'phendesc',
+      82 => 'phenotype',
+      86 => 'phenotype_comparison_cvterm',
+      87 => 'phenotype_cvterm',
+      88 => 'phenotypeprop',
+      89 => 'phenstatement',
+      90 => 'phylonode',
+      91 => 'phylonodeprop',
+      92 => 'phylonode_relationship',
+      93 => 'phylotree',
+      94 => 'phylotreeprop',
+      95 => 'projectprop',
+      96 => 'project_relationship',
+      97 => 'protocol',
+      98 => 'protocolparam',
+      100 => 'pub',
+      101 => 'pubprop',
+      102 => 'pub_relationship',
+      103 => 'quantificationprop',
+      104 => 'quantification_relationship',
+      105 => 'stock',
+      106 => 'stockcollection',
+      107 => 'stockcollectionprop',
+      108 => 'stock_cvterm',
+      109 => 'stock_cvtermprop',
+      110 => 'stock_dbxrefprop',
+      111 => 'stock_feature',
+      112 => 'stock_featuremap',
+      113 => 'stockprop',
+      114 => 'stock_relationship',
+      115 => 'stock_relationship_cvterm',
+      116 => 'studydesignprop',
+      117 => 'studyfactor',
+      118 => 'studyprop',
+      119 => 'studyprop_feature',
+      120 => 'synonym',
+      121 => 'treatment',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_cvterm_dbxref()
+ *
+ * Purpose: To describe the structure of 'cvterm_dbxref' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'cvterm_dbxref' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_cvterm_dbxref() {
+  $description = array(
+    'description' => '',
+    'table' => 'cvterm_dbxref',
+    'fields' => array(
+      'cvterm_dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'cvterm_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'is_for_definition' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'cvterm_dbxref_c1' => array(
+        0 => 'cvterm_id',
+        1 => 'dbxref_id',
+      ),
+    ),
+    'indexes' => array(
+      'cvterm_dbxref_idx1' => array(
+        0 => 'cvterm_id',
+      ),
+      'cvterm_dbxref_idx2' => array(
+        0 => 'dbxref_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'cvterm_dbxref_id',
+    ),
+    'foreign keys' => array(
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'cvterm_id' => 'cvterm_id',
+        ),
+      ),
+      'dbxref' => array(
+        'table' => 'dbxref',
+        'columns' => array(
+          'dbxref_id' => 'dbxref_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_cvtermpath()
+ *
+ * Purpose: To describe the structure of 'cvtermpath' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'cvtermpath' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_cvtermpath() {
+  $description = array(
+    'description' => '',
+    'table' => 'cvtermpath',
+    'fields' => array(
+      'cvtermpath_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'subject_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'object_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'cv_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pathdistance' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+    ),
+    'unique keys' => array(
+      'cvtermpath_c1' => array(
+        0 => 'subject_id',
+        1 => 'object_id',
+        2 => 'type_id',
+        3 => 'pathdistance',
+      ),
+    ),
+    'indexes' => array(
+      'cvtermpath_idx1' => array(
+        0 => 'type_id',
+      ),
+      'cvtermpath_idx2' => array(
+        0 => 'subject_id',
+      ),
+      'cvtermpath_idx3' => array(
+        0 => 'object_id',
+      ),
+      'cvtermpath_idx4' => array(
+        0 => 'cv_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'cvtermpath_id',
+    ),
+    'foreign keys' => array(
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+          'subject_id' => 'cvterm_id',
+          'object_id' => 'cvterm_id',
+        ),
+      ),
+      'cv' => array(
+        'table' => 'cv',
+        'columns' => array(
+          'cv_id' => 'cv_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_cvtermprop()
+ *
+ * Purpose: To describe the structure of 'cvtermprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'cvtermprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_cvtermprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'cvtermprop',
+    'fields' => array(
+      'cvtermprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'cvterm_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'cvterm_id_type_id_value_rank' => array(
+        0 => 'cvterm_id',
+        1 => 'type_id',
+        2 => 'value',
+        3 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'cvtermprop_idx1' => array(
+        0 => 'cvterm_id',
+      ),
+      'cvtermprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'cvtermprop_id',
+    ),
+    'foreign keys' => array(
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'cvterm_id' => 'cvterm_id',
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_cvterm_relationship()
+ *
+ * Purpose: To describe the structure of 'cvterm_relationship' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'cvterm_relationship' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_cvterm_relationship() {
+  $description = array(
+    'description' => '',
+    'table' => 'cvterm_relationship',
+    'fields' => array(
+      'cvterm_relationship_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'subject_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'object_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'cvterm_relationship_c1' => array(
+        0 => 'subject_id',
+        1 => 'object_id',
+        2 => 'type_id',
+      ),
+    ),
+    'indexes' => array(
+      'cvterm_relationship_idx1' => array(
+        0 => 'type_id',
+      ),
+      'cvterm_relationship_idx2' => array(
+        0 => 'subject_id',
+      ),
+      'cvterm_relationship_idx3' => array(
+        0 => 'object_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'cvterm_relationship_id',
+    ),
+    'foreign keys' => array(
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+          'subject_id' => 'cvterm_id',
+          'object_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_cvtermsynonym()
+ *
+ * Purpose: To describe the structure of 'cvtermsynonym' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'cvtermsynonym' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_cvtermsynonym() {
+  $description = array(
+    'description' => '',
+    'table' => 'cvtermsynonym',
+    'fields' => array(
+      'cvtermsynonym_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'cvterm_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'synonym' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '1024',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+    ),
+    'unique keys' => array(
+      'cvtermsynonym_c1' => array(
+        0 => 'cvterm_id',
+        1 => 'synonym',
+      ),
+    ),
+    'indexes' => array(
+      'cvtermsynonym_idx1' => array(
+        0 => 'cvterm_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'cvtermsynonym_id',
+    ),
+    'foreign keys' => array(
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'cvterm_id' => 'cvterm_id',
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_db()
+ *
+ * Purpose: To describe the structure of 'db' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'db' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_db() {
+  $description = array(
+    'description' => '',
+    'table' => 'db',
+    'fields' => array(
+      'db_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'name' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => TRUE,
+      ),
+      'description' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => FALSE,
+      ),
+      'urlprefix' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => FALSE,
+      ),
+      'url' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => FALSE,
+      ),
+    ),
+    'unique keys' => array(
+      'db_c1' => array(
+        0 => 'name',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'db_id',
+    ),
+    'foreign keys' => array(
+    ),
+    'referring_tables' => array(
+      0 => 'dbprop',
+      1 => 'dbxref',
+      2 => 'stockcollection_db',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_dbprop()
+ *
+ * Purpose: To describe the structure of 'dbprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'dbprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_dbprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'dbprop',
+    'fields' => array(
+      'dbprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'db_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'dbprop_c1' => array(
+        0 => 'db_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'dbprop_idx1' => array(
+        0 => 'db_id',
+      ),
+      'dbprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'dbprop_id',
+    ),
+    'foreign keys' => array(
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+      'db' => array(
+        'table' => 'db',
+        'columns' => array(
+          'db_id' => 'db_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_dbxref()
+ *
+ * Purpose: To describe the structure of 'dbxref' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'dbxref' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_dbxref() {
+  $description = array(
+    'description' => '',
+    'table' => 'dbxref',
+    'fields' => array(
+      'dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'db_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'accession' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '1024',
+        'not null' => TRUE,
+      ),
+      'version' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'description' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+    ),
+    'unique keys' => array(
+      'dbxref_c1' => array(
+        0 => 'db_id',
+        1 => 'accession',
+        2 => 'version',
+      ),
+    ),
+    'indexes' => array(
+      'dbxref_idx1' => array(
+        0 => 'db_id',
+      ),
+      'dbxref_idx2' => array(
+        0 => 'accession',
+      ),
+      'dbxref_idx3' => array(
+        0 => 'version',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'dbxref_id',
+    ),
+    'foreign keys' => array(
+      'db' => array(
+        'table' => 'db',
+        'columns' => array(
+          'db_id' => 'db_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'analysis_dbxref',
+      1 => 'arraydesign',
+      2 => 'assay',
+      3 => 'biomaterial',
+      4 => 'biomaterial_dbxref',
+      5 => 'cell_line_dbxref',
+      6 => 'cvterm',
+      7 => 'cvterm_dbxref',
+      8 => 'dbxrefprop',
+      9 => 'element',
+      10 => 'feature',
+      11 => 'feature_cvterm_dbxref',
+      12 => 'feature_dbxref',
+      13 => 'featuremap_dbxref',
+      14 => 'library_dbxref',
+      15 => 'nd_experiment_dbxref',
+      16 => 'nd_experiment_stock_dbxref',
+      17 => 'organism_dbxref',
+      18 => 'phylonode_dbxref',
+      19 => 'phylotree',
+      20 => 'project_dbxref',
+      21 => 'protocol',
+      22 => 'pub_dbxref',
+      23 => 'stock',
+      24 => 'stock_dbxref',
+      25 => 'study',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_dbxrefprop()
+ *
+ * Purpose: To describe the structure of 'dbxrefprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'dbxrefprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_dbxrefprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'dbxrefprop',
+    'fields' => array(
+      'dbxrefprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'dbxrefprop_c1' => array(
+        0 => 'dbxref_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'dbxrefprop_idx1' => array(
+        0 => 'dbxref_id',
+      ),
+      'dbxrefprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'dbxrefprop_id',
+    ),
+    'foreign keys' => array(
+      'dbxref' => array(
+        'table' => 'dbxref',
+        'columns' => array(
+          'dbxref_id' => 'dbxref_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_eimage()
+ *
+ * Purpose: To describe the structure of 'eimage' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'eimage' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_eimage() {
+  $description = array(
+    'description' => '',
+    'table' => 'eimage',
+    'fields' => array(
+      'eimage_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'eimage_data' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'eimage_type' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => TRUE,
+      ),
+      'image_uri' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => FALSE,
+      ),
+    ),
+    'primary key' => array(
+      0 => 'eimage_id',
+    ),
+    'foreign keys' => array(
+    ),
+    'referring_tables' => array(
+      0 => 'expression_image',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_element()
+ *
+ * Purpose: To describe the structure of 'element' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'element' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_element() {
+  $description = array(
+    'description' => '',
+    'table' => 'element',
+    'fields' => array(
+      'element_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'feature_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'arraydesign_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+    ),
+    'unique keys' => array(
+      'element_c1' => array(
+        0 => 'feature_id',
+        1 => 'arraydesign_id',
+      ),
+    ),
+    'indexes' => array(
+      'element_idx1' => array(
+        0 => 'feature_id',
+      ),
+      'element_idx2' => array(
+        0 => 'arraydesign_id',
+      ),
+      'element_idx3' => array(
+        0 => 'type_id',
+      ),
+      'element_idx4' => array(
+        0 => 'dbxref_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'element_id',
+    ),
+    'foreign keys' => array(
+      'feature' => array(
+        'table' => 'feature',
+        'columns' => array(
+          'feature_id' => 'feature_id',
+        ),
+      ),
+      'arraydesign' => array(
+        'table' => 'arraydesign',
+        'columns' => array(
+          'arraydesign_id' => 'arraydesign_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+      'dbxref' => array(
+        'table' => 'dbxref',
+        'columns' => array(
+          'dbxref_id' => 'dbxref_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'element_relationship',
+      2 => 'elementresult',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_element_relationship()
+ *
+ * Purpose: To describe the structure of 'element_relationship' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'element_relationship' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_element_relationship() {
+  $description = array(
+    'description' => '',
+    'table' => 'element_relationship',
+    'fields' => array(
+      'element_relationship_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'subject_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'object_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'element_relationship_c1' => array(
+        0 => 'subject_id',
+        1 => 'object_id',
+        2 => 'type_id',
+        3 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'element_relationship_idx1' => array(
+        0 => 'subject_id',
+      ),
+      'element_relationship_idx2' => array(
+        0 => 'type_id',
+      ),
+      'element_relationship_idx3' => array(
+        0 => 'object_id',
+      ),
+      'element_relationship_idx4' => array(
+        0 => 'value',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'element_relationship_id',
+    ),
+    'foreign keys' => array(
+      'element' => array(
+        'table' => 'element',
+        'columns' => array(
+          'subject_id' => 'element_id',
+          'object_id' => 'element_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_elementresult()
+ *
+ * Purpose: To describe the structure of 'elementresult' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'elementresult' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_elementresult() {
+  $description = array(
+    'description' => '',
+    'table' => 'elementresult',
+    'fields' => array(
+      'elementresult_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'element_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'quantification_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'signal' => array(
+        'size' => 'big',
+        'type' => 'float',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'elementresult_c1' => array(
+        0 => 'element_id',
+        1 => 'quantification_id',
+      ),
+    ),
+    'indexes' => array(
+      'elementresult_idx1' => array(
+        0 => 'element_id',
+      ),
+      'elementresult_idx2' => array(
+        0 => 'quantification_id',
+      ),
+      'elementresult_idx3' => array(
+        0 => 'signal',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'elementresult_id',
+    ),
+    'foreign keys' => array(
+      'element' => array(
+        'table' => 'element',
+        'columns' => array(
+          'element_id' => 'element_id',
+        ),
+      ),
+      'quantification' => array(
+        'table' => 'quantification',
+        'columns' => array(
+          'quantification_id' => 'quantification_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'elementresult_relationship',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_elementresult_relationship()
+ *
+ * Purpose: To describe the structure of 'elementresult_relationship' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'elementresult_relationship' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_elementresult_relationship() {
+  $description = array(
+    'description' => '',
+    'table' => 'elementresult_relationship',
+    'fields' => array(
+      'elementresult_relationship_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'subject_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'object_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'elementresult_relationship_c1' => array(
+        0 => 'subject_id',
+        1 => 'object_id',
+        2 => 'type_id',
+        3 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'elementresult_relationship_idx1' => array(
+        0 => 'subject_id',
+      ),
+      'elementresult_relationship_idx2' => array(
+        0 => 'type_id',
+      ),
+      'elementresult_relationship_idx3' => array(
+        0 => 'object_id',
+      ),
+      'elementresult_relationship_idx4' => array(
+        0 => 'value',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'elementresult_relationship_id',
+    ),
+    'foreign keys' => array(
+      'elementresult' => array(
+        'table' => 'elementresult',
+        'columns' => array(
+          'subject_id' => 'elementresult_id',
+          'object_id' => 'elementresult_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_environment()
+ *
+ * Purpose: To describe the structure of 'environment' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'environment' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_environment() {
+  $description = array(
+    'description' => '',
+    'table' => 'environment',
+    'fields' => array(
+      'environment_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'uniquename' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => TRUE,
+      ),
+      'description' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+    ),
+    'unique keys' => array(
+      'environment_c1' => array(
+        0 => 'uniquename',
+      ),
+    ),
+    'indexes' => array(
+      'environment_idx1' => array(
+        0 => 'uniquename',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'environment_id',
+    ),
+    'foreign keys' => array(
+    ),
+    'referring_tables' => array(
+      0 => 'environment_cvterm',
+      1 => 'phendesc',
+      2 => 'phenotype_comparison',
+      4 => 'phenstatement',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_environment_cvterm()
+ *
+ * Purpose: To describe the structure of 'environment_cvterm' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'environment_cvterm' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_environment_cvterm() {
+  $description = array(
+    'description' => '',
+    'table' => 'environment_cvterm',
+    'fields' => array(
+      'environment_cvterm_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'environment_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'cvterm_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'environment_cvterm_c1' => array(
+        0 => 'environment_id',
+        1 => 'cvterm_id',
+      ),
+    ),
+    'indexes' => array(
+      'environment_cvterm_idx1' => array(
+        0 => 'environment_id',
+      ),
+      'environment_cvterm_idx2' => array(
+        0 => 'cvterm_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'environment_cvterm_id',
+    ),
+    'foreign keys' => array(
+      'environment' => array(
+        'table' => 'environment',
+        'columns' => array(
+          'environment_id' => 'environment_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'cvterm_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_expression()
+ *
+ * Purpose: To describe the structure of 'expression' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'expression' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_expression() {
+  $description = array(
+    'description' => '',
+    'table' => 'expression',
+    'fields' => array(
+      'expression_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'uniquename' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => TRUE,
+      ),
+      'md5checksum' => array(
+        'size' => 'normal',
+        'type' => 'char',
+        'length' => '32',
+        'not null' => FALSE,
+      ),
+      'description' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+    ),
+    'unique keys' => array(
+      'expression_c1' => array(
+        0 => 'uniquename',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'expression_id',
+    ),
+    'foreign keys' => array(
+    ),
+    'referring_tables' => array(
+      0 => 'expression_cvterm',
+      1 => 'expression_image',
+      2 => 'expressionprop',
+      3 => 'expression_pub',
+      4 => 'feature_expression',
+      5 => 'library_expression',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_expression_cvterm()
+ *
+ * Purpose: To describe the structure of 'expression_cvterm' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'expression_cvterm' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_expression_cvterm() {
+  $description = array(
+    'description' => '',
+    'table' => 'expression_cvterm',
+    'fields' => array(
+      'expression_cvterm_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'expression_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'cvterm_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'cvterm_type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'expression_cvterm_c1' => array(
+        0 => 'expression_id',
+        1 => 'cvterm_id',
+        2 => 'rank',
+        3 => 'cvterm_type_id',
+      ),
+    ),
+    'indexes' => array(
+      'expression_cvterm_idx1' => array(
+        0 => 'expression_id',
+      ),
+      'expression_cvterm_idx2' => array(
+        0 => 'cvterm_id',
+      ),
+      'expression_cvterm_idx3' => array(
+        0 => 'cvterm_type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'expression_cvterm_id',
+    ),
+    'foreign keys' => array(
+      'expression' => array(
+        'table' => 'expression',
+        'columns' => array(
+          'expression_id' => 'expression_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'cvterm_id' => 'cvterm_id',
+          'cvterm_type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'expression_cvtermprop',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_expression_cvtermprop()
+ *
+ * Purpose: To describe the structure of 'expression_cvtermprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'expression_cvtermprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_expression_cvtermprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'expression_cvtermprop',
+    'fields' => array(
+      'expression_cvtermprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'expression_cvterm_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'expression_cvtermprop_c1' => array(
+        0 => 'expression_cvterm_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'expression_cvtermprop_idx1' => array(
+        0 => 'expression_cvterm_id',
+      ),
+      'expression_cvtermprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'expression_cvtermprop_id',
+    ),
+    'foreign keys' => array(
+      'expression_cvterm' => array(
+        'table' => 'expression_cvterm',
+        'columns' => array(
+          'expression_cvterm_id' => 'expression_cvterm_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_expression_image()
+ *
+ * Purpose: To describe the structure of 'expression_image' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'expression_image' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_expression_image() {
+  $description = array(
+    'description' => '',
+    'table' => 'expression_image',
+    'fields' => array(
+      'expression_image_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'expression_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'eimage_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'expression_image_c1' => array(
+        0 => 'expression_id',
+        1 => 'eimage_id',
+      ),
+    ),
+    'indexes' => array(
+      'expression_image_idx1' => array(
+        0 => 'expression_id',
+      ),
+      'expression_image_idx2' => array(
+        0 => 'eimage_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'expression_image_id',
+    ),
+    'foreign keys' => array(
+      'expression' => array(
+        'table' => 'expression',
+        'columns' => array(
+          'expression_id' => 'expression_id',
+        ),
+      ),
+      'eimage' => array(
+        'table' => 'eimage',
+        'columns' => array(
+          'eimage_id' => 'eimage_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_expressionprop()
+ *
+ * Purpose: To describe the structure of 'expressionprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'expressionprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_expressionprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'expressionprop',
+    'fields' => array(
+      'expressionprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'expression_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'expressionprop_c1' => array(
+        0 => 'expression_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'expressionprop_idx1' => array(
+        0 => 'expression_id',
+      ),
+      'expressionprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'expressionprop_id',
+    ),
+    'foreign keys' => array(
+      'expression' => array(
+        'table' => 'expression',
+        'columns' => array(
+          'expression_id' => 'expression_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_expression_pub()
+ *
+ * Purpose: To describe the structure of 'expression_pub' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'expression_pub' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_expression_pub() {
+  $description = array(
+    'description' => '',
+    'table' => 'expression_pub',
+    'fields' => array(
+      'expression_pub_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'expression_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'expression_pub_c1' => array(
+        0 => 'expression_id',
+        1 => 'pub_id',
+      ),
+    ),
+    'indexes' => array(
+      'expression_pub_idx1' => array(
+        0 => 'expression_id',
+      ),
+      'expression_pub_idx2' => array(
+        0 => 'pub_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'expression_pub_id',
+    ),
+    'foreign keys' => array(
+      'expression' => array(
+        'table' => 'expression',
+        'columns' => array(
+          'expression_id' => 'expression_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_feature()
+ *
+ * Purpose: To describe the structure of 'feature' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'feature' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_feature() {
+  $description = array(
+    'description' => '',
+    'table' => 'feature',
+    'fields' => array(
+      'feature_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'organism_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'name' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => FALSE,
+      ),
+      'uniquename' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => TRUE,
+      ),
+      'residues' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'seqlen' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'md5checksum' => array(
+        'size' => 'normal',
+        'type' => 'char',
+        'length' => '32',
+        'not null' => FALSE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'is_analysis' => array(
+        'size' => 'normal',
+        'type' => 'boolean',
+        'not null' => TRUE,
+        'default' => FALSE,
+      ),
+      'is_obsolete' => array(
+        'size' => 'normal',
+        'type' => 'boolean',
+        'not null' => TRUE,
+        'default' => FALSE,
+      ),
+      'timeaccessioned' => array(
+        'size' => 'normal',
+        'type' => 'datetime',
+        'not null' => TRUE,
+        'default' => 'now()',
+      ),
+      'timelastmodified' => array(
+        'size' => 'normal',
+        'type' => 'datetime',
+        'not null' => TRUE,
+        'default' => 'now()',
+      ),
+    ),
+    'unique keys' => array(
+      'feature_c1' => array(
+        0 => 'organism_id',
+        1 => 'uniquename',
+        2 => 'type_id',
+      ),
+    ),
+    'indexes' => array(
+      'feature_idx1' => array(
+        0 => 'dbxref_id',
+      ),
+      'feature_idx2' => array(
+        0 => 'organism_id',
+      ),
+      'feature_idx3' => array(
+        0 => 'type_id',
+      ),
+      'feature_idx4' => array(
+        0 => 'uniquename',
+      ),
+      'feature_name_ind1' => array(
+        0 => 'name',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'feature_id',
+    ),
+    'foreign keys' => array(
+      'dbxref' => array(
+        'table' => 'dbxref',
+        'columns' => array(
+          'dbxref_id' => 'dbxref_id',
+        ),
+      ),
+      'organism' => array(
+        'table' => 'organism',
+        'columns' => array(
+          'organism_id' => 'organism_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'analysisfeature',
+      1 => 'cell_line_feature',
+      2 => 'element',
+      3 => 'feature_contact',
+      4 => 'feature_cvterm',
+      5 => 'feature_dbxref',
+      6 => 'feature_expression',
+      7 => 'feature_genotype',
+      9 => 'featureloc',
+      11 => 'feature_phenotype',
+      12 => 'featurepos',
+      14 => 'featureprop',
+      15 => 'feature_pub',
+      16 => 'featurerange',
+      21 => 'feature_relationship',
+      23 => 'feature_synonym',
+      24 => 'library_feature',
+      25 => 'nd_reagent',
+      26 => 'phylonode',
+      27 => 'project_feature',
+      28 => 'stock_feature',
+      29 => 'studyprop_feature',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_feature_contact()
+ *
+ * Purpose: To describe the structure of 'feature_contact' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'feature_contact' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_feature_contact() {
+  $description = array(
+    'description' => '',
+    'table' => 'feature_contact',
+    'fields' => array(
+      'feature_contact_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'feature_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'contact_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'feature_contact_c1' => array(
+        0 => 'feature_id',
+        1 => 'contact_id',
+      ),
+    ),
+    'indexes' => array(
+      'feature_contact_idx1' => array(
+        0 => 'feature_id',
+      ),
+      'feature_contact_idx2' => array(
+        0 => 'contact_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'feature_contact_id',
+    ),
+    'foreign keys' => array(
+      'contact' => array(
+        'table' => 'contact',
+        'columns' => array(
+          'contact_id' => 'contact_id',
+        ),
+      ),
+      'feature' => array(
+        'table' => 'feature',
+        'columns' => array(
+          'feature_id' => 'feature_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_feature_cvterm()
+ *
+ * Purpose: To describe the structure of 'feature_cvterm' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'feature_cvterm' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_feature_cvterm() {
+  $description = array(
+    'description' => '',
+    'table' => 'feature_cvterm',
+    'fields' => array(
+      'feature_cvterm_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'feature_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'cvterm_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'is_not' => array(
+        'size' => 'normal',
+        'type' => 'boolean',
+        'not null' => TRUE,
+        'default' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'feature_cvterm_c1' => array(
+        0 => 'feature_id',
+        1 => 'cvterm_id',
+        2 => 'pub_id',
+        3 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'feature_cvterm_idx1' => array(
+        0 => 'feature_id',
+      ),
+      'feature_cvterm_idx2' => array(
+        0 => 'cvterm_id',
+      ),
+      'feature_cvterm_idx3' => array(
+        0 => 'pub_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'feature_cvterm_id',
+    ),
+    'foreign keys' => array(
+      'feature' => array(
+        'table' => 'feature',
+        'columns' => array(
+          'feature_id' => 'feature_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'cvterm_id' => 'cvterm_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'feature_cvterm_dbxref',
+      1 => 'feature_cvtermprop',
+      2 => 'feature_cvterm_pub',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_feature_cvterm_dbxref()
+ *
+ * Purpose: To describe the structure of 'feature_cvterm_dbxref' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'feature_cvterm_dbxref' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_feature_cvterm_dbxref() {
+  $description = array(
+    'description' => '',
+    'table' => 'feature_cvterm_dbxref',
+    'fields' => array(
+      'feature_cvterm_dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'feature_cvterm_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'feature_cvterm_dbxref_c1' => array(
+        0 => 'feature_cvterm_id',
+        1 => 'dbxref_id',
+      ),
+    ),
+    'indexes' => array(
+      'feature_cvterm_dbxref_idx1' => array(
+        0 => 'feature_cvterm_id',
+      ),
+      'feature_cvterm_dbxref_idx2' => array(
+        0 => 'dbxref_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'feature_cvterm_dbxref_id',
+    ),
+    'foreign keys' => array(
+      'feature_cvterm' => array(
+        'table' => 'feature_cvterm',
+        'columns' => array(
+          'feature_cvterm_id' => 'feature_cvterm_id',
+        ),
+      ),
+      'dbxref' => array(
+        'table' => 'dbxref',
+        'columns' => array(
+          'dbxref_id' => 'dbxref_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_feature_cvtermprop()
+ *
+ * Purpose: To describe the structure of 'feature_cvtermprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'feature_cvtermprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_feature_cvtermprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'feature_cvtermprop',
+    'fields' => array(
+      'feature_cvtermprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'feature_cvterm_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'feature_cvtermprop_c1' => array(
+        0 => 'feature_cvterm_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'feature_cvtermprop_idx1' => array(
+        0 => 'feature_cvterm_id',
+      ),
+      'feature_cvtermprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'feature_cvtermprop_id',
+    ),
+    'foreign keys' => array(
+      'feature_cvterm' => array(
+        'table' => 'feature_cvterm',
+        'columns' => array(
+          'feature_cvterm_id' => 'feature_cvterm_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_feature_cvterm_pub()
+ *
+ * Purpose: To describe the structure of 'feature_cvterm_pub' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'feature_cvterm_pub' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_feature_cvterm_pub() {
+  $description = array(
+    'description' => '',
+    'table' => 'feature_cvterm_pub',
+    'fields' => array(
+      'feature_cvterm_pub_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'feature_cvterm_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'feature_cvterm_pub_c1' => array(
+        0 => 'feature_cvterm_id',
+        1 => 'pub_id',
+      ),
+    ),
+    'indexes' => array(
+      'feature_cvterm_pub_idx1' => array(
+        0 => 'feature_cvterm_id',
+      ),
+      'feature_cvterm_pub_idx2' => array(
+        0 => 'pub_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'feature_cvterm_pub_id',
+    ),
+    'foreign keys' => array(
+      'feature_cvterm' => array(
+        'table' => 'feature_cvterm',
+        'columns' => array(
+          'feature_cvterm_id' => 'feature_cvterm_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_feature_dbxref()
+ *
+ * Purpose: To describe the structure of 'feature_dbxref' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'feature_dbxref' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_feature_dbxref() {
+  $description = array(
+    'description' => '',
+    'table' => 'feature_dbxref',
+    'fields' => array(
+      'feature_dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'feature_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'is_current' => array(
+        'size' => 'normal',
+        'type' => 'boolean',
+        'not null' => TRUE,
+        'default' => 'ru',
+      ),
+    ),
+    'unique keys' => array(
+      'feature_dbxref_c1' => array(
+        0 => 'feature_id',
+        1 => 'dbxref_id',
+      ),
+    ),
+    'indexes' => array(
+      'feature_dbxref_idx1' => array(
+        0 => 'feature_id',
+      ),
+      'feature_dbxref_idx2' => array(
+        0 => 'dbxref_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'feature_dbxref_id',
+    ),
+    'foreign keys' => array(
+      'feature' => array(
+        'table' => 'feature',
+        'columns' => array(
+          'feature_id' => 'feature_id',
+        ),
+      ),
+      'dbxref' => array(
+        'table' => 'dbxref',
+        'columns' => array(
+          'dbxref_id' => 'dbxref_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_feature_expression()
+ *
+ * Purpose: To describe the structure of 'feature_expression' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'feature_expression' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_feature_expression() {
+  $description = array(
+    'description' => '',
+    'table' => 'feature_expression',
+    'fields' => array(
+      'feature_expression_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'expression_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'feature_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'feature_expression_c1' => array(
+        0 => 'expression_id',
+        1 => 'feature_id',
+        2 => 'pub_id',
+      ),
+    ),
+    'indexes' => array(
+      'feature_expression_idx1' => array(
+        0 => 'expression_id',
+      ),
+      'feature_expression_idx2' => array(
+        0 => 'feature_id',
+      ),
+      'feature_expression_idx3' => array(
+        0 => 'pub_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'feature_expression_id',
+    ),
+    'foreign keys' => array(
+      'expression' => array(
+        'table' => 'expression',
+        'columns' => array(
+          'expression_id' => 'expression_id',
+        ),
+      ),
+      'feature' => array(
+        'table' => 'feature',
+        'columns' => array(
+          'feature_id' => 'feature_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'feature_expressionprop',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_feature_expressionprop()
+ *
+ * Purpose: To describe the structure of 'feature_expressionprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'feature_expressionprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_feature_expressionprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'feature_expressionprop',
+    'fields' => array(
+      'feature_expressionprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'feature_expression_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'feature_expressionprop_c1' => array(
+        0 => 'feature_expression_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'feature_expressionprop_idx1' => array(
+        0 => 'feature_expression_id',
+      ),
+      'feature_expressionprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'feature_expressionprop_id',
+    ),
+    'foreign keys' => array(
+      'feature_expression' => array(
+        'table' => 'feature_expression',
+        'columns' => array(
+          'feature_expression_id' => 'feature_expression_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_feature_genotype()
+ *
+ * Purpose: To describe the structure of 'feature_genotype' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'feature_genotype' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_feature_genotype() {
+  $description = array(
+    'description' => '',
+    'table' => 'feature_genotype',
+    'fields' => array(
+      'feature_genotype_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'feature_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'genotype_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'chromosome_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'cgroup' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'cvterm_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'feature_genotype_c1' => array(
+        0 => 'feature_id',
+        1 => 'genotype_id',
+        2 => 'cvterm_id',
+        3 => 'chromosome_id',
+        4 => 'rank',
+        5 => 'cgroup',
+      ),
+    ),
+    'indexes' => array(
+      'feature_genotype_idx1' => array(
+        0 => 'feature_id',
+      ),
+      'feature_genotype_idx2' => array(
+        0 => 'genotype_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'feature_genotype_id',
+    ),
+    'foreign keys' => array(
+      'feature' => array(
+        'table' => 'feature',
+        'columns' => array(
+          'feature_id' => 'feature_id',
+          'chromosome_id' => 'feature_id',
+        ),
+      ),
+      'genotype' => array(
+        'table' => 'genotype',
+        'columns' => array(
+          'genotype_id' => 'genotype_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'cvterm_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_featureloc()
+ *
+ * Purpose: To describe the structure of 'featureloc' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'featureloc' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_featureloc() {
+  $description = array(
+    'description' => '',
+    'table' => 'featureloc',
+    'fields' => array(
+      'featureloc_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'feature_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'srcfeature_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'fmin' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'is_fmin_partial' => array(
+        'size' => 'normal',
+        'type' => 'boolean',
+        'not null' => TRUE,
+        'default' => FALSE,
+      ),
+      'fmax' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'is_fmax_partial' => array(
+        'size' => 'normal',
+        'type' => 'boolean',
+        'not null' => TRUE,
+        'default' => FALSE,
+      ),
+      'strand' => array(
+        'size' => 'small',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'phase' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'residue_info' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'locgroup' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'indexes' => array(
+      'binloc_boxrange' => array(
+        0 => 'fmin',
+      ),
+      'binloc_boxrange_src' => array(
+        0 => 'srcfeature_id',
+        1 => 'fmin',
+      ),
+      'featureloc_idx1' => array(
+        0 => 'feature_id',
+      ),
+      'featureloc_idx1b' => array(
+        0 => 'feature_id',
+        1 => 'fmin',
+        2 => 'fmax',
+      ),
+      'featureloc_idx2' => array(
+        0 => 'srcfeature_id',
+      ),
+      'featureloc_idx3' => array(
+        0 => 'srcfeature_id',
+        1 => 'fmin',
+        2 => 'fmax',
+      ),
+    ),
+    'unique keys' => array(
+      'featureloc_c1' => array(
+        0 => 'feature_id',
+        1 => 'locgroup',
+        2 => 'rank',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'featureloc_id',
+    ),
+    'foreign keys' => array(
+      'feature' => array(
+        'table' => 'feature',
+        'columns' => array(
+          'feature_id' => 'feature_id',
+          'srcfeature_id' => 'feature_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'featureloc_pub',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_featureloc_pub()
+ *
+ * Purpose: To describe the structure of 'featureloc_pub' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'featureloc_pub' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_featureloc_pub() {
+  $description = array(
+    'description' => '',
+    'table' => 'featureloc_pub',
+    'fields' => array(
+      'featureloc_pub_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'featureloc_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'featureloc_pub_c1' => array(
+        0 => 'featureloc_id',
+        1 => 'pub_id',
+      ),
+    ),
+    'indexes' => array(
+      'featureloc_pub_idx1' => array(
+        0 => 'featureloc_id',
+      ),
+      'featureloc_pub_idx2' => array(
+        0 => 'pub_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'featureloc_pub_id',
+    ),
+    'foreign keys' => array(
+      'featureloc' => array(
+        'table' => 'featureloc',
+        'columns' => array(
+          'featureloc_id' => 'featureloc_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_featuremap()
+ *
+ * Purpose: To describe the structure of 'featuremap' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'featuremap' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_featuremap() {
+  $description = array(
+    'description' => '',
+    'table' => 'featuremap',
+    'fields' => array(
+      'featuremap_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'name' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => FALSE,
+      ),
+      'description' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'unittype_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+    ),
+    'unique keys' => array(
+      'featuremap_c1' => array(
+        0 => 'name',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'featuremap_id',
+    ),
+    'foreign keys' => array(
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'unittype_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'featuremap_contact',
+      1 => 'featuremap_dbxref',
+      2 => 'featuremap_organism',
+      3 => 'featuremapprop',
+      4 => 'featuremap_pub',
+      5 => 'featurepos',
+      6 => 'featurerange',
+      7 => 'stock_featuremap',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_featuremap_contact()
+ *
+ * Purpose: To describe the structure of 'featuremap_contact' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'featuremap_contact' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_featuremap_contact() {
+  $description = array(
+    'description' => '',
+    'table' => 'featuremap_contact',
+    'fields' => array(
+      'featuremap_contact_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'featuremap_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'contact_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'featuremap_contact_c1' => array(
+        0 => 'featuremap_id',
+        1 => 'contact_id',
+      ),
+    ),
+    'indexes' => array(
+      'featuremap_contact_idx1' => array(
+        0 => 'featuremap_id',
+      ),
+      'featuremap_contact_idx2' => array(
+        0 => 'contact_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'featuremap_contact_id',
+    ),
+    'foreign keys' => array(
+      'contact' => array(
+        'table' => 'contact',
+        'columns' => array(
+          'contact_id' => 'contact_id',
+        ),
+      ),
+      'featuremap' => array(
+        'table' => 'featuremap',
+        'columns' => array(
+          'featuremap_id' => 'featuremap_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_featuremap_dbxref()
+ *
+ * Purpose: To describe the structure of 'featuremap_dbxref' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'featuremap_dbxref' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_featuremap_dbxref() {
+  $description = array(
+    'description' => '',
+    'table' => 'featuremap_dbxref',
+    'fields' => array(
+      'featuremap_dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'featuremap_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'is_current' => array(
+        'size' => 'normal',
+        'type' => 'boolean',
+        'not null' => TRUE,
+        'default' => 'ru',
+      ),
+    ),
+    'indexes' => array(
+      'featuremap_dbxref_idx1' => array(
+        0 => 'featuremap_id',
+      ),
+      'featuremap_dbxref_idx2' => array(
+        0 => 'dbxref_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'featuremap_dbxref_id',
+    ),
+    'foreign keys' => array(
+      'featuremap' => array(
+        'table' => 'featuremap',
+        'columns' => array(
+          'featuremap_id' => 'featuremap_id',
+        ),
+      ),
+      'dbxref' => array(
+        'table' => 'dbxref',
+        'columns' => array(
+          'dbxref_id' => 'dbxref_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_featuremap_organism()
+ *
+ * Purpose: To describe the structure of 'featuremap_organism' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'featuremap_organism' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_featuremap_organism() {
+  $description = array(
+    'description' => '',
+    'table' => 'featuremap_organism',
+    'fields' => array(
+      'featuremap_organism_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'featuremap_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'organism_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'featuremap_organism_c1' => array(
+        0 => 'featuremap_id',
+        1 => 'organism_id',
+      ),
+    ),
+    'indexes' => array(
+      'featuremap_organism_idx1' => array(
+        0 => 'featuremap_id',
+      ),
+      'featuremap_organism_idx2' => array(
+        0 => 'organism_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'featuremap_organism_id',
+    ),
+    'foreign keys' => array(
+      'featuremap' => array(
+        'table' => 'featuremap',
+        'columns' => array(
+          'featuremap_id' => 'featuremap_id',
+        ),
+      ),
+      'organism' => array(
+        'table' => 'organism',
+        'columns' => array(
+          'organism_id' => 'organism_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_featuremapprop()
+ *
+ * Purpose: To describe the structure of 'featuremapprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'featuremapprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_featuremapprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'featuremapprop',
+    'fields' => array(
+      'featuremapprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'featuremap_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'featuremapprop_c1' => array(
+        0 => 'featuremap_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'featuremapprop_idx1' => array(
+        0 => 'featuremap_id',
+      ),
+      'featuremapprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'featuremapprop_id',
+    ),
+    'foreign keys' => array(
+      'featuremap' => array(
+        'table' => 'featuremap',
+        'columns' => array(
+          'featuremap_id' => 'featuremap_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_featuremap_pub()
+ *
+ * Purpose: To describe the structure of 'featuremap_pub' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'featuremap_pub' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_featuremap_pub() {
+  $description = array(
+    'description' => '',
+    'table' => 'featuremap_pub',
+    'fields' => array(
+      'featuremap_pub_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'featuremap_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'indexes' => array(
+      'featuremap_pub_idx1' => array(
+        0 => 'featuremap_id',
+      ),
+      'featuremap_pub_idx2' => array(
+        0 => 'pub_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'featuremap_pub_id',
+    ),
+    'foreign keys' => array(
+      'featuremap' => array(
+        'table' => 'featuremap',
+        'columns' => array(
+          'featuremap_id' => 'featuremap_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_feature_phenotype()
+ *
+ * Purpose: To describe the structure of 'feature_phenotype' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'feature_phenotype' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_feature_phenotype() {
+  $description = array(
+    'description' => '',
+    'table' => 'feature_phenotype',
+    'fields' => array(
+      'feature_phenotype_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'feature_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'phenotype_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'feature_phenotype_c1' => array(
+        0 => 'feature_id',
+        1 => 'phenotype_id',
+      ),
+    ),
+    'indexes' => array(
+      'feature_phenotype_idx1' => array(
+        0 => 'feature_id',
+      ),
+      'feature_phenotype_idx2' => array(
+        0 => 'phenotype_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'feature_phenotype_id',
+    ),
+    'foreign keys' => array(
+      'feature' => array(
+        'table' => 'feature',
+        'columns' => array(
+          'feature_id' => 'feature_id',
+        ),
+      ),
+      'phenotype' => array(
+        'table' => 'phenotype',
+        'columns' => array(
+          'phenotype_id' => 'phenotype_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_featurepos()
+ *
+ * Purpose: To describe the structure of 'featurepos' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'featurepos' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_featurepos() {
+  $description = array(
+    'description' => '',
+    'table' => 'featurepos',
+    'fields' => array(
+      'featurepos_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'featuremap_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'feature_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'map_feature_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'mappos' => array(
+        'size' => 'big',
+        'type' => 'float',
+        'not null' => TRUE,
+      ),
+    ),
+    'indexes' => array(
+      'featurepos_idx1' => array(
+        0 => 'featuremap_id',
+      ),
+      'featurepos_idx2' => array(
+        0 => 'feature_id',
+      ),
+      'featurepos_idx3' => array(
+        0 => 'map_feature_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'featurepos_id',
+    ),
+    'foreign keys' => array(
+      'featuremap' => array(
+        'table' => 'featuremap',
+        'columns' => array(
+          'featuremap_id' => 'featuremap_id',
+        ),
+      ),
+      'feature' => array(
+        'table' => 'feature',
+        'columns' => array(
+          'feature_id' => 'feature_id',
+          'map_feature_id' => 'feature_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'featureposprop',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_featureposprop()
+ *
+ * Purpose: To describe the structure of 'featureposprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'featureposprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_featureposprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'featureposprop',
+    'fields' => array(
+      'featureposprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'featurepos_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'featureposprop_c1' => array(
+        0 => 'featurepos_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'featureposprop_idx1' => array(
+        0 => 'featurepos_id',
+      ),
+      'featureposprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'featureposprop_id',
+    ),
+    'foreign keys' => array(
+      'featurepos' => array(
+        'table' => 'featurepos',
+        'columns' => array(
+          'featurepos_id' => 'featurepos_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_featureprop()
+ *
+ * Purpose: To describe the structure of 'featureprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'featureprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_featureprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'featureprop',
+    'fields' => array(
+      'featureprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'feature_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'featureprop_c1' => array(
+        0 => 'feature_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'featureprop_idx1' => array(
+        0 => 'feature_id',
+      ),
+      'featureprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'featureprop_id',
+    ),
+    'foreign keys' => array(
+      'feature' => array(
+        'table' => 'feature',
+        'columns' => array(
+          'feature_id' => 'feature_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'featureprop_pub',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_featureprop_pub()
+ *
+ * Purpose: To describe the structure of 'featureprop_pub' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'featureprop_pub' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_featureprop_pub() {
+  $description = array(
+    'description' => '',
+    'table' => 'featureprop_pub',
+    'fields' => array(
+      'featureprop_pub_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'featureprop_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'featureprop_pub_c1' => array(
+        0 => 'featureprop_id',
+        1 => 'pub_id',
+      ),
+    ),
+    'indexes' => array(
+      'featureprop_pub_idx1' => array(
+        0 => 'featureprop_id',
+      ),
+      'featureprop_pub_idx2' => array(
+        0 => 'pub_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'featureprop_pub_id',
+    ),
+    'foreign keys' => array(
+      'featureprop' => array(
+        'table' => 'featureprop',
+        'columns' => array(
+          'featureprop_id' => 'featureprop_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_feature_pub()
+ *
+ * Purpose: To describe the structure of 'feature_pub' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'feature_pub' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_feature_pub() {
+  $description = array(
+    'description' => '',
+    'table' => 'feature_pub',
+    'fields' => array(
+      'feature_pub_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'feature_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'feature_pub_c1' => array(
+        0 => 'feature_id',
+        1 => 'pub_id',
+      ),
+    ),
+    'indexes' => array(
+      'feature_pub_idx1' => array(
+        0 => 'feature_id',
+      ),
+      'feature_pub_idx2' => array(
+        0 => 'pub_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'feature_pub_id',
+    ),
+    'foreign keys' => array(
+      'feature' => array(
+        'table' => 'feature',
+        'columns' => array(
+          'feature_id' => 'feature_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'feature_pubprop',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_feature_pubprop()
+ *
+ * Purpose: To describe the structure of 'feature_pubprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'feature_pubprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_feature_pubprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'feature_pubprop',
+    'fields' => array(
+      'feature_pubprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'feature_pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'feature_pubprop_c1' => array(
+        0 => 'feature_pub_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'feature_pubprop_idx1' => array(
+        0 => 'feature_pub_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'feature_pubprop_id',
+    ),
+    'foreign keys' => array(
+      'feature_pub' => array(
+        'table' => 'feature_pub',
+        'columns' => array(
+          'feature_pub_id' => 'feature_pub_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_featurerange()
+ *
+ * Purpose: To describe the structure of 'featurerange' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'featurerange' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_featurerange() {
+  $description = array(
+    'description' => '',
+    'table' => 'featurerange',
+    'fields' => array(
+      'featurerange_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'featuremap_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'feature_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'leftstartf_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'leftendf_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'rightstartf_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'rightendf_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'rangestr' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => FALSE,
+      ),
+    ),
+    'indexes' => array(
+      'featurerange_idx1' => array(
+        0 => 'featuremap_id',
+      ),
+      'featurerange_idx2' => array(
+        0 => 'feature_id',
+      ),
+      'featurerange_idx3' => array(
+        0 => 'leftstartf_id',
+      ),
+      'featurerange_idx4' => array(
+        0 => 'leftendf_id',
+      ),
+      'featurerange_idx5' => array(
+        0 => 'rightstartf_id',
+      ),
+      'featurerange_idx6' => array(
+        0 => 'rightendf_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'featurerange_id',
+    ),
+    'foreign keys' => array(
+      'featuremap' => array(
+        'table' => 'featuremap',
+        'columns' => array(
+          'featuremap_id' => 'featuremap_id',
+        ),
+      ),
+      'feature' => array(
+        'table' => 'feature',
+        'columns' => array(
+          'feature_id' => 'feature_id',
+          'leftstartf_id' => 'feature_id',
+          'leftendf_id' => 'feature_id',
+          'rightstartf_id' => 'feature_id',
+          'rightendf_id' => 'feature_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_feature_relationship()
+ *
+ * Purpose: To describe the structure of 'feature_relationship' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'feature_relationship' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_feature_relationship() {
+  $description = array(
+    'description' => '',
+    'table' => 'feature_relationship',
+    'fields' => array(
+      'feature_relationship_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'subject_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'object_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'feature_relationship_c1' => array(
+        0 => 'subject_id',
+        1 => 'object_id',
+        2 => 'type_id',
+        3 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'feature_relationship_idx1' => array(
+        0 => 'subject_id',
+      ),
+      'feature_relationship_idx1b' => array(
+        0 => 'object_id',
+        1 => 'subject_id',
+        2 => 'type_id',
+      ),
+      'feature_relationship_idx2' => array(
+        0 => 'object_id',
+      ),
+      'feature_relationship_idx3' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'feature_relationship_id',
+    ),
+    'foreign keys' => array(
+      'feature' => array(
+        'table' => 'feature',
+        'columns' => array(
+          'subject_id' => 'feature_id',
+          'object_id' => 'feature_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'feature_relationshipprop',
+      1 => 'feature_relationship_pub',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_feature_relationshipprop()
+ *
+ * Purpose: To describe the structure of 'feature_relationshipprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'feature_relationshipprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_feature_relationshipprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'feature_relationshipprop',
+    'fields' => array(
+      'feature_relationshipprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'feature_relationship_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'feature_relationshipprop_c1' => array(
+        0 => 'feature_relationship_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'feature_relationshipprop_idx1' => array(
+        0 => 'feature_relationship_id',
+      ),
+      'feature_relationshipprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'feature_relationshipprop_id',
+    ),
+    'foreign keys' => array(
+      'feature_relationship' => array(
+        'table' => 'feature_relationship',
+        'columns' => array(
+          'feature_relationship_id' => 'feature_relationship_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'feature_relationshipprop_pub',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_feature_relationshipprop_pub()
+ *
+ * Purpose: To describe the structure of 'feature_relationshipprop_pub' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'feature_relationshipprop_pub' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_feature_relationshipprop_pub() {
+  $description = array(
+    'description' => '',
+    'table' => 'feature_relationshipprop_pub',
+    'fields' => array(
+      'feature_relationshipprop_pub_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'feature_relationshipprop_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'feature_relationshipprop_pub_c1' => array(
+        0 => 'feature_relationshipprop_id',
+        1 => 'pub_id',
+      ),
+    ),
+    'indexes' => array(
+      'feature_relationshipprop_pub_idx1' => array(
+        0 => 'feature_relationshipprop_id',
+      ),
+      'feature_relationshipprop_pub_idx2' => array(
+        0 => 'pub_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'feature_relationshipprop_pub_id',
+    ),
+    'foreign keys' => array(
+      'feature_relationshipprop' => array(
+        'table' => 'feature_relationshipprop',
+        'columns' => array(
+          'feature_relationshipprop_id' => 'feature_relationshipprop_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_feature_relationship_pub()
+ *
+ * Purpose: To describe the structure of 'feature_relationship_pub' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'feature_relationship_pub' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_feature_relationship_pub() {
+  $description = array(
+    'description' => '',
+    'table' => 'feature_relationship_pub',
+    'fields' => array(
+      'feature_relationship_pub_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'feature_relationship_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'feature_relationship_pub_c1' => array(
+        0 => 'feature_relationship_id',
+        1 => 'pub_id',
+      ),
+    ),
+    'indexes' => array(
+      'feature_relationship_pub_idx1' => array(
+        0 => 'feature_relationship_id',
+      ),
+      'feature_relationship_pub_idx2' => array(
+        0 => 'pub_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'feature_relationship_pub_id',
+    ),
+    'foreign keys' => array(
+      'feature_relationship' => array(
+        'table' => 'feature_relationship',
+        'columns' => array(
+          'feature_relationship_id' => 'feature_relationship_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_feature_synonym()
+ *
+ * Purpose: To describe the structure of 'feature_synonym' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'feature_synonym' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_feature_synonym() {
+  $description = array(
+    'description' => '',
+    'table' => 'feature_synonym',
+    'fields' => array(
+      'feature_synonym_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'synonym_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'feature_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'is_current' => array(
+        'size' => 'normal',
+        'type' => 'boolean',
+        'not null' => TRUE,
+        'default' => FALSE,
+      ),
+      'is_internal' => array(
+        'size' => 'normal',
+        'type' => 'boolean',
+        'not null' => TRUE,
+        'default' => FALSE,
+      ),
+    ),
+    'unique keys' => array(
+      'feature_synonym_c1' => array(
+        0 => 'synonym_id',
+        1 => 'feature_id',
+        2 => 'pub_id',
+      ),
+    ),
+    'indexes' => array(
+      'feature_synonym_idx1' => array(
+        0 => 'synonym_id',
+      ),
+      'feature_synonym_idx2' => array(
+        0 => 'feature_id',
+      ),
+      'feature_synonym_idx3' => array(
+        0 => 'pub_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'feature_synonym_id',
+    ),
+    'foreign keys' => array(
+      'synonym' => array(
+        'table' => 'synonym',
+        'columns' => array(
+          'synonym_id' => 'synonym_id',
+        ),
+      ),
+      'feature' => array(
+        'table' => 'feature',
+        'columns' => array(
+          'feature_id' => 'feature_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_genotype()
+ *
+ * Purpose: To describe the structure of 'genotype' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'genotype' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_genotype() {
+  $description = array(
+    'description' => '',
+    'table' => 'genotype',
+    'fields' => array(
+      'genotype_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'name' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'uniquename' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => TRUE,
+      ),
+      'description' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'genotype_c1' => array(
+        0 => 'uniquename',
+      ),
+    ),
+    'indexes' => array(
+      'genotype_idx1' => array(
+        0 => 'uniquename',
+      ),
+      'genotype_idx2' => array(
+        0 => 'name',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'genotype_id',
+    ),
+    'foreign keys' => array(
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'feature_genotype',
+      1 => 'genotypeprop',
+      2 => 'nd_experiment_genotype',
+      3 => 'phendesc',
+      4 => 'phenotype_comparison',
+      6 => 'phenstatement',
+      7 => 'stock_genotype',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_genotypeprop()
+ *
+ * Purpose: To describe the structure of 'genotypeprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'genotypeprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_genotypeprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'genotypeprop',
+    'fields' => array(
+      'genotypeprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'genotype_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'genotypeprop_c1' => array(
+        0 => 'genotype_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'genotypeprop_idx1' => array(
+        0 => 'genotype_id',
+      ),
+      'genotypeprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'genotypeprop_id',
+    ),
+    'foreign keys' => array(
+      'genotype' => array(
+        'table' => 'genotype',
+        'columns' => array(
+          'genotype_id' => 'genotype_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_library()
+ *
+ * Purpose: To describe the structure of 'library' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'library' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_library() {
+  $description = array(
+    'description' => '',
+    'table' => 'library',
+    'fields' => array(
+      'library_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'organism_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'name' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => FALSE,
+      ),
+      'uniquename' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'is_obsolete' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'timeaccessioned' => array(
+        'size' => 'normal',
+        'type' => 'datetime',
+        'not null' => TRUE,
+        'default' => 'now()',
+      ),
+      'timelastmodified' => array(
+        'size' => 'normal',
+        'type' => 'datetime',
+        'not null' => TRUE,
+        'default' => 'now()',
+      ),
+    ),
+    'unique keys' => array(
+      'library_c1' => array(
+        0 => 'organism_id',
+        1 => 'uniquename',
+        2 => 'type_id',
+      ),
+    ),
+    'indexes' => array(
+      'library_contact_idx1' => array(
+        0 => 'library_id',
+      ),
+      'library_idx1' => array(
+        0 => 'organism_id',
+      ),
+      'library_idx2' => array(
+        0 => 'type_id',
+      ),
+      'library_idx3' => array(
+        0 => 'uniquename',
+      ),
+      'library_name_ind1' => array(
+        0 => 'name',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'library_id',
+    ),
+    'foreign keys' => array(
+      'organism' => array(
+        'table' => 'organism',
+        'columns' => array(
+          'organism_id' => 'organism_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'cell_line_library',
+      1 => 'library_contact',
+      2 => 'library_cvterm',
+      3 => 'library_dbxref',
+      4 => 'library_expression',
+      5 => 'library_feature',
+      6 => 'libraryprop',
+      7 => 'library_pub',
+      8 => 'library_relationship',
+      10 => 'library_synonym',
+      11 => 'stock_library',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_library_contact()
+ *
+ * Purpose: To describe the structure of 'library_contact' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'library_contact' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_library_contact() {
+  $description = array(
+    'description' => '',
+    'table' => 'library_contact',
+    'fields' => array(
+      'library_contact_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'library_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'contact_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'library_contact_c1' => array(
+        0 => 'library_id',
+        1 => 'contact_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'library_contact_id',
+    ),
+    'foreign keys' => array(
+      'library' => array(
+        'table' => 'library',
+        'columns' => array(
+          'library_id' => 'library_id',
+        ),
+      ),
+      'contact' => array(
+        'table' => 'contact',
+        'columns' => array(
+          'contact_id' => 'contact_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_library_cvterm()
+ *
+ * Purpose: To describe the structure of 'library_cvterm' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'library_cvterm' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_library_cvterm() {
+  $description = array(
+    'description' => '',
+    'table' => 'library_cvterm',
+    'fields' => array(
+      'library_cvterm_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'library_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'cvterm_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'library_cvterm_c1' => array(
+        0 => 'library_id',
+        1 => 'cvterm_id',
+        2 => 'pub_id',
+      ),
+    ),
+    'indexes' => array(
+      'library_cvterm_idx1' => array(
+        0 => 'library_id',
+      ),
+      'library_cvterm_idx2' => array(
+        0 => 'cvterm_id',
+      ),
+      'library_cvterm_idx3' => array(
+        0 => 'pub_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'library_cvterm_id',
+    ),
+    'foreign keys' => array(
+      'library' => array(
+        'table' => 'library',
+        'columns' => array(
+          'library_id' => 'library_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'cvterm_id' => 'cvterm_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_library_dbxref()
+ *
+ * Purpose: To describe the structure of 'library_dbxref' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'library_dbxref' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_library_dbxref() {
+  $description = array(
+    'description' => '',
+    'table' => 'library_dbxref',
+    'fields' => array(
+      'library_dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'library_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'is_current' => array(
+        'size' => 'normal',
+        'type' => 'boolean',
+        'not null' => TRUE,
+        'default' => 'ru',
+      ),
+    ),
+    'unique keys' => array(
+      'library_dbxref_c1' => array(
+        0 => 'library_id',
+        1 => 'dbxref_id',
+      ),
+    ),
+    'indexes' => array(
+      'library_dbxref_idx1' => array(
+        0 => 'library_id',
+      ),
+      'library_dbxref_idx2' => array(
+        0 => 'dbxref_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'library_dbxref_id',
+    ),
+    'foreign keys' => array(
+      'library' => array(
+        'table' => 'library',
+        'columns' => array(
+          'library_id' => 'library_id',
+        ),
+      ),
+      'dbxref' => array(
+        'table' => 'dbxref',
+        'columns' => array(
+          'dbxref_id' => 'dbxref_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_library_expression()
+ *
+ * Purpose: To describe the structure of 'library_expression' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'library_expression' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_library_expression() {
+  $description = array(
+    'description' => '',
+    'table' => 'library_expression',
+    'fields' => array(
+      'library_expression_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'library_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'expression_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'library_expression_c1' => array(
+        0 => 'library_id',
+        1 => 'expression_id',
+      ),
+    ),
+    'indexes' => array(
+      'library_expression_idx1' => array(
+        0 => 'library_id',
+      ),
+      'library_expression_idx2' => array(
+        0 => 'expression_id',
+      ),
+      'library_expression_idx3' => array(
+        0 => 'pub_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'library_expression_id',
+    ),
+    'foreign keys' => array(
+      'library' => array(
+        'table' => 'library',
+        'columns' => array(
+          'library_id' => 'library_id',
+        ),
+      ),
+      'expression' => array(
+        'table' => 'expression',
+        'columns' => array(
+          'expression_id' => 'expression_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'library_expressionprop',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_library_expressionprop()
+ *
+ * Purpose: To describe the structure of 'library_expressionprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'library_expressionprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_library_expressionprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'library_expressionprop',
+    'fields' => array(
+      'library_expressionprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'library_expression_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'library_expressionprop_c1' => array(
+        0 => 'library_expression_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'library_expressionprop_idx1' => array(
+        0 => 'library_expression_id',
+      ),
+      'library_expressionprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'library_expressionprop_id',
+    ),
+    'foreign keys' => array(
+      'library_expression' => array(
+        'table' => 'library_expression',
+        'columns' => array(
+          'library_expression_id' => 'library_expression_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_library_feature()
+ *
+ * Purpose: To describe the structure of 'library_feature' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'library_feature' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_library_feature() {
+  $description = array(
+    'description' => '',
+    'table' => 'library_feature',
+    'fields' => array(
+      'library_feature_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'library_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'feature_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'library_feature_c1' => array(
+        0 => 'library_id',
+        1 => 'feature_id',
+      ),
+    ),
+    'indexes' => array(
+      'library_feature_idx1' => array(
+        0 => 'library_id',
+      ),
+      'library_feature_idx2' => array(
+        0 => 'feature_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'library_feature_id',
+    ),
+    'foreign keys' => array(
+      'library' => array(
+        'table' => 'library',
+        'columns' => array(
+          'library_id' => 'library_id',
+        ),
+      ),
+      'feature' => array(
+        'table' => 'feature',
+        'columns' => array(
+          'feature_id' => 'feature_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'library_featureprop',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_library_featureprop()
+ *
+ * Purpose: To describe the structure of 'library_featureprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'library_featureprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_library_featureprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'library_featureprop',
+    'fields' => array(
+      'library_featureprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'library_feature_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'library_featureprop_c1' => array(
+        0 => 'library_feature_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'library_featureprop_idx1' => array(
+        0 => 'library_feature_id',
+      ),
+      'library_featureprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'library_featureprop_id',
+    ),
+    'foreign keys' => array(
+      'library_feature' => array(
+        'table' => 'library_feature',
+        'columns' => array(
+          'library_feature_id' => 'library_feature_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_libraryprop()
+ *
+ * Purpose: To describe the structure of 'libraryprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'libraryprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_libraryprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'libraryprop',
+    'fields' => array(
+      'libraryprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'library_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'libraryprop_c1' => array(
+        0 => 'library_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'libraryprop_idx1' => array(
+        0 => 'library_id',
+      ),
+      'libraryprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'libraryprop_id',
+    ),
+    'foreign keys' => array(
+      'library' => array(
+        'table' => 'library',
+        'columns' => array(
+          'library_id' => 'library_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'libraryprop_pub',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_libraryprop_pub()
+ *
+ * Purpose: To describe the structure of 'libraryprop_pub' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'libraryprop_pub' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_libraryprop_pub() {
+  $description = array(
+    'description' => '',
+    'table' => 'libraryprop_pub',
+    'fields' => array(
+      'libraryprop_pub_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'libraryprop_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'libraryprop_pub_c1' => array(
+        0 => 'libraryprop_id',
+        1 => 'pub_id',
+      ),
+    ),
+    'indexes' => array(
+      'libraryprop_pub_idx1' => array(
+        0 => 'libraryprop_id',
+      ),
+      'libraryprop_pub_idx2' => array(
+        0 => 'pub_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'libraryprop_pub_id',
+    ),
+    'foreign keys' => array(
+      'libraryprop' => array(
+        'table' => 'libraryprop',
+        'columns' => array(
+          'libraryprop_id' => 'libraryprop_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_library_pub()
+ *
+ * Purpose: To describe the structure of 'library_pub' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'library_pub' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_library_pub() {
+  $description = array(
+    'description' => '',
+    'table' => 'library_pub',
+    'fields' => array(
+      'library_pub_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'library_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'library_pub_c1' => array(
+        0 => 'library_id',
+        1 => 'pub_id',
+      ),
+    ),
+    'indexes' => array(
+      'library_pub_idx1' => array(
+        0 => 'library_id',
+      ),
+      'library_pub_idx2' => array(
+        0 => 'pub_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'library_pub_id',
+    ),
+    'foreign keys' => array(
+      'library' => array(
+        'table' => 'library',
+        'columns' => array(
+          'library_id' => 'library_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_library_relationship()
+ *
+ * Purpose: To describe the structure of 'library_relationship' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'library_relationship' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_library_relationship() {
+  $description = array(
+    'description' => '',
+    'table' => 'library_relationship',
+    'fields' => array(
+      'library_relationship_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'subject_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'object_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'library_relationship_c1' => array(
+        0 => 'subject_id',
+        1 => 'object_id',
+        2 => 'type_id',
+      ),
+    ),
+    'indexes' => array(
+      'library_relationship_idx1' => array(
+        0 => 'subject_id',
+      ),
+      'library_relationship_idx2' => array(
+        0 => 'object_id',
+      ),
+      'library_relationship_idx3' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'library_relationship_id',
+    ),
+    'foreign keys' => array(
+      'library' => array(
+        'table' => 'library',
+        'columns' => array(
+          'subject_id' => 'library_id',
+          'object_id' => 'library_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'library_relationship_pub',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_library_relationship_pub()
+ *
+ * Purpose: To describe the structure of 'library_relationship_pub' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'library_relationship_pub' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_library_relationship_pub() {
+  $description = array(
+    'description' => '',
+    'table' => 'library_relationship_pub',
+    'fields' => array(
+      'library_relationship_pub_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'library_relationship_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'library_relationship_pub_c1' => array(
+        0 => 'library_relationship_id',
+        1 => 'pub_id',
+      ),
+    ),
+    'indexes' => array(
+      'library_relationship_pub_idx1' => array(
+        0 => 'library_relationship_id',
+      ),
+      'library_relationship_pub_idx2' => array(
+        0 => 'pub_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'library_relationship_pub_id',
+    ),
+    'foreign keys' => array(
+      'library_relationship' => array(
+        'table' => 'library_relationship',
+        'columns' => array(
+          'library_relationship_id' => 'library_relationship_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_library_synonym()
+ *
+ * Purpose: To describe the structure of 'library_synonym' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'library_synonym' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_library_synonym() {
+  $description = array(
+    'description' => '',
+    'table' => 'library_synonym',
+    'fields' => array(
+      'library_synonym_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'synonym_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'library_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'is_current' => array(
+        'size' => 'normal',
+        'type' => 'boolean',
+        'not null' => TRUE,
+        'default' => 'ru',
+      ),
+      'is_internal' => array(
+        'size' => 'normal',
+        'type' => 'boolean',
+        'not null' => TRUE,
+        'default' => FALSE,
+      ),
+    ),
+    'unique keys' => array(
+      'library_synonym_c1' => array(
+        0 => 'synonym_id',
+        1 => 'library_id',
+        2 => 'pub_id',
+      ),
+    ),
+    'indexes' => array(
+      'library_synonym_idx1' => array(
+        0 => 'synonym_id',
+      ),
+      'library_synonym_idx2' => array(
+        0 => 'library_id',
+      ),
+      'library_synonym_idx3' => array(
+        0 => 'pub_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'library_synonym_id',
+    ),
+    'foreign keys' => array(
+      'synonym' => array(
+        'table' => 'synonym',
+        'columns' => array(
+          'synonym_id' => 'synonym_id',
+        ),
+      ),
+      'library' => array(
+        'table' => 'library',
+        'columns' => array(
+          'library_id' => 'library_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_magedocumentation()
+ *
+ * Purpose: To describe the structure of 'magedocumentation' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'magedocumentation' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_magedocumentation() {
+  $description = array(
+    'description' => '',
+    'table' => 'magedocumentation',
+    'fields' => array(
+      'magedocumentation_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'mageml_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'tableinfo_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'row_id' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'mageidentifier' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => TRUE,
+      ),
+    ),
+    'indexes' => array(
+      'magedocumentation_idx1' => array(
+        0 => 'mageml_id',
+      ),
+      'magedocumentation_idx2' => array(
+        0 => 'tableinfo_id',
+      ),
+      'magedocumentation_idx3' => array(
+        0 => 'row_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'magedocumentation_id',
+    ),
+    'foreign keys' => array(
+      'mageml' => array(
+        'table' => 'mageml',
+        'columns' => array(
+          'mageml_id' => 'mageml_id',
+        ),
+      ),
+      'tableinfo' => array(
+        'table' => 'tableinfo',
+        'columns' => array(
+          'tableinfo_id' => 'tableinfo_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_mageml()
+ *
+ * Purpose: To describe the structure of 'mageml' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'mageml' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_mageml() {
+  $description = array(
+    'description' => '',
+    'table' => 'mageml',
+    'fields' => array(
+      'mageml_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'mage_package' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => TRUE,
+      ),
+      'mage_ml' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => TRUE,
+      ),
+    ),
+    'primary key' => array(
+      0 => 'mageml_id',
+    ),
+    'foreign keys' => array(
+    ),
+    'referring_tables' => array(
+      0 => 'magedocumentation',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_materialized_view()
+ *
+ * Purpose: To describe the structure of 'materialized_view' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'materialized_view' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_materialized_view() {
+  $description = array(
+    'description' => '',
+    'table' => 'materialized_view',
+    'fields' => array(
+      'materialized_view_id' => array(
+        'size' => 'normal',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'last_update' => array(
+        'size' => 'normal',
+        'type' => 'datetime',
+        'not null' => FALSE,
+      ),
+      'refresh_time' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'name' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '64',
+        'not null' => FALSE,
+      ),
+      'mv_schema' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '64',
+        'not null' => FALSE,
+      ),
+      'mv_table' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '128',
+        'not null' => FALSE,
+      ),
+      'mv_specs' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'indexed' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'query' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'special_index' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+    ),
+    'unique keys' => array(
+      'name' => array(
+        0 => 'name',
+      ),
+    ),
+    'foreign keys' => array(
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_nd_experiment()
+ *
+ * Purpose: To describe the structure of 'nd_experiment' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'nd_experiment' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_nd_experiment() {
+  $description = array(
+    'description' => '',
+    'table' => 'nd_experiment',
+    'fields' => array(
+      'nd_experiment_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'nd_geolocation_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'indexes' => array(
+      'nd_experiment_idx1' => array(
+        0 => 'nd_geolocation_id',
+      ),
+      'nd_experiment_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'nd_experiment_id',
+    ),
+    'foreign keys' => array(
+      'nd_geolocation' => array(
+        'table' => 'nd_geolocation',
+        'columns' => array(
+          'nd_geolocation_id' => 'nd_geolocation_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'nd_experiment_analysis',
+      1 => 'nd_experiment_contact',
+      2 => 'nd_experiment_dbxref',
+      3 => 'nd_experiment_genotype',
+      4 => 'nd_experiment_phenotype',
+      5 => 'nd_experiment_project',
+      6 => 'nd_experimentprop',
+      7 => 'nd_experiment_protocol',
+      8 => 'nd_experiment_pub',
+      9 => 'nd_experiment_stock',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_nd_experiment_analysis()
+ *
+ * Purpose: To describe the structure of 'nd_experiment_analysis' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'nd_experiment_analysis' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_nd_experiment_analysis() {
+  $description = array(
+    'description' => '',
+    'table' => 'nd_experiment_analysis',
+    'fields' => array(
+      'nd_experiment_analysis_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'nd_experiment_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'analysis_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+    ),
+    'indexes' => array(
+      'nd_experiment_analysis_idx1' => array(
+        0 => 'nd_experiment_id',
+      ),
+      'nd_experiment_analysis_idx2' => array(
+        0 => 'analysis_id',
+      ),
+      'nd_experiment_analysis_idx3' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'nd_experiment_analysis_id',
+    ),
+    'foreign keys' => array(
+      'nd_experiment' => array(
+        'table' => 'nd_experiment',
+        'columns' => array(
+          'nd_experiment_id' => 'nd_experiment_id',
+        ),
+      ),
+      'analysis' => array(
+        'table' => 'analysis',
+        'columns' => array(
+          'analysis_id' => 'analysis_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_nd_experiment_contact()
+ *
+ * Purpose: To describe the structure of 'nd_experiment_contact' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'nd_experiment_contact' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_nd_experiment_contact() {
+  $description = array(
+    'description' => '',
+    'table' => 'nd_experiment_contact',
+    'fields' => array(
+      'nd_experiment_contact_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'nd_experiment_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'contact_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'indexes' => array(
+      'nd_experiment_contact_idx1' => array(
+        0 => 'nd_experiment_id',
+      ),
+      'nd_experiment_contact_idx2' => array(
+        0 => 'contact_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'nd_experiment_contact_id',
+    ),
+    'foreign keys' => array(
+      'nd_experiment' => array(
+        'table' => 'nd_experiment',
+        'columns' => array(
+          'nd_experiment_id' => 'nd_experiment_id',
+        ),
+      ),
+      'contact' => array(
+        'table' => 'contact',
+        'columns' => array(
+          'contact_id' => 'contact_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_nd_experiment_dbxref()
+ *
+ * Purpose: To describe the structure of 'nd_experiment_dbxref' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'nd_experiment_dbxref' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_nd_experiment_dbxref() {
+  $description = array(
+    'description' => '',
+    'table' => 'nd_experiment_dbxref',
+    'fields' => array(
+      'nd_experiment_dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'nd_experiment_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'indexes' => array(
+      'nd_experiment_dbxref_idx1' => array(
+        0 => 'nd_experiment_id',
+      ),
+      'nd_experiment_dbxref_idx2' => array(
+        0 => 'dbxref_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'nd_experiment_dbxref_id',
+    ),
+    'foreign keys' => array(
+      'nd_experiment' => array(
+        'table' => 'nd_experiment',
+        'columns' => array(
+          'nd_experiment_id' => 'nd_experiment_id',
+        ),
+      ),
+      'dbxref' => array(
+        'table' => 'dbxref',
+        'columns' => array(
+          'dbxref_id' => 'dbxref_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_nd_experiment_genotype()
+ *
+ * Purpose: To describe the structure of 'nd_experiment_genotype' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'nd_experiment_genotype' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_nd_experiment_genotype() {
+  $description = array(
+    'description' => '',
+    'table' => 'nd_experiment_genotype',
+    'fields' => array(
+      'nd_experiment_genotype_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'nd_experiment_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'genotype_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'nd_experiment_genotype_c1' => array(
+        0 => 'nd_experiment_id',
+        1 => 'genotype_id',
+      ),
+    ),
+    'indexes' => array(
+      'nd_experiment_genotype_idx1' => array(
+        0 => 'nd_experiment_id',
+      ),
+      'nd_experiment_genotype_idx2' => array(
+        0 => 'genotype_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'nd_experiment_genotype_id',
+    ),
+    'foreign keys' => array(
+      'nd_experiment' => array(
+        'table' => 'nd_experiment',
+        'columns' => array(
+          'nd_experiment_id' => 'nd_experiment_id',
+        ),
+      ),
+      'genotype' => array(
+        'table' => 'genotype',
+        'columns' => array(
+          'genotype_id' => 'genotype_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_nd_experiment_phenotype()
+ *
+ * Purpose: To describe the structure of 'nd_experiment_phenotype' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'nd_experiment_phenotype' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_nd_experiment_phenotype() {
+  $description = array(
+    'description' => '',
+    'table' => 'nd_experiment_phenotype',
+    'fields' => array(
+      'nd_experiment_phenotype_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'nd_experiment_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'phenotype_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'nd_experiment_phenotype_c1' => array(
+        0 => 'nd_experiment_id',
+        1 => 'phenotype_id',
+      ),
+    ),
+    'indexes' => array(
+      'nd_experiment_phenotype_idx1' => array(
+        0 => 'nd_experiment_id',
+      ),
+      'nd_experiment_phenotype_idx2' => array(
+        0 => 'phenotype_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'nd_experiment_phenotype_id',
+    ),
+    'foreign keys' => array(
+      'nd_experiment' => array(
+        'table' => 'nd_experiment',
+        'columns' => array(
+          'nd_experiment_id' => 'nd_experiment_id',
+        ),
+      ),
+      'phenotype' => array(
+        'table' => 'phenotype',
+        'columns' => array(
+          'phenotype_id' => 'phenotype_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_nd_experiment_project()
+ *
+ * Purpose: To describe the structure of 'nd_experiment_project' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'nd_experiment_project' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_nd_experiment_project() {
+  $description = array(
+    'description' => '',
+    'table' => 'nd_experiment_project',
+    'fields' => array(
+      'nd_experiment_project_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'project_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'nd_experiment_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'nd_experiment_project_c1' => array(
+        0 => 'project_id',
+        1 => 'nd_experiment_id',
+      ),
+    ),
+    'indexes' => array(
+      'nd_experiment_project_idx1' => array(
+        0 => 'project_id',
+      ),
+      'nd_experiment_project_idx2' => array(
+        0 => 'nd_experiment_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'nd_experiment_project_id',
+    ),
+    'foreign keys' => array(
+      'project' => array(
+        'table' => 'project',
+        'columns' => array(
+          'project_id' => 'project_id',
+        ),
+      ),
+      'nd_experiment' => array(
+        'table' => 'nd_experiment',
+        'columns' => array(
+          'nd_experiment_id' => 'nd_experiment_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_nd_experimentprop()
+ *
+ * Purpose: To describe the structure of 'nd_experimentprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'nd_experimentprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_nd_experimentprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'nd_experimentprop',
+    'fields' => array(
+      'nd_experimentprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'nd_experiment_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'nd_experimentprop_c1' => array(
+        0 => 'nd_experiment_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'nd_experimentprop_idx1' => array(
+        0 => 'nd_experiment_id',
+      ),
+      'nd_experimentprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'nd_experimentprop_id',
+    ),
+    'foreign keys' => array(
+      'nd_experiment' => array(
+        'table' => 'nd_experiment',
+        'columns' => array(
+          'nd_experiment_id' => 'nd_experiment_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_nd_experiment_protocol()
+ *
+ * Purpose: To describe the structure of 'nd_experiment_protocol' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'nd_experiment_protocol' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_nd_experiment_protocol() {
+  $description = array(
+    'description' => '',
+    'table' => 'nd_experiment_protocol',
+    'fields' => array(
+      'nd_experiment_protocol_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'nd_experiment_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'nd_protocol_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'indexes' => array(
+      'nd_experiment_protocol_idx1' => array(
+        0 => 'nd_experiment_id',
+      ),
+      'nd_experiment_protocol_idx2' => array(
+        0 => 'nd_protocol_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'nd_experiment_protocol_id',
+    ),
+    'foreign keys' => array(
+      'nd_experiment' => array(
+        'table' => 'nd_experiment',
+        'columns' => array(
+          'nd_experiment_id' => 'nd_experiment_id',
+        ),
+      ),
+      'nd_protocol' => array(
+        'table' => 'nd_protocol',
+        'columns' => array(
+          'nd_protocol_id' => 'nd_protocol_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_nd_experiment_pub()
+ *
+ * Purpose: To describe the structure of 'nd_experiment_pub' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'nd_experiment_pub' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_nd_experiment_pub() {
+  $description = array(
+    'description' => '',
+    'table' => 'nd_experiment_pub',
+    'fields' => array(
+      'nd_experiment_pub_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'nd_experiment_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'nd_experiment_pub_c1' => array(
+        0 => 'nd_experiment_id',
+        1 => 'pub_id',
+      ),
+    ),
+    'indexes' => array(
+      'nd_experiment_pub_idx1' => array(
+        0 => 'nd_experiment_id',
+      ),
+      'nd_experiment_pub_idx2' => array(
+        0 => 'pub_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'nd_experiment_pub_id',
+    ),
+    'foreign keys' => array(
+      'nd_experiment' => array(
+        'table' => 'nd_experiment',
+        'columns' => array(
+          'nd_experiment_id' => 'nd_experiment_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_nd_experiment_stock()
+ *
+ * Purpose: To describe the structure of 'nd_experiment_stock' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'nd_experiment_stock' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_nd_experiment_stock() {
+  $description = array(
+    'description' => '',
+    'table' => 'nd_experiment_stock',
+    'fields' => array(
+      'nd_experiment_stock_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'nd_experiment_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'stock_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'indexes' => array(
+      'nd_experiment_stock_idx1' => array(
+        0 => 'nd_experiment_id',
+      ),
+      'nd_experiment_stock_idx2' => array(
+        0 => 'stock_id',
+      ),
+      'nd_experiment_stock_idx3' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'nd_experiment_stock_id',
+    ),
+    'foreign keys' => array(
+      'nd_experiment' => array(
+        'table' => 'nd_experiment',
+        'columns' => array(
+          'nd_experiment_id' => 'nd_experiment_id',
+        ),
+      ),
+      'stock' => array(
+        'table' => 'stock',
+        'columns' => array(
+          'stock_id' => 'stock_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'nd_experiment_stock_dbxref',
+      1 => 'nd_experiment_stockprop',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_nd_experiment_stock_dbxref()
+ *
+ * Purpose: To describe the structure of 'nd_experiment_stock_dbxref' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'nd_experiment_stock_dbxref' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_nd_experiment_stock_dbxref() {
+  $description = array(
+    'description' => '',
+    'table' => 'nd_experiment_stock_dbxref',
+    'fields' => array(
+      'nd_experiment_stock_dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'nd_experiment_stock_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'indexes' => array(
+      'nd_experiment_stock_dbxref_idx1' => array(
+        0 => 'nd_experiment_stock_id',
+      ),
+      'nd_experiment_stock_dbxref_idx2' => array(
+        0 => 'dbxref_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'nd_experiment_stock_dbxref_id',
+    ),
+    'foreign keys' => array(
+      'nd_experiment_stock' => array(
+        'table' => 'nd_experiment_stock',
+        'columns' => array(
+          'nd_experiment_stock_id' => 'nd_experiment_stock_id',
+        ),
+      ),
+      'dbxref' => array(
+        'table' => 'dbxref',
+        'columns' => array(
+          'dbxref_id' => 'dbxref_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_nd_experiment_stockprop()
+ *
+ * Purpose: To describe the structure of 'nd_experiment_stockprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'nd_experiment_stockprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_nd_experiment_stockprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'nd_experiment_stockprop',
+    'fields' => array(
+      'nd_experiment_stockprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'nd_experiment_stock_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'nd_experiment_stockprop_c1' => array(
+        0 => 'nd_experiment_stock_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'nd_experiment_stockprop_idx1' => array(
+        0 => 'nd_experiment_stock_id',
+      ),
+      'nd_experiment_stockprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'nd_experiment_stockprop_id',
+    ),
+    'foreign keys' => array(
+      'nd_experiment_stock' => array(
+        'table' => 'nd_experiment_stock',
+        'columns' => array(
+          'nd_experiment_stock_id' => 'nd_experiment_stock_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_nd_geolocation()
+ *
+ * Purpose: To describe the structure of 'nd_geolocation' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'nd_geolocation' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_nd_geolocation() {
+  $description = array(
+    'description' => '',
+    'table' => 'nd_geolocation',
+    'fields' => array(
+      'nd_geolocation_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'description' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'latitude' => array(
+        'size' => 'normal',
+        'type' => 'float',
+        'not null' => FALSE,
+      ),
+      'longitude' => array(
+        'size' => 'normal',
+        'type' => 'float',
+        'not null' => FALSE,
+      ),
+      'geodetic_datum' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '32',
+        'not null' => FALSE,
+      ),
+      'altitude' => array(
+        'size' => 'normal',
+        'type' => 'float',
+        'not null' => FALSE,
+      ),
+    ),
+    'indexes' => array(
+      'nd_geolocation_idx1' => array(
+        0 => 'latitude',
+      ),
+      'nd_geolocation_idx2' => array(
+        0 => 'longitude',
+      ),
+      'nd_geolocation_idx3' => array(
+        0 => 'altitude',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'nd_geolocation_id',
+    ),
+    'foreign keys' => array(
+    ),
+    'referring_tables' => array(
+      0 => 'nd_experiment',
+      1 => 'nd_geolocationprop',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_nd_geolocationprop()
+ *
+ * Purpose: To describe the structure of 'nd_geolocationprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'nd_geolocationprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_nd_geolocationprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'nd_geolocationprop',
+    'fields' => array(
+      'nd_geolocationprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'nd_geolocation_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'nd_geolocationprop_c1' => array(
+        0 => 'nd_geolocation_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'nd_geolocationprop_idx1' => array(
+        0 => 'nd_geolocation_id',
+      ),
+      'nd_geolocationprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'nd_geolocationprop_id',
+    ),
+    'foreign keys' => array(
+      'nd_geolocation' => array(
+        'table' => 'nd_geolocation',
+        'columns' => array(
+          'nd_geolocation_id' => 'nd_geolocation_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_nd_protocol()
+ *
+ * Purpose: To describe the structure of 'nd_protocol' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'nd_protocol' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_nd_protocol() {
+  $description = array(
+    'description' => '',
+    'table' => 'nd_protocol',
+    'fields' => array(
+      'nd_protocol_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'name' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'indexes' => array(
+      'nd_protocol_idx1' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'unique keys' => array(
+      'name' => array(
+        0 => 'name',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'nd_protocol_id',
+    ),
+    'foreign keys' => array(
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'nd_experiment_protocol',
+      1 => 'nd_protocolprop',
+      2 => 'nd_protocol_reagent',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_nd_protocolprop()
+ *
+ * Purpose: To describe the structure of 'nd_protocolprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'nd_protocolprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_nd_protocolprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'nd_protocolprop',
+    'fields' => array(
+      'nd_protocolprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'nd_protocol_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'nd_protocolprop_c1' => array(
+        0 => 'nd_protocol_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'nd_protocolprop_idx1' => array(
+        0 => 'nd_protocol_id',
+      ),
+      'nd_protocolprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'nd_protocolprop_id',
+    ),
+    'foreign keys' => array(
+      'nd_protocol' => array(
+        'table' => 'nd_protocol',
+        'columns' => array(
+          'nd_protocol_id' => 'nd_protocol_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_nd_protocol_reagent()
+ *
+ * Purpose: To describe the structure of 'nd_protocol_reagent' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'nd_protocol_reagent' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_nd_protocol_reagent() {
+  $description = array(
+    'description' => '',
+    'table' => 'nd_protocol_reagent',
+    'fields' => array(
+      'nd_protocol_reagent_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'nd_protocol_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'reagent_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'indexes' => array(
+      'nd_protocol_reagent_idx1' => array(
+        0 => 'nd_protocol_id',
+      ),
+      'nd_protocol_reagent_idx2' => array(
+        0 => 'reagent_id',
+      ),
+      'nd_protocol_reagent_idx3' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'nd_protocol_reagent_id',
+    ),
+    'foreign keys' => array(
+      'nd_protocol' => array(
+        'table' => 'nd_protocol',
+        'columns' => array(
+          'nd_protocol_id' => 'nd_protocol_id',
+        ),
+      ),
+      'nd_reagent' => array(
+        'table' => 'nd_reagent',
+        'columns' => array(
+          'reagent_id' => 'nd_reagent_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_nd_reagent()
+ *
+ * Purpose: To describe the structure of 'nd_reagent' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'nd_reagent' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_nd_reagent() {
+  $description = array(
+    'description' => '',
+    'table' => 'nd_reagent',
+    'fields' => array(
+      'nd_reagent_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'name' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '80',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'feature_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+    ),
+    'indexes' => array(
+      'nd_reagent_idx1' => array(
+        0 => 'type_id',
+      ),
+      'nd_reagent_idx2' => array(
+        0 => 'feature_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'nd_reagent_id',
+    ),
+    'foreign keys' => array(
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+      'feature' => array(
+        'table' => 'feature',
+        'columns' => array(
+          'feature_id' => 'feature_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'nd_protocol_reagent',
+      1 => 'nd_reagentprop',
+      2 => 'nd_reagent_relationship',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_nd_reagentprop()
+ *
+ * Purpose: To describe the structure of 'nd_reagentprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'nd_reagentprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_nd_reagentprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'nd_reagentprop',
+    'fields' => array(
+      'nd_reagentprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'nd_reagent_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'nd_reagentprop_c1' => array(
+        0 => 'nd_reagent_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'nd_reagentprop_idx1' => array(
+        0 => 'nd_reagent_id',
+      ),
+      'nd_reagentprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'nd_reagentprop_id',
+    ),
+    'foreign keys' => array(
+      'nd_reagent' => array(
+        'table' => 'nd_reagent',
+        'columns' => array(
+          'nd_reagent_id' => 'nd_reagent_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_nd_reagent_relationship()
+ *
+ * Purpose: To describe the structure of 'nd_reagent_relationship' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'nd_reagent_relationship' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_nd_reagent_relationship() {
+  $description = array(
+    'description' => '',
+    'table' => 'nd_reagent_relationship',
+    'fields' => array(
+      'nd_reagent_relationship_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'subject_reagent_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'object_reagent_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'indexes' => array(
+      'nd_reagent_relationship_idx1' => array(
+        0 => 'subject_reagent_id',
+      ),
+      'nd_reagent_relationship_idx2' => array(
+        0 => 'object_reagent_id',
+      ),
+      'nd_reagent_relationship_idx3' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'nd_reagent_relationship_id',
+    ),
+    'foreign keys' => array(
+      'nd_reagent' => array(
+        'table' => 'nd_reagent',
+        'columns' => array(
+          'subject_reagent_id' => 'nd_reagent_id',
+          'object_reagent_id' => 'nd_reagent_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_organism()
+ *
+ * Purpose: To describe the structure of 'organism' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'organism' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_organism() {
+  $description = array(
+    'description' => '',
+    'table' => 'organism',
+    'fields' => array(
+      'organism_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'abbreviation' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => FALSE,
+      ),
+      'genus' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => TRUE,
+      ),
+      'species' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => TRUE,
+      ),
+      'common_name' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => FALSE,
+      ),
+      'infraspecific_name' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '1024',
+        'not null' => FALSE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'comment' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+    ),
+    'unique keys' => array(
+      'organism_c1' => array(
+        0 => 'genus',
+        1 => 'species',
+        2 => 'type_id',
+        3 => 'infraspecific_name',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'organism_id',
+    ),
+    'foreign keys' => array(
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'analysis_organism',
+      1 => 'biomaterial',
+      2 => 'cell_line',
+      3 => 'feature',
+      4 => 'featuremap_organism',
+      5 => 'library',
+      6 => 'organism_cvterm',
+      7 => 'organism_dbxref',
+      8 => 'organismprop',
+      9 => 'organism_pub',
+      10 => 'organism_relationship',
+      12 => 'phenotype_comparison',
+      13 => 'phylonode_organism',
+      14 => 'stock',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_organism_cvterm()
+ *
+ * Purpose: To describe the structure of 'organism_cvterm' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'organism_cvterm' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_organism_cvterm() {
+  $description = array(
+    'description' => '',
+    'table' => 'organism_cvterm',
+    'fields' => array(
+      'organism_cvterm_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'organism_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'cvterm_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'organism_cvterm_c1' => array(
+        0 => 'organism_id',
+        1 => 'cvterm_id',
+        2 => 'pub_id',
+      ),
+    ),
+    'indexes' => array(
+      'organism_cvterm_idx1' => array(
+        0 => 'organism_id',
+      ),
+      'organism_cvterm_idx2' => array(
+        0 => 'cvterm_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'organism_cvterm_id',
+    ),
+    'foreign keys' => array(
+      'organism' => array(
+        'table' => 'organism',
+        'columns' => array(
+          'organism_id' => 'organism_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'cvterm_id' => 'cvterm_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'organism_cvtermprop',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_organism_cvtermprop()
+ *
+ * Purpose: To describe the structure of 'organism_cvtermprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'organism_cvtermprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_organism_cvtermprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'organism_cvtermprop',
+    'fields' => array(
+      'organism_cvtermprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'organism_cvterm_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'organism_cvtermprop_c1' => array(
+        0 => 'organism_cvterm_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'organism_cvtermprop_idx1' => array(
+        0 => 'organism_cvterm_id',
+      ),
+      'organism_cvtermprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'organism_cvtermprop_id',
+    ),
+    'foreign keys' => array(
+      'organism_cvterm' => array(
+        'table' => 'organism_cvterm',
+        'columns' => array(
+          'organism_cvterm_id' => 'organism_cvterm_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_organism_dbxref()
+ *
+ * Purpose: To describe the structure of 'organism_dbxref' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'organism_dbxref' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_organism_dbxref() {
+  $description = array(
+    'description' => '',
+    'table' => 'organism_dbxref',
+    'fields' => array(
+      'organism_dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'organism_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'organism_dbxref_c1' => array(
+        0 => 'organism_id',
+        1 => 'dbxref_id',
+      ),
+    ),
+    'indexes' => array(
+      'organism_dbxref_idx1' => array(
+        0 => 'organism_id',
+      ),
+      'organism_dbxref_idx2' => array(
+        0 => 'dbxref_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'organism_dbxref_id',
+    ),
+    'foreign keys' => array(
+      'organism' => array(
+        'table' => 'organism',
+        'columns' => array(
+          'organism_id' => 'organism_id',
+        ),
+      ),
+      'dbxref' => array(
+        'table' => 'dbxref',
+        'columns' => array(
+          'dbxref_id' => 'dbxref_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_organism_feature_count()
+ *
+ * Purpose: To describe the structure of 'organism_feature_count' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'organism_feature_count' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_organism_feature_count() {
+  $description = array(
+    'description' => '',
+    'table' => 'organism_feature_count',
+    'fields' => array(
+      'organism_id' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'genus' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => TRUE,
+      ),
+      'species' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => TRUE,
+      ),
+      'common_name' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => FALSE,
+      ),
+      'num_features' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'cvterm_id' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'feature_type' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => TRUE,
+      ),
+    ),
+    'indexes' => array(
+      'organism_feature_count_idx1' => array(
+        0 => 'organism_id',
+      ),
+      'organism_feature_count_idx2' => array(
+        0 => 'cvterm_id',
+      ),
+      'organism_feature_count_idx3' => array(
+        0 => 'feature_type',
+      ),
+    ),
+    'foreign keys' => array(
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_organismprop()
+ *
+ * Purpose: To describe the structure of 'organismprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'organismprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_organismprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'organismprop',
+    'fields' => array(
+      'organismprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'organism_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'organismprop_c1' => array(
+        0 => 'organism_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'organismprop_idx1' => array(
+        0 => 'organism_id',
+      ),
+      'organismprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'organismprop_id',
+    ),
+    'foreign keys' => array(
+      'organism' => array(
+        'table' => 'organism',
+        'columns' => array(
+          'organism_id' => 'organism_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'organismprop_pub',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_organismprop_pub()
+ *
+ * Purpose: To describe the structure of 'organismprop_pub' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'organismprop_pub' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_organismprop_pub() {
+  $description = array(
+    'description' => '',
+    'table' => 'organismprop_pub',
+    'fields' => array(
+      'organismprop_pub_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'organismprop_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'organismprop_pub_c1' => array(
+        0 => 'organismprop_id',
+        1 => 'pub_id',
+      ),
+    ),
+    'indexes' => array(
+      'organismprop_pub_idx1' => array(
+        0 => 'organismprop_id',
+      ),
+      'organismprop_pub_idx2' => array(
+        0 => 'pub_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'organismprop_pub_id',
+    ),
+    'foreign keys' => array(
+      'organismprop' => array(
+        'table' => 'organismprop',
+        'columns' => array(
+          'organismprop_id' => 'organismprop_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_organism_pub()
+ *
+ * Purpose: To describe the structure of 'organism_pub' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'organism_pub' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_organism_pub() {
+  $description = array(
+    'description' => '',
+    'table' => 'organism_pub',
+    'fields' => array(
+      'organism_pub_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'organism_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'organism_pub_c1' => array(
+        0 => 'organism_id',
+        1 => 'pub_id',
+      ),
+    ),
+    'indexes' => array(
+      'organism_pub_idx1' => array(
+        0 => 'organism_id',
+      ),
+      'organism_pub_idx2' => array(
+        0 => 'pub_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'organism_pub_id',
+    ),
+    'foreign keys' => array(
+      'organism' => array(
+        'table' => 'organism',
+        'columns' => array(
+          'organism_id' => 'organism_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_organism_relationship()
+ *
+ * Purpose: To describe the structure of 'organism_relationship' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'organism_relationship' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_organism_relationship() {
+  $description = array(
+    'description' => '',
+    'table' => 'organism_relationship',
+    'fields' => array(
+      'organism_relationship_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'subject_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'object_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'organism_relationship_c1' => array(
+        0 => 'subject_id',
+        1 => 'object_id',
+        2 => 'type_id',
+        3 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'organism_relationship_idx1' => array(
+        0 => 'subject_id',
+      ),
+      'organism_relationship_idx2' => array(
+        0 => 'object_id',
+      ),
+      'organism_relationship_idx3' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'organism_relationship_id',
+    ),
+    'foreign keys' => array(
+      'organism' => array(
+        'table' => 'organism',
+        'columns' => array(
+          'object_id' => 'organism_id',
+          'subject_id' => 'organism_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_phendesc()
+ *
+ * Purpose: To describe the structure of 'phendesc' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'phendesc' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_phendesc() {
+  $description = array(
+    'description' => '',
+    'table' => 'phendesc',
+    'fields' => array(
+      'phendesc_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'genotype_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'environment_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'description' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'phendesc_c1' => array(
+        0 => 'genotype_id',
+        1 => 'environment_id',
+        2 => 'type_id',
+        3 => 'pub_id',
+      ),
+    ),
+    'indexes' => array(
+      'phendesc_idx1' => array(
+        0 => 'genotype_id',
+      ),
+      'phendesc_idx2' => array(
+        0 => 'environment_id',
+      ),
+      'phendesc_idx3' => array(
+        0 => 'pub_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'phendesc_id',
+    ),
+    'foreign keys' => array(
+      'genotype' => array(
+        'table' => 'genotype',
+        'columns' => array(
+          'genotype_id' => 'genotype_id',
+        ),
+      ),
+      'environment' => array(
+        'table' => 'environment',
+        'columns' => array(
+          'environment_id' => 'environment_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_phenotype()
+ *
+ * Purpose: To describe the structure of 'phenotype' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'phenotype' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_phenotype() {
+  $description = array(
+    'description' => '',
+    'table' => 'phenotype',
+    'fields' => array(
+      'phenotype_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'uniquename' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => TRUE,
+      ),
+      'name' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'observable_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'attr_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'cvalue_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'assay_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+    ),
+    'unique keys' => array(
+      'phenotype_c1' => array(
+        0 => 'uniquename',
+      ),
+    ),
+    'indexes' => array(
+      'phenotype_idx1' => array(
+        0 => 'cvalue_id',
+      ),
+      'phenotype_idx2' => array(
+        0 => 'observable_id',
+      ),
+      'phenotype_idx3' => array(
+        0 => 'attr_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'phenotype_id',
+    ),
+    'foreign keys' => array(
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'observable_id' => 'cvterm_id',
+          'attr_id' => 'cvterm_id',
+          'cvalue_id' => 'cvterm_id',
+          'assay_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'feature_phenotype',
+      1 => 'nd_experiment_phenotype',
+      2 => 'phenotype_comparison',
+      4 => 'phenotype_cvterm',
+      5 => 'phenotypeprop',
+      6 => 'phenstatement',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_phenotype_comparison()
+ *
+ * Purpose: To describe the structure of 'phenotype_comparison' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'phenotype_comparison' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_phenotype_comparison() {
+  $description = array(
+    'description' => '',
+    'table' => 'phenotype_comparison',
+    'fields' => array(
+      'phenotype_comparison_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'genotype1_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'environment1_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'genotype2_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'environment2_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'phenotype1_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'phenotype2_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'organism_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'phenotype_comparison_c1' => array(
+        0 => 'genotype1_id',
+        1 => 'environment1_id',
+        2 => 'genotype2_id',
+        3 => 'environment2_id',
+        4 => 'phenotype1_id',
+        5 => 'pub_id',
+      ),
+    ),
+    'indexes' => array(
+      'phenotype_comparison_idx1' => array(
+        0 => 'genotype1_id',
+      ),
+      'phenotype_comparison_idx2' => array(
+        0 => 'genotype2_id',
+      ),
+      'phenotype_comparison_idx4' => array(
+        0 => 'pub_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'phenotype_comparison_id',
+    ),
+    'foreign keys' => array(
+      'genotype' => array(
+        'table' => 'genotype',
+        'columns' => array(
+          'genotype1_id' => 'genotype_id',
+          'genotype2_id' => 'genotype_id',
+        ),
+      ),
+      'environment' => array(
+        'table' => 'environment',
+        'columns' => array(
+          'environment1_id' => 'environment_id',
+          'environment2_id' => 'environment_id',
+        ),
+      ),
+      'phenotype' => array(
+        'table' => 'phenotype',
+        'columns' => array(
+          'phenotype1_id' => 'phenotype_id',
+          'phenotype2_id' => 'phenotype_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+      'organism' => array(
+        'table' => 'organism',
+        'columns' => array(
+          'organism_id' => 'organism_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'phenotype_comparison_cvterm',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_phenotype_comparison_cvterm()
+ *
+ * Purpose: To describe the structure of 'phenotype_comparison_cvterm' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'phenotype_comparison_cvterm' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_phenotype_comparison_cvterm() {
+  $description = array(
+    'description' => '',
+    'table' => 'phenotype_comparison_cvterm',
+    'fields' => array(
+      'phenotype_comparison_cvterm_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'phenotype_comparison_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'cvterm_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'phenotype_comparison_cvterm_c1' => array(
+        0 => 'phenotype_comparison_id',
+        1 => 'cvterm_id',
+      ),
+    ),
+    'indexes' => array(
+      'phenotype_comparison_cvterm_idx1' => array(
+        0 => 'phenotype_comparison_id',
+      ),
+      'phenotype_comparison_cvterm_idx2' => array(
+        0 => 'cvterm_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'phenotype_comparison_cvterm_id',
+    ),
+    'foreign keys' => array(
+      'phenotype_comparison' => array(
+        'table' => 'phenotype_comparison',
+        'columns' => array(
+          'phenotype_comparison_id' => 'phenotype_comparison_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'cvterm_id' => 'cvterm_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_phenotype_cvterm()
+ *
+ * Purpose: To describe the structure of 'phenotype_cvterm' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'phenotype_cvterm' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_phenotype_cvterm() {
+  $description = array(
+    'description' => '',
+    'table' => 'phenotype_cvterm',
+    'fields' => array(
+      'phenotype_cvterm_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'phenotype_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'cvterm_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'phenotype_cvterm_c1' => array(
+        0 => 'phenotype_id',
+        1 => 'cvterm_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'phenotype_cvterm_idx1' => array(
+        0 => 'phenotype_id',
+      ),
+      'phenotype_cvterm_idx2' => array(
+        0 => 'cvterm_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'phenotype_cvterm_id',
+    ),
+    'foreign keys' => array(
+      'phenotype' => array(
+        'table' => 'phenotype',
+        'columns' => array(
+          'phenotype_id' => 'phenotype_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'cvterm_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_phenotypeprop()
+ *
+ * Purpose: To describe the structure of 'phenotypeprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'phenotypeprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_phenotypeprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'phenotypeprop',
+    'fields' => array(
+      'phenotypeprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'phenotype_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'phenotypeprop_c1' => array(
+        0 => 'phenotype_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'phenotypeprop_idx1' => array(
+        0 => 'phenotype_id',
+      ),
+      'phenotypeprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'phenotypeprop_id',
+    ),
+    'foreign keys' => array(
+      'phenotype' => array(
+        'table' => 'phenotype',
+        'columns' => array(
+          'phenotype_id' => 'phenotype_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_phenstatement()
+ *
+ * Purpose: To describe the structure of 'phenstatement' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'phenstatement' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_phenstatement() {
+  $description = array(
+    'description' => '',
+    'table' => 'phenstatement',
+    'fields' => array(
+      'phenstatement_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'genotype_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'environment_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'phenotype_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'phenstatement_c1' => array(
+        0 => 'genotype_id',
+        1 => 'phenotype_id',
+        2 => 'environment_id',
+        3 => 'type_id',
+        4 => 'pub_id',
+      ),
+    ),
+    'indexes' => array(
+      'phenstatement_idx1' => array(
+        0 => 'genotype_id',
+      ),
+      'phenstatement_idx2' => array(
+        0 => 'phenotype_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'phenstatement_id',
+    ),
+    'foreign keys' => array(
+      'genotype' => array(
+        'table' => 'genotype',
+        'columns' => array(
+          'genotype_id' => 'genotype_id',
+        ),
+      ),
+      'environment' => array(
+        'table' => 'environment',
+        'columns' => array(
+          'environment_id' => 'environment_id',
+        ),
+      ),
+      'phenotype' => array(
+        'table' => 'phenotype',
+        'columns' => array(
+          'phenotype_id' => 'phenotype_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_phylonode()
+ *
+ * Purpose: To describe the structure of 'phylonode' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'phylonode' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_phylonode() {
+  $description = array(
+    'description' => '',
+    'table' => 'phylonode',
+    'fields' => array(
+      'phylonode_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'phylotree_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'parent_phylonode_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'left_idx' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'right_idx' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'feature_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'label' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => FALSE,
+      ),
+      'distance' => array(
+        'size' => 'big',
+        'type' => 'float',
+        'not null' => FALSE,
+      ),
+    ),
+    'indexes' => array(
+      'parent_phylonode_id' => array(
+        0 => 'parent_phylonode_id',
+      ),
+    ),
+    'unique keys' => array(
+      'phylotree_id_left_idx' => array(
+        0 => 'phylotree_id',
+        1 => 'left_idx',
+      ),
+      'phylotree_id_right_idx' => array(
+        0 => 'phylotree_id',
+        1 => 'right_idx',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'phylonode_id',
+    ),
+    'foreign keys' => array(
+      'phylotree' => array(
+        'table' => 'phylotree',
+        'columns' => array(
+          'phylotree_id' => 'phylotree_id',
+        ),
+      ),
+      'phylonode' => array(
+        'table' => 'phylonode',
+        'columns' => array(
+          'parent_phylonode_id' => 'phylonode_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+      'feature' => array(
+        'table' => 'feature',
+        'columns' => array(
+          'feature_id' => 'feature_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'phylonode',
+      1 => 'phylonode_dbxref',
+      2 => 'phylonode_organism',
+      3 => 'phylonodeprop',
+      4 => 'phylonode_pub',
+      5 => 'phylonode_relationship',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_phylonode_dbxref()
+ *
+ * Purpose: To describe the structure of 'phylonode_dbxref' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'phylonode_dbxref' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_phylonode_dbxref() {
+  $description = array(
+    'description' => '',
+    'table' => 'phylonode_dbxref',
+    'fields' => array(
+      'phylonode_dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'phylonode_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'indexes' => array(
+      'phylonode_dbxref_idx1' => array(
+        0 => 'phylonode_id',
+      ),
+      'phylonode_dbxref_idx2' => array(
+        0 => 'dbxref_id',
+      ),
+    ),
+    'unique keys' => array(
+      'phylonode_id_dbxref_id' => array(
+        0 => 'phylonode_id',
+        1 => 'dbxref_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'phylonode_dbxref_id',
+    ),
+    'foreign keys' => array(
+      'phylonode' => array(
+        'table' => 'phylonode',
+        'columns' => array(
+          'phylonode_id' => 'phylonode_id',
+        ),
+      ),
+      'dbxref' => array(
+        'table' => 'dbxref',
+        'columns' => array(
+          'dbxref_id' => 'dbxref_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_phylonode_organism()
+ *
+ * Purpose: To describe the structure of 'phylonode_organism' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'phylonode_organism' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_phylonode_organism() {
+  $description = array(
+    'description' => '',
+    'table' => 'phylonode_organism',
+    'fields' => array(
+      'phylonode_organism_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'phylonode_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'organism_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'indexes' => array(
+      'phylonode_organism_idx1' => array(
+        0 => 'phylonode_id',
+      ),
+      'phylonode_organism_idx2' => array(
+        0 => 'organism_id',
+      ),
+    ),
+    'unique keys' => array(
+      'phylonode_id' => array(
+        0 => 'phylonode_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'phylonode_organism_id',
+    ),
+    'foreign keys' => array(
+      'phylonode' => array(
+        'table' => 'phylonode',
+        'columns' => array(
+          'phylonode_id' => 'phylonode_id',
+        ),
+      ),
+      'organism' => array(
+        'table' => 'organism',
+        'columns' => array(
+          'organism_id' => 'organism_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_phylonodeprop()
+ *
+ * Purpose: To describe the structure of 'phylonodeprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'phylonodeprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_phylonodeprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'phylonodeprop',
+    'fields' => array(
+      'phylonodeprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'phylonode_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'indexes' => array(
+      'phylonodeprop_idx1' => array(
+        0 => 'phylonode_id',
+      ),
+      'phylonodeprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'unique keys' => array(
+      'phylonode_id_type_id_value_rank' => array(
+        0 => 'phylonode_id',
+        1 => 'type_id',
+        2 => 'value',
+        3 => 'rank',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'phylonodeprop_id',
+    ),
+    'foreign keys' => array(
+      'phylonode' => array(
+        'table' => 'phylonode',
+        'columns' => array(
+          'phylonode_id' => 'phylonode_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_phylonode_pub()
+ *
+ * Purpose: To describe the structure of 'phylonode_pub' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'phylonode_pub' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_phylonode_pub() {
+  $description = array(
+    'description' => '',
+    'table' => 'phylonode_pub',
+    'fields' => array(
+      'phylonode_pub_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'phylonode_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'indexes' => array(
+      'phylonode_pub_idx1' => array(
+        0 => 'phylonode_id',
+      ),
+      'phylonode_pub_idx2' => array(
+        0 => 'pub_id',
+      ),
+    ),
+    'unique keys' => array(
+      'phylonode_id_pub_id' => array(
+        0 => 'phylonode_id',
+        1 => 'pub_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'phylonode_pub_id',
+    ),
+    'foreign keys' => array(
+      'phylonode' => array(
+        'table' => 'phylonode',
+        'columns' => array(
+          'phylonode_id' => 'phylonode_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_phylonode_relationship()
+ *
+ * Purpose: To describe the structure of 'phylonode_relationship' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'phylonode_relationship' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_phylonode_relationship() {
+  $description = array(
+    'description' => '',
+    'table' => 'phylonode_relationship',
+    'fields' => array(
+      'phylonode_relationship_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'subject_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'object_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'phylotree_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'indexes' => array(
+      'phylonode_relationship_idx1' => array(
+        0 => 'subject_id',
+      ),
+      'phylonode_relationship_idx2' => array(
+        0 => 'object_id',
+      ),
+      'phylonode_relationship_idx3' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'phylonode_relationship_id',
+    ),
+    'unique keys' => array(
+      'subject_id_object_id_type_id' => array(
+        0 => 'subject_id',
+        1 => 'object_id',
+        2 => 'type_id',
+      ),
+    ),
+    'foreign keys' => array(
+      'phylonode' => array(
+        'table' => 'phylonode',
+        'columns' => array(
+          'subject_id' => 'phylonode_id',
+          'object_id' => 'phylonode_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+      'phylotree' => array(
+        'table' => 'phylotree',
+        'columns' => array(
+          'phylotree_id' => 'phylotree_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_phylotree()
+ *
+ * Purpose: To describe the structure of 'phylotree' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'phylotree' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_phylotree() {
+  $description = array(
+    'description' => '',
+    'table' => 'phylotree',
+    'fields' => array(
+      'phylotree_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'name' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => FALSE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'analysis_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'comment' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+    ),
+    'indexes' => array(
+      'phylotree_idx1' => array(
+        0 => 'phylotree_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'phylotree_id',
+    ),
+    'foreign keys' => array(
+      'dbxref' => array(
+        'table' => 'dbxref',
+        'columns' => array(
+          'dbxref_id' => 'dbxref_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+      'analysis' => array(
+        'table' => 'analysis',
+        'columns' => array(
+          'analysis_id' => 'analysis_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'phylonode',
+      1 => 'phylonode_relationship',
+      2 => 'phylotreeprop',
+      3 => 'phylotree_pub',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_phylotreeprop()
+ *
+ * Purpose: To describe the structure of 'phylotreeprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'phylotreeprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_phylotreeprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'phylotreeprop',
+    'fields' => array(
+      'phylotreeprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'phylotree_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'phylotreeprop_c1' => array(
+        0 => 'phylotree_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'phylotreeprop_idx1' => array(
+        0 => 'phylotree_id',
+      ),
+      'phylotreeprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'phylotreeprop_id',
+    ),
+    'foreign keys' => array(
+      'phylotree' => array(
+        'table' => 'phylotree',
+        'columns' => array(
+          'phylotree_id' => 'phylotree_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_phylotree_pub()
+ *
+ * Purpose: To describe the structure of 'phylotree_pub' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'phylotree_pub' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_phylotree_pub() {
+  $description = array(
+    'description' => '',
+    'table' => 'phylotree_pub',
+    'fields' => array(
+      'phylotree_pub_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'phylotree_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'indexes' => array(
+      'phylotree_pub_idx1' => array(
+        0 => 'phylotree_id',
+      ),
+      'phylotree_pub_idx2' => array(
+        0 => 'pub_id',
+      ),
+    ),
+    'unique keys' => array(
+      'phylotree_id_pub_id' => array(
+        0 => 'phylotree_id',
+        1 => 'pub_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'phylotree_pub_id',
+    ),
+    'foreign keys' => array(
+      'phylotree' => array(
+        'table' => 'phylotree',
+        'columns' => array(
+          'phylotree_id' => 'phylotree_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_project()
+ *
+ * Purpose: To describe the structure of 'project' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'project' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_project() {
+  $description = array(
+    'description' => '',
+    'table' => 'project',
+    'fields' => array(
+      'project_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'name' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => TRUE,
+      ),
+      'description' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+    ),
+    'unique keys' => array(
+      'project_c1' => array(
+        0 => 'name',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'project_id',
+    ),
+    'foreign keys' => array(
+    ),
+    'referring_tables' => array(
+      0 => 'assay_project',
+      1 => 'nd_experiment_project',
+      2 => 'project_analysis',
+      3 => 'project_contact',
+      4 => 'project_dbxref',
+      5 => 'project_feature',
+      6 => 'projectprop',
+      7 => 'project_pub',
+      8 => 'project_relationship',
+      10 => 'project_stock',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_project_analysis()
+ *
+ * Purpose: To describe the structure of 'project_analysis' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'project_analysis' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_project_analysis() {
+  $description = array(
+    'description' => '',
+    'table' => 'project_analysis',
+    'fields' => array(
+      'project_analysis_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'project_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'analysis_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'project_analysis_c1' => array(
+        0 => 'project_id',
+        1 => 'analysis_id',
+      ),
+    ),
+    'indexes' => array(
+      'project_analysis_idx1' => array(
+        0 => 'project_id',
+      ),
+      'project_analysis_idx2' => array(
+        0 => 'analysis_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'project_analysis_id',
+    ),
+    'foreign keys' => array(
+      'project' => array(
+        'table' => 'project',
+        'columns' => array(
+          'project_id' => 'project_id',
+        ),
+      ),
+      'analysis' => array(
+        'table' => 'analysis',
+        'columns' => array(
+          'analysis_id' => 'analysis_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_project_contact()
+ *
+ * Purpose: To describe the structure of 'project_contact' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'project_contact' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_project_contact() {
+  $description = array(
+    'description' => '',
+    'table' => 'project_contact',
+    'fields' => array(
+      'project_contact_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'project_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'contact_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'project_contact_c1' => array(
+        0 => 'project_id',
+        1 => 'contact_id',
+      ),
+    ),
+    'indexes' => array(
+      'project_contact_idx1' => array(
+        0 => 'project_id',
+      ),
+      'project_contact_idx2' => array(
+        0 => 'contact_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'project_contact_id',
+    ),
+    'foreign keys' => array(
+      'project' => array(
+        'table' => 'project',
+        'columns' => array(
+          'project_id' => 'project_id',
+        ),
+      ),
+      'contact' => array(
+        'table' => 'contact',
+        'columns' => array(
+          'contact_id' => 'contact_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_project_dbxref()
+ *
+ * Purpose: To describe the structure of 'project_dbxref' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'project_dbxref' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_project_dbxref() {
+  $description = array(
+    'description' => '',
+    'table' => 'project_dbxref',
+    'fields' => array(
+      'project_dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'project_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'is_current' => array(
+        'size' => 'normal',
+        'type' => 'boolean',
+        'not null' => TRUE,
+        'default' => 'ru',
+      ),
+    ),
+    'unique keys' => array(
+      'project_dbxref_c1' => array(
+        0 => 'project_id',
+        1 => 'dbxref_id',
+      ),
+    ),
+    'indexes' => array(
+      'project_dbxref_idx1' => array(
+        0 => 'project_id',
+      ),
+      'project_dbxref_idx2' => array(
+        0 => 'dbxref_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'project_dbxref_id',
+    ),
+    'foreign keys' => array(
+      'dbxref' => array(
+        'table' => 'dbxref',
+        'columns' => array(
+          'dbxref_id' => 'dbxref_id',
+        ),
+      ),
+      'project' => array(
+        'table' => 'project',
+        'columns' => array(
+          'project_id' => 'project_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_project_feature()
+ *
+ * Purpose: To describe the structure of 'project_feature' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'project_feature' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_project_feature() {
+  $description = array(
+    'description' => '',
+    'table' => 'project_feature',
+    'fields' => array(
+      'project_feature_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'feature_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'project_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'project_feature_c1' => array(
+        0 => 'feature_id',
+        1 => 'project_id',
+      ),
+    ),
+    'indexes' => array(
+      'project_feature_idx1' => array(
+        0 => 'feature_id',
+      ),
+      'project_feature_idx2' => array(
+        0 => 'project_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'project_feature_id',
+    ),
+    'foreign keys' => array(
+      'feature' => array(
+        'table' => 'feature',
+        'columns' => array(
+          'feature_id' => 'feature_id',
+        ),
+      ),
+      'project' => array(
+        'table' => 'project',
+        'columns' => array(
+          'project_id' => 'project_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_projectprop()
+ *
+ * Purpose: To describe the structure of 'projectprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'projectprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_projectprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'projectprop',
+    'fields' => array(
+      'projectprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'project_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'projectprop_c1' => array(
+        0 => 'project_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'projectprop_id',
+    ),
+    'foreign keys' => array(
+      'project' => array(
+        'table' => 'project',
+        'columns' => array(
+          'project_id' => 'project_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_project_pub()
+ *
+ * Purpose: To describe the structure of 'project_pub' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'project_pub' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_project_pub() {
+  $description = array(
+    'description' => '',
+    'table' => 'project_pub',
+    'fields' => array(
+      'project_pub_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'project_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'project_pub_c1' => array(
+        0 => 'project_id',
+        1 => 'pub_id',
+      ),
+    ),
+    'indexes' => array(
+      'project_pub_idx1' => array(
+        0 => 'project_id',
+      ),
+      'project_pub_idx2' => array(
+        0 => 'pub_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'project_pub_id',
+    ),
+    'foreign keys' => array(
+      'project' => array(
+        'table' => 'project',
+        'columns' => array(
+          'project_id' => 'project_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_project_relationship()
+ *
+ * Purpose: To describe the structure of 'project_relationship' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'project_relationship' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_project_relationship() {
+  $description = array(
+    'description' => '',
+    'table' => 'project_relationship',
+    'fields' => array(
+      'project_relationship_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'subject_project_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'object_project_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'project_relationship_c1' => array(
+        0 => 'subject_project_id',
+        1 => 'object_project_id',
+        2 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'project_relationship_id',
+    ),
+    'foreign keys' => array(
+      'project' => array(
+        'table' => 'project',
+        'columns' => array(
+          'subject_project_id' => 'project_id',
+          'object_project_id' => 'project_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_project_stock()
+ *
+ * Purpose: To describe the structure of 'project_stock' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'project_stock' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_project_stock() {
+  $description = array(
+    'description' => '',
+    'table' => 'project_stock',
+    'fields' => array(
+      'project_stock_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'stock_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'project_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'project_stock_c1' => array(
+        0 => 'stock_id',
+        1 => 'project_id',
+      ),
+    ),
+    'indexes' => array(
+      'project_stock_idx1' => array(
+        0 => 'stock_id',
+      ),
+      'project_stock_idx2' => array(
+        0 => 'project_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'project_stock_id',
+    ),
+    'foreign keys' => array(
+      'stock' => array(
+        'table' => 'stock',
+        'columns' => array(
+          'stock_id' => 'stock_id',
+        ),
+      ),
+      'project' => array(
+        'table' => 'project',
+        'columns' => array(
+          'project_id' => 'project_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_protocol()
+ *
+ * Purpose: To describe the structure of 'protocol' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'protocol' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_protocol() {
+  $description = array(
+    'description' => '',
+    'table' => 'protocol',
+    'fields' => array(
+      'protocol_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'name' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => TRUE,
+      ),
+      'uri' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'protocoldescription' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'hardwaredescription' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'softwaredescription' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+    ),
+    'unique keys' => array(
+      'protocol_c1' => array(
+        0 => 'name',
+      ),
+    ),
+    'indexes' => array(
+      'protocol_idx1' => array(
+        0 => 'type_id',
+      ),
+      'protocol_idx2' => array(
+        0 => 'pub_id',
+      ),
+      'protocol_idx3' => array(
+        0 => 'dbxref_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'protocol_id',
+    ),
+    'foreign keys' => array(
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+      'dbxref' => array(
+        'table' => 'dbxref',
+        'columns' => array(
+          'dbxref_id' => 'dbxref_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'acquisition',
+      1 => 'arraydesign',
+      2 => 'assay',
+      3 => 'protocolparam',
+      4 => 'quantification',
+      5 => 'treatment',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_protocolparam()
+ *
+ * Purpose: To describe the structure of 'protocolparam' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'protocolparam' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_protocolparam() {
+  $description = array(
+    'description' => '',
+    'table' => 'protocolparam',
+    'fields' => array(
+      'protocolparam_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'protocol_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'name' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => TRUE,
+      ),
+      'datatype_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'unittype_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'indexes' => array(
+      'protocolparam_idx1' => array(
+        0 => 'protocol_id',
+      ),
+      'protocolparam_idx2' => array(
+        0 => 'datatype_id',
+      ),
+      'protocolparam_idx3' => array(
+        0 => 'unittype_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'protocolparam_id',
+    ),
+    'foreign keys' => array(
+      'protocol' => array(
+        'table' => 'protocol',
+        'columns' => array(
+          'protocol_id' => 'protocol_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'datatype_id' => 'cvterm_id',
+          'unittype_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_pub()
+ *
+ * Purpose: To describe the structure of 'pub' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'pub' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_pub() {
+  $description = array(
+    'description' => '',
+    'table' => 'pub',
+    'fields' => array(
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'title' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'volumetitle' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'volume' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => FALSE,
+      ),
+      'series_name' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => FALSE,
+      ),
+      'issue' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => FALSE,
+      ),
+      'pyear' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => FALSE,
+      ),
+      'pages' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => FALSE,
+      ),
+      'miniref' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => FALSE,
+      ),
+      'uniquename' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'is_obsolete' => array(
+        'size' => 'normal',
+        'type' => 'boolean',
+        'not null' => FALSE,
+        'default' => FALSE,
+      ),
+      'publisher' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => FALSE,
+      ),
+      'pubplace' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => FALSE,
+      ),
+    ),
+    'unique keys' => array(
+      'pub_c1' => array(
+        0 => 'uniquename',
+      ),
+    ),
+    'indexes' => array(
+      'pub_idx1' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'pub_id',
+    ),
+    'foreign keys' => array(
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'analysis_pub',
+      1 => 'cell_line_cvterm',
+      2 => 'cell_line_feature',
+      3 => 'cell_line_library',
+      4 => 'cell_lineprop_pub',
+      5 => 'cell_line_pub',
+      6 => 'cell_line_synonym',
+      7 => 'expression_pub',
+      8 => 'feature_cvterm',
+      9 => 'feature_cvterm_pub',
+      10 => 'feature_expression',
+      11 => 'featureloc_pub',
+      12 => 'featuremap_pub',
+      13 => 'featureprop_pub',
+      14 => 'feature_pub',
+      15 => 'feature_relationshipprop_pub',
+      16 => 'feature_relationship_pub',
+      17 => 'feature_synonym',
+      18 => 'library_cvterm',
+      19 => 'library_expression',
+      20 => 'libraryprop_pub',
+      21 => 'library_pub',
+      22 => 'library_relationship_pub',
+      23 => 'library_synonym',
+      24 => 'nd_experiment_pub',
+      25 => 'organism_cvterm',
+      26 => 'organismprop_pub',
+      27 => 'organism_pub',
+      28 => 'phendesc',
+      29 => 'phenotype_comparison',
+      30 => 'phenotype_comparison_cvterm',
+      31 => 'phenstatement',
+      32 => 'phylonode_pub',
+      33 => 'phylotree_pub',
+      34 => 'project_pub',
+      35 => 'protocol',
+      36 => 'pubauthor',
+      37 => 'pub_dbxref',
+      38 => 'pubprop',
+      39 => 'pub_relationship',
+      41 => 'stock_cvterm',
+      42 => 'stockprop_pub',
+      43 => 'stock_pub',
+      44 => 'stock_relationship_cvterm',
+      45 => 'stock_relationship_pub',
+      46 => 'study',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_pubauthor()
+ *
+ * Purpose: To describe the structure of 'pubauthor' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'pubauthor' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_pubauthor() {
+  $description = array(
+    'description' => '',
+    'table' => 'pubauthor',
+    'fields' => array(
+      'pubauthor_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'editor' => array(
+        'size' => 'normal',
+        'type' => 'boolean',
+        'not null' => FALSE,
+        'default' => FALSE,
+      ),
+      'surname' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '100',
+        'not null' => TRUE,
+      ),
+      'givennames' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '100',
+        'not null' => FALSE,
+      ),
+      'suffix' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '100',
+        'not null' => FALSE,
+      ),
+    ),
+    'unique keys' => array(
+      'pubauthor_c1' => array(
+        0 => 'pub_id',
+        1 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'pubauthor_contact_idx1' => array(
+        0 => 'pubauthor_id',
+      ),
+      'pubauthor_idx2' => array(
+        0 => 'pub_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'pubauthor_id',
+    ),
+    'foreign keys' => array(
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'pubauthor_contact',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_pubauthor_contact()
+ *
+ * Purpose: To describe the structure of 'pubauthor_contact' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'pubauthor_contact' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_pubauthor_contact() {
+  $description = array(
+    'description' => '',
+    'table' => 'pubauthor_contact',
+    'fields' => array(
+      'pubauthor_contact_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'contact_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pubauthor_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'pubauthor_contact_c1' => array(
+        0 => 'contact_id',
+        1 => 'pubauthor_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'pubauthor_contact_id',
+    ),
+    'foreign keys' => array(
+      'pubauthor' => array(
+        'table' => 'pubauthor',
+        'columns' => array(
+          'pubauthor_id' => 'pubauthor_id',
+        ),
+      ),
+      'contact' => array(
+        'table' => 'contact',
+        'columns' => array(
+          'contact_id' => 'contact_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_pub_dbxref()
+ *
+ * Purpose: To describe the structure of 'pub_dbxref' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'pub_dbxref' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_pub_dbxref() {
+  $description = array(
+    'description' => '',
+    'table' => 'pub_dbxref',
+    'fields' => array(
+      'pub_dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'is_current' => array(
+        'size' => 'normal',
+        'type' => 'boolean',
+        'not null' => TRUE,
+        'default' => 'ru',
+      ),
+    ),
+    'unique keys' => array(
+      'pub_dbxref_c1' => array(
+        0 => 'pub_id',
+        1 => 'dbxref_id',
+      ),
+    ),
+    'indexes' => array(
+      'pub_dbxref_idx1' => array(
+        0 => 'pub_id',
+      ),
+      'pub_dbxref_idx2' => array(
+        0 => 'dbxref_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'pub_dbxref_id',
+    ),
+    'foreign keys' => array(
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+      'dbxref' => array(
+        'table' => 'dbxref',
+        'columns' => array(
+          'dbxref_id' => 'dbxref_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_pubprop()
+ *
+ * Purpose: To describe the structure of 'pubprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'pubprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_pubprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'pubprop',
+    'fields' => array(
+      'pubprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => TRUE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+    ),
+    'unique keys' => array(
+      'pubprop_c1' => array(
+        0 => 'pub_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'pubprop_idx1' => array(
+        0 => 'pub_id',
+      ),
+      'pubprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'pubprop_id',
+    ),
+    'foreign keys' => array(
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_pub_relationship()
+ *
+ * Purpose: To describe the structure of 'pub_relationship' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'pub_relationship' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_pub_relationship() {
+  $description = array(
+    'description' => '',
+    'table' => 'pub_relationship',
+    'fields' => array(
+      'pub_relationship_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'subject_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'object_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'pub_relationship_c1' => array(
+        0 => 'subject_id',
+        1 => 'object_id',
+        2 => 'type_id',
+      ),
+    ),
+    'indexes' => array(
+      'pub_relationship_idx1' => array(
+        0 => 'subject_id',
+      ),
+      'pub_relationship_idx2' => array(
+        0 => 'object_id',
+      ),
+      'pub_relationship_idx3' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'pub_relationship_id',
+    ),
+    'foreign keys' => array(
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'subject_id' => 'pub_id',
+          'object_id' => 'pub_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_quantification()
+ *
+ * Purpose: To describe the structure of 'quantification' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'quantification' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_quantification() {
+  $description = array(
+    'description' => '',
+    'table' => 'quantification',
+    'fields' => array(
+      'quantification_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'acquisition_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'operator_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'protocol_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'analysis_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'quantificationdate' => array(
+        'size' => 'normal',
+        'type' => 'datetime',
+        'not null' => FALSE,
+        'default' => 'now()',
+      ),
+      'name' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'uri' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+    ),
+    'unique keys' => array(
+      'quantification_c1' => array(
+        0 => 'name',
+        1 => 'analysis_id',
+      ),
+    ),
+    'indexes' => array(
+      'quantification_idx1' => array(
+        0 => 'acquisition_id',
+      ),
+      'quantification_idx2' => array(
+        0 => 'operator_id',
+      ),
+      'quantification_idx3' => array(
+        0 => 'protocol_id',
+      ),
+      'quantification_idx4' => array(
+        0 => 'analysis_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'quantification_id',
+    ),
+    'foreign keys' => array(
+      'acquisition' => array(
+        'table' => 'acquisition',
+        'columns' => array(
+          'acquisition_id' => 'acquisition_id',
+        ),
+      ),
+      'contact' => array(
+        'table' => 'contact',
+        'columns' => array(
+          'operator_id' => 'contact_id',
+        ),
+      ),
+      'protocol' => array(
+        'table' => 'protocol',
+        'columns' => array(
+          'protocol_id' => 'protocol_id',
+        ),
+      ),
+      'analysis' => array(
+        'table' => 'analysis',
+        'columns' => array(
+          'analysis_id' => 'analysis_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'elementresult',
+      1 => 'quantificationprop',
+      2 => 'quantification_relationship',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_quantificationprop()
+ *
+ * Purpose: To describe the structure of 'quantificationprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'quantificationprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_quantificationprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'quantificationprop',
+    'fields' => array(
+      'quantificationprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'quantification_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'quantificationprop_c1' => array(
+        0 => 'quantification_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'quantificationprop_idx1' => array(
+        0 => 'quantification_id',
+      ),
+      'quantificationprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'quantificationprop_id',
+    ),
+    'foreign keys' => array(
+      'quantification' => array(
+        'table' => 'quantification',
+        'columns' => array(
+          'quantification_id' => 'quantification_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_quantification_relationship()
+ *
+ * Purpose: To describe the structure of 'quantification_relationship' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'quantification_relationship' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_quantification_relationship() {
+  $description = array(
+    'description' => '',
+    'table' => 'quantification_relationship',
+    'fields' => array(
+      'quantification_relationship_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'subject_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'object_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'quantification_relationship_c1' => array(
+        0 => 'subject_id',
+        1 => 'object_id',
+        2 => 'type_id',
+      ),
+    ),
+    'indexes' => array(
+      'quantification_relationship_idx1' => array(
+        0 => 'subject_id',
+      ),
+      'quantification_relationship_idx2' => array(
+        0 => 'type_id',
+      ),
+      'quantification_relationship_idx3' => array(
+        0 => 'object_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'quantification_relationship_id',
+    ),
+    'foreign keys' => array(
+      'quantification' => array(
+        'table' => 'quantification',
+        'columns' => array(
+          'subject_id' => 'quantification_id',
+          'object_id' => 'quantification_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_stock()
+ *
+ * Purpose: To describe the structure of 'stock' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'stock' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_stock() {
+  $description = array(
+    'description' => '',
+    'table' => 'stock',
+    'fields' => array(
+      'stock_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'organism_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'name' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => FALSE,
+      ),
+      'uniquename' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => TRUE,
+      ),
+      'description' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'is_obsolete' => array(
+        'size' => 'normal',
+        'type' => 'boolean',
+        'not null' => TRUE,
+        'default' => FALSE,
+      ),
+    ),
+    'unique keys' => array(
+      'stock_c1' => array(
+        0 => 'organism_id',
+        1 => 'uniquename',
+        2 => 'type_id',
+      ),
+    ),
+    'indexes' => array(
+      'stock_idx1' => array(
+        0 => 'dbxref_id',
+      ),
+      'stock_idx2' => array(
+        0 => 'organism_id',
+      ),
+      'stock_idx3' => array(
+        0 => 'type_id',
+      ),
+      'stock_idx4' => array(
+        0 => 'uniquename',
+      ),
+      'stock_name_ind1' => array(
+        0 => 'name',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'stock_id',
+    ),
+    'foreign keys' => array(
+      'dbxref' => array(
+        'table' => 'dbxref',
+        'columns' => array(
+          'dbxref_id' => 'dbxref_id',
+        ),
+      ),
+      'organism' => array(
+        'table' => 'organism',
+        'columns' => array(
+          'organism_id' => 'organism_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'nd_experiment_stock',
+      1 => 'project_stock',
+      2 => 'stockcollection_stock',
+      3 => 'stock_cvterm',
+      4 => 'stock_dbxref',
+      5 => 'stock_feature',
+      6 => 'stock_featuremap',
+      7 => 'stock_genotype',
+      8 => 'stock_library',
+      9 => 'stockprop',
+      10 => 'stock_pub',
+      11 => 'stock_relationship',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_stockcollection()
+ *
+ * Purpose: To describe the structure of 'stockcollection' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'stockcollection' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_stockcollection() {
+  $description = array(
+    'description' => '',
+    'table' => 'stockcollection',
+    'fields' => array(
+      'stockcollection_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'contact_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'name' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => FALSE,
+      ),
+      'uniquename' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'stockcollection_c1' => array(
+        0 => 'uniquename',
+        1 => 'type_id',
+      ),
+    ),
+    'indexes' => array(
+      'stockcollection_idx1' => array(
+        0 => 'contact_id',
+      ),
+      'stockcollection_idx2' => array(
+        0 => 'type_id',
+      ),
+      'stockcollection_idx3' => array(
+        0 => 'uniquename',
+      ),
+      'stockcollection_name_ind1' => array(
+        0 => 'name',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'stockcollection_id',
+    ),
+    'foreign keys' => array(
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+      'contact' => array(
+        'table' => 'contact',
+        'columns' => array(
+          'contact_id' => 'contact_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'stockcollection_db',
+      1 => 'stockcollectionprop',
+      2 => 'stockcollection_stock',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_stockcollection_db()
+ *
+ * Purpose: To describe the structure of 'stockcollection_db' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'stockcollection_db' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_stockcollection_db() {
+  $description = array(
+    'description' => '',
+    'table' => 'stockcollection_db',
+    'fields' => array(
+      'stockcollection_db_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'stockcollection_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'db_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'stockcollection_db_c1' => array(
+        0 => 'stockcollection_id',
+        1 => 'db_id',
+      ),
+    ),
+    'indexes' => array(
+      'stockcollection_db_idx1' => array(
+        0 => 'stockcollection_id',
+      ),
+      'stockcollection_db_idx2' => array(
+        0 => 'db_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'stockcollection_db_id',
+    ),
+    'foreign keys' => array(
+      'db' => array(
+        'table' => 'db',
+        'columns' => array(
+          'db_id' => 'db_id',
+        ),
+      ),
+      'stockcollection' => array(
+        'table' => 'stockcollection',
+        'columns' => array(
+          'stockcollection_id' => 'stockcollection_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_stockcollectionprop()
+ *
+ * Purpose: To describe the structure of 'stockcollectionprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'stockcollectionprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_stockcollectionprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'stockcollectionprop',
+    'fields' => array(
+      'stockcollectionprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'stockcollection_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'stockcollectionprop_c1' => array(
+        0 => 'stockcollection_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'stockcollectionprop_idx1' => array(
+        0 => 'stockcollection_id',
+      ),
+      'stockcollectionprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'stockcollectionprop_id',
+    ),
+    'foreign keys' => array(
+      'stockcollection' => array(
+        'table' => 'stockcollection',
+        'columns' => array(
+          'stockcollection_id' => 'stockcollection_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_stockcollection_stock()
+ *
+ * Purpose: To describe the structure of 'stockcollection_stock' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'stockcollection_stock' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_stockcollection_stock() {
+  $description = array(
+    'description' => '',
+    'table' => 'stockcollection_stock',
+    'fields' => array(
+      'stockcollection_stock_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'stockcollection_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'stock_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'stockcollection_stock_c1' => array(
+        0 => 'stockcollection_id',
+        1 => 'stock_id',
+      ),
+    ),
+    'indexes' => array(
+      'stockcollection_stock_idx1' => array(
+        0 => 'stockcollection_id',
+      ),
+      'stockcollection_stock_idx2' => array(
+        0 => 'stock_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'stockcollection_stock_id',
+    ),
+    'foreign keys' => array(
+      'stockcollection' => array(
+        'table' => 'stockcollection',
+        'columns' => array(
+          'stockcollection_id' => 'stockcollection_id',
+        ),
+      ),
+      'stock' => array(
+        'table' => 'stock',
+        'columns' => array(
+          'stock_id' => 'stock_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_stock_cvterm()
+ *
+ * Purpose: To describe the structure of 'stock_cvterm' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'stock_cvterm' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_stock_cvterm() {
+  $description = array(
+    'description' => '',
+    'table' => 'stock_cvterm',
+    'fields' => array(
+      'stock_cvterm_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'stock_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'cvterm_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'is_not' => array(
+        'size' => 'normal',
+        'type' => 'boolean',
+        'not null' => TRUE,
+        'default' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'stock_cvterm_c1' => array(
+        0 => 'stock_id',
+        1 => 'cvterm_id',
+        2 => 'pub_id',
+        3 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'stock_cvterm_idx1' => array(
+        0 => 'stock_id',
+      ),
+      'stock_cvterm_idx2' => array(
+        0 => 'cvterm_id',
+      ),
+      'stock_cvterm_idx3' => array(
+        0 => 'pub_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'stock_cvterm_id',
+    ),
+    'foreign keys' => array(
+      'stock' => array(
+        'table' => 'stock',
+        'columns' => array(
+          'stock_id' => 'stock_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'cvterm_id' => 'cvterm_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'stock_cvtermprop',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_stock_cvtermprop()
+ *
+ * Purpose: To describe the structure of 'stock_cvtermprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'stock_cvtermprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_stock_cvtermprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'stock_cvtermprop',
+    'fields' => array(
+      'stock_cvtermprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'stock_cvterm_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'stock_cvtermprop_c1' => array(
+        0 => 'stock_cvterm_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'stock_cvtermprop_idx1' => array(
+        0 => 'stock_cvterm_id',
+      ),
+      'stock_cvtermprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'stock_cvtermprop_id',
+    ),
+    'foreign keys' => array(
+      'stock_cvterm' => array(
+        'table' => 'stock_cvterm',
+        'columns' => array(
+          'stock_cvterm_id' => 'stock_cvterm_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_stock_dbxref()
+ *
+ * Purpose: To describe the structure of 'stock_dbxref' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'stock_dbxref' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_stock_dbxref() {
+  $description = array(
+    'description' => '',
+    'table' => 'stock_dbxref',
+    'fields' => array(
+      'stock_dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'stock_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'is_current' => array(
+        'size' => 'normal',
+        'type' => 'boolean',
+        'not null' => TRUE,
+        'default' => 'ru',
+      ),
+    ),
+    'unique keys' => array(
+      'stock_dbxref_c1' => array(
+        0 => 'stock_id',
+        1 => 'dbxref_id',
+      ),
+    ),
+    'indexes' => array(
+      'stock_dbxref_idx1' => array(
+        0 => 'stock_id',
+      ),
+      'stock_dbxref_idx2' => array(
+        0 => 'dbxref_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'stock_dbxref_id',
+    ),
+    'foreign keys' => array(
+      'stock' => array(
+        'table' => 'stock',
+        'columns' => array(
+          'stock_id' => 'stock_id',
+        ),
+      ),
+      'dbxref' => array(
+        'table' => 'dbxref',
+        'columns' => array(
+          'dbxref_id' => 'dbxref_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'stock_dbxrefprop',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_stock_dbxrefprop()
+ *
+ * Purpose: To describe the structure of 'stock_dbxrefprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'stock_dbxrefprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_stock_dbxrefprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'stock_dbxrefprop',
+    'fields' => array(
+      'stock_dbxrefprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'stock_dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'stock_dbxrefprop_c1' => array(
+        0 => 'stock_dbxref_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'stock_dbxrefprop_idx1' => array(
+        0 => 'stock_dbxref_id',
+      ),
+      'stock_dbxrefprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'stock_dbxrefprop_id',
+    ),
+    'foreign keys' => array(
+      'stock_dbxref' => array(
+        'table' => 'stock_dbxref',
+        'columns' => array(
+          'stock_dbxref_id' => 'stock_dbxref_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_stock_feature()
+ *
+ * Purpose: To describe the structure of 'stock_feature' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'stock_feature' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_stock_feature() {
+  $description = array(
+    'description' => '',
+    'table' => 'stock_feature',
+    'fields' => array(
+      'stock_feature_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'feature_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'stock_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'stock_feature_c1' => array(
+        0 => 'feature_id',
+        1 => 'stock_id',
+        2 => 'type_id',
+        3 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'stock_feature_idx1' => array(
+        0 => 'stock_feature_id',
+      ),
+      'stock_feature_idx2' => array(
+        0 => 'feature_id',
+      ),
+      'stock_feature_idx3' => array(
+        0 => 'stock_id',
+      ),
+      'stock_feature_idx4' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'stock_feature_id',
+    ),
+    'foreign keys' => array(
+      'feature' => array(
+        'table' => 'feature',
+        'columns' => array(
+          'feature_id' => 'feature_id',
+        ),
+      ),
+      'stock' => array(
+        'table' => 'stock',
+        'columns' => array(
+          'stock_id' => 'stock_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_stock_featuremap()
+ *
+ * Purpose: To describe the structure of 'stock_featuremap' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'stock_featuremap' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_stock_featuremap() {
+  $description = array(
+    'description' => '',
+    'table' => 'stock_featuremap',
+    'fields' => array(
+      'stock_featuremap_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'featuremap_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'stock_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+    ),
+    'unique keys' => array(
+      'stock_featuremap_c1' => array(
+        0 => 'featuremap_id',
+        1 => 'stock_id',
+        2 => 'type_id',
+      ),
+    ),
+    'indexes' => array(
+      'stock_featuremap_idx1' => array(
+        0 => 'featuremap_id',
+      ),
+      'stock_featuremap_idx2' => array(
+        0 => 'stock_id',
+      ),
+      'stock_featuremap_idx3' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'stock_featuremap_id',
+    ),
+    'foreign keys' => array(
+      'featuremap' => array(
+        'table' => 'featuremap',
+        'columns' => array(
+          'featuremap_id' => 'featuremap_id',
+        ),
+      ),
+      'stock' => array(
+        'table' => 'stock',
+        'columns' => array(
+          'stock_id' => 'stock_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_stock_genotype()
+ *
+ * Purpose: To describe the structure of 'stock_genotype' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'stock_genotype' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_stock_genotype() {
+  $description = array(
+    'description' => '',
+    'table' => 'stock_genotype',
+    'fields' => array(
+      'stock_genotype_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'stock_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'genotype_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'stock_genotype_c1' => array(
+        0 => 'stock_id',
+        1 => 'genotype_id',
+      ),
+    ),
+    'indexes' => array(
+      'stock_genotype_idx1' => array(
+        0 => 'stock_id',
+      ),
+      'stock_genotype_idx2' => array(
+        0 => 'genotype_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'stock_genotype_id',
+    ),
+    'foreign keys' => array(
+      'stock' => array(
+        'table' => 'stock',
+        'columns' => array(
+          'stock_id' => 'stock_id',
+        ),
+      ),
+      'genotype' => array(
+        'table' => 'genotype',
+        'columns' => array(
+          'genotype_id' => 'genotype_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_stock_library()
+ *
+ * Purpose: To describe the structure of 'stock_library' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'stock_library' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_stock_library() {
+  $description = array(
+    'description' => '',
+    'table' => 'stock_library',
+    'fields' => array(
+      'stock_library_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'library_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'stock_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'stock_library_c1' => array(
+        0 => 'library_id',
+        1 => 'stock_id',
+      ),
+    ),
+    'indexes' => array(
+      'stock_library_idx1' => array(
+        0 => 'library_id',
+      ),
+      'stock_library_idx2' => array(
+        0 => 'stock_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'stock_library_id',
+    ),
+    'foreign keys' => array(
+      'library' => array(
+        'table' => 'library',
+        'columns' => array(
+          'library_id' => 'library_id',
+        ),
+      ),
+      'stock' => array(
+        'table' => 'stock',
+        'columns' => array(
+          'stock_id' => 'stock_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_stockprop()
+ *
+ * Purpose: To describe the structure of 'stockprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'stockprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_stockprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'stockprop',
+    'fields' => array(
+      'stockprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'stock_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'stockprop_c1' => array(
+        0 => 'stock_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'stockprop_idx1' => array(
+        0 => 'stock_id',
+      ),
+      'stockprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'stockprop_id',
+    ),
+    'foreign keys' => array(
+      'stock' => array(
+        'table' => 'stock',
+        'columns' => array(
+          'stock_id' => 'stock_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'stockprop_pub',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_stockprop_pub()
+ *
+ * Purpose: To describe the structure of 'stockprop_pub' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'stockprop_pub' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_stockprop_pub() {
+  $description = array(
+    'description' => '',
+    'table' => 'stockprop_pub',
+    'fields' => array(
+      'stockprop_pub_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'stockprop_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'stockprop_pub_c1' => array(
+        0 => 'stockprop_id',
+        1 => 'pub_id',
+      ),
+    ),
+    'indexes' => array(
+      'stockprop_pub_idx1' => array(
+        0 => 'stockprop_id',
+      ),
+      'stockprop_pub_idx2' => array(
+        0 => 'pub_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'stockprop_pub_id',
+    ),
+    'foreign keys' => array(
+      'stockprop' => array(
+        'table' => 'stockprop',
+        'columns' => array(
+          'stockprop_id' => 'stockprop_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_stock_pub()
+ *
+ * Purpose: To describe the structure of 'stock_pub' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'stock_pub' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_stock_pub() {
+  $description = array(
+    'description' => '',
+    'table' => 'stock_pub',
+    'fields' => array(
+      'stock_pub_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'stock_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'stock_pub_c1' => array(
+        0 => 'stock_id',
+        1 => 'pub_id',
+      ),
+    ),
+    'indexes' => array(
+      'stock_pub_idx1' => array(
+        0 => 'stock_id',
+      ),
+      'stock_pub_idx2' => array(
+        0 => 'pub_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'stock_pub_id',
+    ),
+    'foreign keys' => array(
+      'stock' => array(
+        'table' => 'stock',
+        'columns' => array(
+          'stock_id' => 'stock_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_stock_relationship()
+ *
+ * Purpose: To describe the structure of 'stock_relationship' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'stock_relationship' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_stock_relationship() {
+  $description = array(
+    'description' => '',
+    'table' => 'stock_relationship',
+    'fields' => array(
+      'stock_relationship_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'subject_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'object_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'stock_relationship_c1' => array(
+        0 => 'subject_id',
+        1 => 'object_id',
+        2 => 'type_id',
+        3 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'stock_relationship_idx1' => array(
+        0 => 'subject_id',
+      ),
+      'stock_relationship_idx2' => array(
+        0 => 'object_id',
+      ),
+      'stock_relationship_idx3' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'stock_relationship_id',
+    ),
+    'foreign keys' => array(
+      'stock' => array(
+        'table' => 'stock',
+        'columns' => array(
+          'subject_id' => 'stock_id',
+          'object_id' => 'stock_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'stock_relationship_cvterm',
+      1 => 'stock_relationship_pub',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_stock_relationship_cvterm()
+ *
+ * Purpose: To describe the structure of 'stock_relationship_cvterm' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'stock_relationship_cvterm' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_stock_relationship_cvterm() {
+  $description = array(
+    'description' => '',
+    'table' => 'stock_relationship_cvterm',
+    'fields' => array(
+      'stock_relationship_cvterm_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'stock_relationship_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'cvterm_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+    ),
+    'primary key' => array(
+      0 => 'stock_relationship_cvterm_id',
+    ),
+    'foreign keys' => array(
+      'stock_relationship' => array(
+        'table' => 'stock_relationship',
+        'columns' => array(
+          'stock_relationship_id' => 'stock_relationship_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'cvterm_id' => 'cvterm_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_stock_relationship_pub()
+ *
+ * Purpose: To describe the structure of 'stock_relationship_pub' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'stock_relationship_pub' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_stock_relationship_pub() {
+  $description = array(
+    'description' => '',
+    'table' => 'stock_relationship_pub',
+    'fields' => array(
+      'stock_relationship_pub_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'stock_relationship_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'stock_relationship_pub_c1' => array(
+        0 => 'stock_relationship_id',
+        1 => 'pub_id',
+      ),
+    ),
+    'indexes' => array(
+      'stock_relationship_pub_idx1' => array(
+        0 => 'stock_relationship_id',
+      ),
+      'stock_relationship_pub_idx2' => array(
+        0 => 'pub_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'stock_relationship_pub_id',
+    ),
+    'foreign keys' => array(
+      'stock_relationship' => array(
+        'table' => 'stock_relationship',
+        'columns' => array(
+          'stock_relationship_id' => 'stock_relationship_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_study()
+ *
+ * Purpose: To describe the structure of 'study' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'study' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_study() {
+  $description = array(
+    'description' => '',
+    'table' => 'study',
+    'fields' => array(
+      'study_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'contact_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'pub_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'dbxref_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'name' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => TRUE,
+      ),
+      'description' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+    ),
+    'unique keys' => array(
+      'study_c1' => array(
+        0 => 'name',
+      ),
+    ),
+    'indexes' => array(
+      'study_idx1' => array(
+        0 => 'contact_id',
+      ),
+      'study_idx2' => array(
+        0 => 'pub_id',
+      ),
+      'study_idx3' => array(
+        0 => 'dbxref_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'study_id',
+    ),
+    'foreign keys' => array(
+      'contact' => array(
+        'table' => 'contact',
+        'columns' => array(
+          'contact_id' => 'contact_id',
+        ),
+      ),
+      'pub' => array(
+        'table' => 'pub',
+        'columns' => array(
+          'pub_id' => 'pub_id',
+        ),
+      ),
+      'dbxref' => array(
+        'table' => 'dbxref',
+        'columns' => array(
+          'dbxref_id' => 'dbxref_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'study_assay',
+      1 => 'studydesign',
+      2 => 'studyprop',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_study_assay()
+ *
+ * Purpose: To describe the structure of 'study_assay' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'study_assay' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_study_assay() {
+  $description = array(
+    'description' => '',
+    'table' => 'study_assay',
+    'fields' => array(
+      'study_assay_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'study_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'assay_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'study_assay_c1' => array(
+        0 => 'study_id',
+        1 => 'assay_id',
+      ),
+    ),
+    'indexes' => array(
+      'study_assay_idx1' => array(
+        0 => 'study_id',
+      ),
+      'study_assay_idx2' => array(
+        0 => 'assay_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'study_assay_id',
+    ),
+    'foreign keys' => array(
+      'study' => array(
+        'table' => 'study',
+        'columns' => array(
+          'study_id' => 'study_id',
+        ),
+      ),
+      'assay' => array(
+        'table' => 'assay',
+        'columns' => array(
+          'assay_id' => 'assay_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_studydesign()
+ *
+ * Purpose: To describe the structure of 'studydesign' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'studydesign' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_studydesign() {
+  $description = array(
+    'description' => '',
+    'table' => 'studydesign',
+    'fields' => array(
+      'studydesign_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'study_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'description' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+    ),
+    'indexes' => array(
+      'studydesign_idx1' => array(
+        0 => 'study_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'studydesign_id',
+    ),
+    'foreign keys' => array(
+      'study' => array(
+        'table' => 'study',
+        'columns' => array(
+          'study_id' => 'study_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'studydesignprop',
+      1 => 'studyfactor',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_studydesignprop()
+ *
+ * Purpose: To describe the structure of 'studydesignprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'studydesignprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_studydesignprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'studydesignprop',
+    'fields' => array(
+      'studydesignprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'studydesign_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'unique keys' => array(
+      'studydesignprop_c1' => array(
+        0 => 'studydesign_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'indexes' => array(
+      'studydesignprop_idx1' => array(
+        0 => 'studydesign_id',
+      ),
+      'studydesignprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'studydesignprop_id',
+    ),
+    'foreign keys' => array(
+      'studydesign' => array(
+        'table' => 'studydesign',
+        'columns' => array(
+          'studydesign_id' => 'studydesign_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_studyfactor()
+ *
+ * Purpose: To describe the structure of 'studyfactor' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'studyfactor' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_studyfactor() {
+  $description = array(
+    'description' => '',
+    'table' => 'studyfactor',
+    'fields' => array(
+      'studyfactor_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'studydesign_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'name' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => TRUE,
+      ),
+      'description' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+    ),
+    'indexes' => array(
+      'studyfactor_idx1' => array(
+        0 => 'studydesign_id',
+      ),
+      'studyfactor_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'studyfactor_id',
+    ),
+    'foreign keys' => array(
+      'studydesign' => array(
+        'table' => 'studydesign',
+        'columns' => array(
+          'studydesign_id' => 'studydesign_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'studyfactorvalue',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_studyfactorvalue()
+ *
+ * Purpose: To describe the structure of 'studyfactorvalue' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'studyfactorvalue' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_studyfactorvalue() {
+  $description = array(
+    'description' => '',
+    'table' => 'studyfactorvalue',
+    'fields' => array(
+      'studyfactorvalue_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'studyfactor_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'assay_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'factorvalue' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'name' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'indexes' => array(
+      'studyfactorvalue_idx1' => array(
+        0 => 'studyfactor_id',
+      ),
+      'studyfactorvalue_idx2' => array(
+        0 => 'assay_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'studyfactorvalue_id',
+    ),
+    'foreign keys' => array(
+      'studyfactor' => array(
+        'table' => 'studyfactor',
+        'columns' => array(
+          'studyfactor_id' => 'studyfactor_id',
+        ),
+      ),
+      'assay' => array(
+        'table' => 'assay',
+        'columns' => array(
+          'assay_id' => 'assay_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_studyprop()
+ *
+ * Purpose: To describe the structure of 'studyprop' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'studyprop' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_studyprop() {
+  $description = array(
+    'description' => '',
+    'table' => 'studyprop',
+    'fields' => array(
+      'studyprop_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'study_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'value' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+    ),
+    'indexes' => array(
+      'studyprop_idx1' => array(
+        0 => 'study_id',
+      ),
+      'studyprop_idx2' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'studyprop_id',
+    ),
+    'unique keys' => array(
+      'study_id_type_id_rank' => array(
+        0 => 'study_id',
+        1 => 'type_id',
+        2 => 'rank',
+      ),
+    ),
+    'foreign keys' => array(
+      'study' => array(
+        'table' => 'study',
+        'columns' => array(
+          'study_id' => 'study_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'studyprop_feature',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_studyprop_feature()
+ *
+ * Purpose: To describe the structure of 'studyprop_feature' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'studyprop_feature' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_studyprop_feature() {
+  $description = array(
+    'description' => '',
+    'table' => 'studyprop_feature',
+    'fields' => array(
+      'studyprop_feature_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'studyprop_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'feature_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+    ),
+    'indexes' => array(
+      'studyprop_feature_idx1' => array(
+        0 => 'studyprop_id',
+      ),
+      'studyprop_feature_idx2' => array(
+        0 => 'feature_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'studyprop_feature_id',
+    ),
+    'unique keys' => array(
+      'studyprop_id_feature_id' => array(
+        0 => 'studyprop_id',
+        1 => 'feature_id',
+      ),
+    ),
+    'foreign keys' => array(
+      'studyprop' => array(
+        'table' => 'studyprop',
+        'columns' => array(
+          'studyprop_id' => 'studyprop_id',
+        ),
+      ),
+      'feature' => array(
+        'table' => 'feature',
+        'columns' => array(
+          'feature_id' => 'feature_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_synonym()
+ *
+ * Purpose: To describe the structure of 'synonym' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'synonym' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_synonym() {
+  $description = array(
+    'description' => '',
+    'table' => 'synonym',
+    'fields' => array(
+      'synonym_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'name' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'synonym_sgml' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'synonym_c1' => array(
+        0 => 'name',
+        1 => 'type_id',
+      ),
+    ),
+    'indexes' => array(
+      'synonym_idx1' => array(
+        0 => 'type_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'synonym_id',
+    ),
+    'foreign keys' => array(
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'cell_line_synonym',
+      1 => 'feature_synonym',
+      2 => 'library_synonym',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_tableinfo()
+ *
+ * Purpose: To describe the structure of 'tableinfo' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'tableinfo' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_tableinfo() {
+  $description = array(
+    'description' => '',
+    'table' => 'tableinfo',
+    'fields' => array(
+      'tableinfo_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'name' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '30',
+        'not null' => TRUE,
+      ),
+      'primary_key_column' => array(
+        'size' => 'normal',
+        'type' => 'varchar',
+        'length' => '30',
+        'not null' => FALSE,
+      ),
+      'is_view' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'view_on_table_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'superclass_table_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'is_updateable' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 1,
+      ),
+      'modification_date' => array(
+        'size' => 'normal',
+        'type' => 'date',
+        'not null' => TRUE,
+        'default' => 'now()',
+      ),
+    ),
+    'unique keys' => array(
+      'tableinfo_c1' => array(
+        0 => 'name',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'tableinfo_id',
+    ),
+    'foreign keys' => array(
+    ),
+    'referring_tables' => array(
+      0 => 'control',
+      1 => 'magedocumentation',
+    ),
+  );
+  return $description;
+}
+/**
+ * Implements hook_chado_schema_v1_3_treatment()
+ *
+ * Purpose: To describe the structure of 'treatment' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ * @see chado_generate_var()
+ * @see chado_expan_var()
+ *
+ * @return
+ *    An array describing the 'treatment' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_schema_v1_3_treatment() {
+  $description = array(
+    'description' => '',
+    'table' => 'treatment',
+    'fields' => array(
+      'treatment_id' => array(
+        'size' => 'big',
+        'type' => 'serial',
+        'not null' => TRUE,
+      ),
+      'rank' => array(
+        'size' => 'normal',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'biomaterial_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'type_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => TRUE,
+      ),
+      'protocol_id' => array(
+        'size' => 'big',
+        'type' => 'int',
+        'not null' => FALSE,
+      ),
+      'name' => array(
+        'size' => 'normal',
+        'type' => 'text',
+        'not null' => FALSE,
+      ),
+    ),
+    'indexes' => array(
+      'treatment_idx1' => array(
+        0 => 'biomaterial_id',
+      ),
+      'treatment_idx2' => array(
+        0 => 'type_id',
+      ),
+      'treatment_idx3' => array(
+        0 => 'protocol_id',
+      ),
+    ),
+    'primary key' => array(
+      0 => 'treatment_id',
+    ),
+    'foreign keys' => array(
+      'biomaterial' => array(
+        'table' => 'biomaterial',
+        'columns' => array(
+          'biomaterial_id' => 'biomaterial_id',
+        ),
+      ),
+      'cvterm' => array(
+        'table' => 'cvterm',
+        'columns' => array(
+          'type_id' => 'cvterm_id',
+        ),
+      ),
+      'protocol' => array(
+        'table' => 'protocol',
+        'columns' => array(
+          'protocol_id' => 'protocol_id',
+        ),
+      ),
+    ),
+    'referring_tables' => array(
+      0 => 'biomaterial_treatment',
+    ),
+  );
+  return $description;
+}
+/**
+ * Lists the table names in the v1.3 chado schema
+ *
+ * @return
+ *    An array containing all of the table names
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ *
+ */
+function tripal_core_chado_get_v1_3_tables() {
+  $tables = array(
+  'acquisition',
+    'acquisitionprop',
+    'acquisition_relationship',
+    'analysis',
+    'analysis_cvterm',
+    'analysis_dbxref',
+    'analysisfeature',
+    'analysisfeatureprop',
+    'analysis_organism',
+    'analysisprop',
+    'analysis_pub',
+    'analysis_relationship',
+    'arraydesign',
+    'arraydesignprop',
+    'assay',
+    'assay_biomaterial',
+    'assay_project',
+    'assayprop',
+    'biomaterial',
+    'biomaterial_dbxref',
+    'biomaterialprop',
+    'biomaterial_relationship',
+    'biomaterial_treatment',
+    'cell_line',
+    'cell_line_cvterm',
+    'cell_line_cvtermprop',
+    'cell_line_dbxref',
+    'cell_line_feature',
+    'cell_line_library',
+    'cell_lineprop',
+    'cell_lineprop_pub',
+    'cell_line_pub',
+    'cell_line_relationship',
+    'cell_line_synonym',
+    'chadoprop',
+    'channel',
+    'contact',
+    'contactprop',
+    'contact_relationship',
+    'control',
+    'cv',
+    'cvprop',
+    'cv_root_mview',
+    'cvterm',
+    'cvterm_dbxref',
+    'cvtermpath',
+    'cvtermprop',
+    'cvterm_relationship',
+    'cvtermsynonym',
+    'db',
+    'dbprop',
+    'dbxref',
+    'dbxrefprop',
+    'eimage',
+    'element',
+    'element_relationship',
+    'elementresult',
+    'elementresult_relationship',
+    'environment',
+    'environment_cvterm',
+    'expression',
+    'expression_cvterm',
+    'expression_cvtermprop',
+    'expression_image',
+    'expressionprop',
+    'expression_pub',
+    'feature',
+    'feature_contact',
+    'feature_cvterm',
+    'feature_cvterm_dbxref',
+    'feature_cvtermprop',
+    'feature_cvterm_pub',
+    'feature_dbxref',
+    'feature_expression',
+    'feature_expressionprop',
+    'feature_genotype',
+    'featureloc',
+    'featureloc_pub',
+    'featuremap',
+    'featuremap_contact',
+    'featuremap_dbxref',
+    'featuremap_organism',
+    'featuremapprop',
+    'featuremap_pub',
+    'feature_phenotype',
+    'featurepos',
+    'featureposprop',
+    'featureprop',
+    'featureprop_pub',
+    'feature_pub',
+    'feature_pubprop',
+    'featurerange',
+    'feature_relationship',
+    'feature_relationshipprop',
+    'feature_relationshipprop_pub',
+    'feature_relationship_pub',
+    'feature_synonym',
+    'genotype',
+    'genotypeprop',
+    'library',
+    'library_contact',
+    'library_cvterm',
+    'library_dbxref',
+    'library_expression',
+    'library_expressionprop',
+    'library_feature',
+    'library_featureprop',
+    'libraryprop',
+    'libraryprop_pub',
+    'library_pub',
+    'library_relationship',
+    'library_relationship_pub',
+    'library_synonym',
+    'magedocumentation',
+    'mageml',
+    'materialized_view',
+    'nd_experiment',
+    'nd_experiment_analysis',
+    'nd_experiment_contact',
+    'nd_experiment_dbxref',
+    'nd_experiment_genotype',
+    'nd_experiment_phenotype',
+    'nd_experiment_project',
+    'nd_experimentprop',
+    'nd_experiment_protocol',
+    'nd_experiment_pub',
+    'nd_experiment_stock',
+    'nd_experiment_stock_dbxref',
+    'nd_experiment_stockprop',
+    'nd_geolocation',
+    'nd_geolocationprop',
+    'nd_protocol',
+    'nd_protocolprop',
+    'nd_protocol_reagent',
+    'nd_reagent',
+    'nd_reagentprop',
+    'nd_reagent_relationship',
+    'organism',
+    'organism_cvterm',
+    'organism_cvtermprop',
+    'organism_dbxref',
+    'organism_feature_count',
+    'organismprop',
+    'organismprop_pub',
+    'organism_pub',
+    'organism_relationship',
+    'phendesc',
+    'phenotype',
+    'phenotype_comparison',
+    'phenotype_comparison_cvterm',
+    'phenotype_cvterm',
+    'phenotypeprop',
+    'phenstatement',
+    'phylonode',
+    'phylonode_dbxref',
+    'phylonode_organism',
+    'phylonodeprop',
+    'phylonode_pub',
+    'phylonode_relationship',
+    'phylotree',
+    'phylotreeprop',
+    'phylotree_pub',
+    'project',
+    'project_analysis',
+    'project_contact',
+    'project_dbxref',
+    'project_feature',
+    'projectprop',
+    'project_pub',
+    'project_relationship',
+    'project_stock',
+    'protocol',
+    'protocolparam',
+    'pub',
+    'pubauthor',
+    'pubauthor_contact',
+    'pub_dbxref',
+    'pubprop',
+    'pub_relationship',
+    'quantification',
+    'quantificationprop',
+    'quantification_relationship',
+    'stock',
+    'stockcollection',
+    'stockcollection_db',
+    'stockcollectionprop',
+    'stockcollection_stock',
+    'stock_cvterm',
+    'stock_cvtermprop',
+    'stock_dbxref',
+    'stock_dbxrefprop',
+    'stock_feature',
+    'stock_featuremap',
+    'stock_genotype',
+    'stock_library',
+    'stockprop',
+    'stockprop_pub',
+    'stock_pub',
+    'stock_relationship',
+    'stock_relationship_cvterm',
+    'stock_relationship_pub',
+    'study',
+    'study_assay',
+    'studydesign',
+    'studydesignprop',
+    'studyfactor',
+    'studyfactorvalue',
+    'studyprop',
+    'studyprop_feature',
+    'synonym',
+    'tableinfo',
+    'treatment',
+  );
+  return $tables;
+}

+ 21 - 11
tripal_core/api/tripal_core.tripal.api.inc

@@ -97,6 +97,12 @@ function tripal_report_error($type, $severity, $message, $variables = array(), $
       break;
   }
 
+  // If we are not set to return debugging information and the severity string is debug
+  // then don't report the error.
+  if (($severity == TRIPAL_DEBUG) AND (getenv('TRIPAL_DEBUG') != 1)) {
+    return FALSE;
+  }
+
   // get the backtrace and include in the error message, but only if the
   // TRIPAL_DEBUG environment variable is set.
   if (getenv('TRIPAL_DEBUG') == 1) {
@@ -109,7 +115,7 @@ function tripal_report_error($type, $severity, $message, $variables = array(), $
     }
   }
 
-  // Send to watchdog
+  // Send to watchdog.
   try {
     watchdog($type, $message, $variables, $severity);
   }
@@ -126,19 +132,22 @@ function tripal_report_error($type, $severity, $message, $variables = array(), $
     $print_message = $message;
   }
 
-  // If print option supplied then print directly to the screen
+  // If print option supplied then print directly to the screen.
   if (isset($options['print'])) {
     print $severity_string . ' (' . strtoupper($type) . '): ' . $print_message . "\n";
   }
 
-  // Print to the Tripal error log
-  tripal_log('[' . strtoupper($type) . '] ' . $print_message . "\n", $severity_string);
-
+  // Print to the Tripal error log but only if the severity is not info.
+  if (($severity != TRIPAL_INFO)) {
+    tripal_log('[' . strtoupper($type) . '] ' . $print_message . "\n", $severity_string);
+  }
 }
 
 /**
- * Display messages to tripal administrators. This can be used instead of
- * drupal_set_message when you want to target tripal administrators.
+ * Display messages to tripal administrators.
+ *
+ * This can be used instead of drupal_set_message when you want to target
+ * tripal administrators.
  *
  * @param $message
  *   The message to be displayed to the tripal administrators
@@ -219,10 +228,11 @@ function tripal_set_message($message, $importance = TRIPAL_INFO, $options = arra
  *   are supported.
  * @param $options
  *   An array of options where the following keys are supported:
- *     - first_progress_bar: this sohuld be used for the first log call for a progress bar
- *     - is_progress_bar: this option should be used for all but the first print of a
- *         progress bar to allow it all to be printed on the same line without intervening
- *         date prefixes
+ *     - first_progress_bar: this sohuld be used for the first log call for a
+ *         progress bar.
+ *     - is_progress_bar: this option should be used for all but the first
+ *         print of a progress bar to allow it all to be printed on the same
+ *         line without intervening date prefixes.
  * @return
  *   The number of bytes that were written to the file, or FALSE on failure
  */

Разлика између датотеке није приказан због своје велике величине
+ 8835 - 0
tripal_core/chado_schema/default_schema-1.2-1.3-diff.sql


Разлика између датотеке није приказан због своје велике величине
+ 2751 - 0
tripal_core/chado_schema/default_schema-1.3.sql


+ 3 - 207
tripal_core/chado_schema/initialize-1.2.sql

@@ -1,218 +1,15 @@
 /* For load_gff3.pl */
-insert into organism (abbreviation, genus, species, common_name)
-       values ('H.sapiens', 'Homo','sapiens','human');
-insert into organism (abbreviation, genus, species, common_name)
-       values ('D.melanogaster', 'Drosophila','melanogaster','fruitfly');
-insert into organism (abbreviation, genus, species, common_name)
-       values ('M.musculus', 'Mus','musculus','mouse');
-insert into organism (abbreviation, genus, species, common_name)
-       values ('A.gambiae', 'Anopheles','gambiae','mosquito');
-insert into organism (abbreviation, genus, species, common_name)
-       values ('R.norvegicus', 'Rattus','norvegicus','rat');
-insert into organism (abbreviation, genus, species, common_name)
-       values ('A.thaliana', 'Arabidopsis','thaliana','mouse-ear cress');
-insert into organism (abbreviation, genus, species, common_name)
-       values ('C.elegans', 'Caenorhabditis','elegans','worm');
-insert into organism (abbreviation, genus, species, common_name)
-       values ('D.rerio', 'Danio','rerio','zebrafish');
-insert into organism (abbreviation, genus, species, common_name)
-       values ('O.sativa', 'Oryza','sativa','rice');
-insert into organism (abbreviation, genus, species, common_name)
-       values ('S.cerevisiae', 'Saccharomyces','cerevisiae','yeast');
-insert into organism (abbreviation, genus, species, common_name)
-       values ('X.laevis', 'Xenopus','laevis','frog');
-insert into organism (abbreviation, genus, species,common_name) 
-       values ('D.discoideum','Dictyostelium','discoideum','dicty');
-insert into contact (name) values ('Affymetrix');
+
 insert into contact (name,description) values ('null','null');
 insert into cv (name) values ('null');
 insert into cv (name,definition) values ('local','Locally created terms');
 insert into cv (name,definition) values ('Statistical Terms','Locally created terms for statistics');
-insert into db (name, description) values ('null','a fake database for local items');
+insert into db (name, description) values ('null', 'Use when a database is not available.');
 
 insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'local:null');
 insert into cvterm (name,cv_id,dbxref_id) values ('null',(select cv_id from cv where name = 'null'),(select dbxref_id from dbxref where accession='local:null'));
 
-insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'local:computer file');
-insert into cvterm (name,cv_id,dbxref_id) values ('computer file', (select cv_id from cv where name = 'null'),(select dbxref_id from dbxref where accession='local:computer file'));
-
-insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'local:glass');
-insert into cvterm (name,definition,cv_id,dbxref_id) values ('glass','glass array',(select cv_id from cv where name = 'local'),(select dbxref_id from dbxref where accession='local:glass'));
-
-insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'local:photochemical_oligo');
-insert into cvterm (name,definition,cv_id,dbxref_id) values ('photochemical_oligo','in-situ photochemically synthesized oligoes',(select cv_id from cv where name = 'local'),(select dbxref_id from dbxref where accession='local:photochemical_oligo'));
-
 insert into pub (miniref,uniquename,type_id) values ('null','null',(select cvterm_id from cvterm where name = 'null'));
-insert into db (name, description) values ('GFF_source', 'A collection of sources (ie, column 2) from GFF files');
-
-insert into db (name) values ('ATCC');
-
-insert into db (name) values ('refseq');
-insert into db (name) values ('genbank');
-insert into db (name) values ('EMBL');
-insert into db (name) values ('TIGR');
-insert into db (name) values ('ucsc');
-insert into db (name) values ('ucla');
-insert into db (name) values ('SGD');
-
-insert into db (name) values ('PFAM');
-insert into db (name) values ('SUPERFAMILY');
-insert into db (name) values ('PROFILE');
-insert into db (name) values ('PRODOM');
-insert into db (name) values ('PRINTS');
-insert into db (name) values ('SMART');
-insert into db (name) values ('TIGRFAMs');
-insert into db (name) values ('PIR');
-
-insert into db (name) values ('Affymetrix_U133');
-insert into db (name) values ('Affymetrix_U133PLUS');
-insert into db (name) values ('Affymetrix_U95');
-insert into db (name) values ('LocusLink');
-insert into db (name) values ('RefSeq_protein');
-insert into db (name) values ('GenBank_protein');
-insert into db (name) values ('OMIM');
-insert into db (name) values ('Swiss');
-insert into db (name) values ('RefSNP');
-insert into db (name) values ('TSC');
---insert into db (name, contact_id, description, urlprefix) values ('affy:U133',(select contact_id from contact where name = 'null'),'Affymetrix U133','http://https://www.affymetrix.com/analysis/netaffx/fullrecord.affx?pk=HG-U133_PLUS_2:');
---insert into db (name, contact_id, description, urlprefix) values ('affy:U95',(select contact_id from contact where name = 'null'),'Affymetrix U95','http://https://www.affymetrix.com/analysis/netaffx/fullrecord.affx?pk=HG-U95AV2:');
-
-insert into db (name, description) values ('GR','Gramene');
-insert into db (name, description, urlprefix) values ('uniprot','UniProt/TrEMBL','http://us.expasy.org/cgi-bin/niceprot.pl?');
-insert into db (name, description, urlprefix) values ('refseq:mrna','RefSeq mRNA','http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=search&db=nucleotide&dopt=GenBank&term=');
-insert into db (name, description, urlprefix) values ('refseq:protein','RefSeq Protein','http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=search&db=protein&dopt=GenBank&term=');
-insert into db (name, description, urlprefix) values ('unigene','Unigene','http://www.ncbi.nih.gov/entrez/query.fcgi?db=unigene&cmd=search&term=');
-insert into db (name, description, urlprefix) values ('omim','OMIM','http://www.ncbi.nlm.nih.gov/entrez/dispomim.cgi?id=');
-insert into db (name, description, urlprefix) values ('locuslink','LocusLink','http://www.ncbi.nlm.nih.gov/LocusLink/LocRpt.cgi?l=');
-insert into db (name, description, urlprefix) values ('genbank:mrna','GenBank mRNA','http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=search&db=nucleotide&dopt=GenBank&term=');
-insert into db (name, description, urlprefix) values ('genbank:protein','GenBank Protein','http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=search&db=protein&dopt=GenBank&term=');
-insert into db (name, description, urlprefix) values ('swissprot:display','SwissProt','http://us.expasy.org/cgi-bin/niceprot.pl?');
-insert into db (name, description, urlprefix) values ('pfam','Pfam','http://www.sanger.ac.uk/cgi-bin/Pfam/dql.pl?query=');
-
-insert into analysis (name,program,programversion) values ('dabg' ,'dabg' ,'dabg' );
-insert into analysis (name,program,programversion) values ('dchip','dchip','dchip');
-insert into analysis (name,program,programversion) values ('gcrma','gcrma','gcrma');
-insert into analysis (name,program,programversion) values ('mas5' ,'mas5' ,'mas5' );
-insert into analysis (name,program,programversion) values ('mpam' ,'mpam' ,'mpam' );
-insert into analysis (name,program,programversion) values ('plier','plier','plier');
-insert into analysis (name,program,programversion) values ('rma'  ,'rma'  ,'rma'  );
-insert into analysis (name,program,programversion) values ('sea'  ,'sea'  ,'sea'  );
-insert into analysis (name,program,programversion) values ('vsn'  ,'vsn'  ,'vsn'  );
-
-insert into arraydesign (name,manufacturer_id,platformtype_id) values ('unknown'                                    , (select contact_id from contact where name = 'null'),(select cvterm_id from cvterm where name = 'null'));
-insert into arraydesign (name,manufacturer_id,platformtype_id) values ('virtual array'                              , (select contact_id from contact where name = 'null'),(select cvterm_id from cvterm where name = 'null'));
-insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_HG-U133_Plus_2' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
-insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_HG-U133A'       , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
-insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_HG-U133A_2'     , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
-insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_HG-U133B'       , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
-insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_HG-U95Av2'      , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
-insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_HG-U95B'        , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
-insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_HG-U95C'        , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
-insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_HG-U95D'        , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
-insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_HG-U95E'        , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
-insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_HuExon1'        , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
-insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_HuGeneFL'       , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
-insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_U74Av2'         , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
-insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_MG-U74Av2'      , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
-insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_MG-U74Bv2'      , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
-insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_MG-U74Cv2'      , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
-insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_RG-U34A'        , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
-insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_RG-U34B'        , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
-insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_RG-U34C'        , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
-insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_RT-U34'         , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
-insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_RN-U34'         , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
-insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_YG-S98'         , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
-insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_Yeast_2'        , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
-insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_RAE230A'        , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
-insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_RAE230B'        , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
-insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_Rat230_2'       , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
-insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_MOE430A'        , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
-insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_MOE430B'        , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
-insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_Mouse430_2'     , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
-insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_Mouse430A_2'    , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
-insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_ATH1-121501'    , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
-insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_Mapping100K_Hind240' , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
-insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_Mapping100K_Xba240'  , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
-insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_Mapping10K_Xba131'   , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
-insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_Mapping10K_Xba142'   , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
-insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_Mapping500K_NspI'    , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
-insert into arraydesign (name,manufacturer_id,platformtype_id,substratetype_id) values ('Affymetrix_Mapping500K_StyI'    , (select contact_id from contact where name = 'Affymetrix'),(select cvterm_id from cvterm where name = 'photochemical_oligo'),(select cvterm_id from cvterm where name = 'glass'));
-
-insert into cv (name) values ('developmental stages');
-insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'developmental stages:fetus');
-insert into cvterm (name,cv_id,dbxref_id) values ('fetus',      (select cv_id from cv where name = 'local'),(select dbxref_id from dbxref where accession='developmental stages:fetus'));
-
-insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'developmental stages:neonate');
-insert into cvterm (name,cv_id,dbxref_id) values ('neonate',    (select cv_id from cv where name = 'developmental stages'), (select dbxref_id from dbxref where accession='developmental stages:neonate'));
-
-insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'developmental stages:child');
-insert into cvterm (name,cv_id,dbxref_id) values ('child',      (select cv_id from cv where name = 'developmental stages'), (select dbxref_id from dbxref where accession='developmental stages:child'));
-
-insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'developmental stages:adult_young');
-insert into cvterm (name,cv_id,dbxref_id) values ('adult_young',(select cv_id from cv where name = 'developmental stages'),(select dbxref_id from dbxref where accession='developmental stages:adult_young'));
-
-insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'developmental stages:adult');
-insert into cvterm (name,cv_id,dbxref_id) values ('adult',      (select cv_id from cv where name = 'developmental stages'),(select dbxref_id from dbxref where accession='developmental stages:adult'));
-
-insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'developmental stages:adult_old');
-insert into cvterm (name,cv_id,dbxref_id) values ('adult_old',  (select cv_id from cv where name = 'developmental stages'), (select dbxref_id from dbxref where accession='developmental stages:adult_old'));
-
-insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'local:survival_time');
-insert into cvterm (name,cv_id,dbxref_id) values ('survival_time',(select cv_id from cv where name = 'local'),(select dbxref_id from dbxref where accession='local:survival_time'));
-
-
-insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'Statistical Terms:n');
-insert into cvterm (name,definition,cv_id,dbxref_id) values ('n','sensu statistica',  (select cv_id from cv where name = 'Statistical Terms'),(select dbxref_id from dbxref where accession='Statistical Terms:n'));
-
-insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'Statistical Terms:minimum');
-insert into cvterm (name,definition,cv_id,dbxref_id) values ('minimum','sensu statistica',  (select cv_id from cv where name = 'Statistical Terms'),(select dbxref_id from dbxref where accession='Statistical Terms:minimum'));
-
-insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'Statistical Terms:maximum');
-insert into cvterm (name,definition,cv_id,dbxref_id) values ('maximum','sensu statistica',  (select cv_id from cv where name = 'Statistical Terms'),(select dbxref_id from dbxref where accession='Statistical Terms:maximum'));
-
-insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'Statistical Terms:modality');
-insert into cvterm (name,definition,cv_id,dbxref_id) values ('modality','sensu statistica',  (select cv_id from cv where name = 'Statistical Terms'),(select dbxref_id from dbxref where accession='Statistical Terms:modality'));
-
-insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'Statistical Terms:modality p');
-insert into cvterm (name,definition,cv_id,dbxref_id) values ('modality p','sensu statistica',  (select cv_id from cv where name = 'Statistical Terms'),(select dbxref_id from dbxref where accession='Statistical Terms:modality p'));
-
-insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'Statistical Terms:mean');
-insert into cvterm (name,definition,cv_id,dbxref_id) values ('mean','sensu statistica',  (select cv_id from cv where name = 'Statistical Terms'),(select dbxref_id from dbxref where accession='Statistical Terms:mean'));
-
-insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'Statistical Terms:median');
-insert into cvterm (name,definition,cv_id,dbxref_id) values ('median','sensu statistica',  (select cv_id from cv where name = 'Statistical Terms'),(select dbxref_id from dbxref where accession='Statistical Terms:median'));
-
-insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'Statistical Terms:mode');
-insert into cvterm (name,definition,cv_id,dbxref_id) values ('mode','sensu statistica',  (select cv_id from cv where name = 'Statistical Terms'),(select dbxref_id from dbxref where accession='Statistical Terms:mode'));
-
-insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'Statistical Terms:quartile 1');
-insert into cvterm (name,definition,cv_id,dbxref_id) values ('quartile 1','sensu statistica',  (select cv_id from cv where name = 'Statistical Terms'),(select dbxref_id from dbxref where accession='Statistical Terms:quartile 1'));
-
-insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'Statistical Terms:quartile 3');
-insert into cvterm (name,definition,cv_id,dbxref_id) values ('quartile 3','sensu statistica',  (select cv_id from cv where name = 'Statistical Terms'),(select dbxref_id from dbxref where accession='Statistical Terms:quartile 3'));
-
-insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'Statistical Terms:skewness');
-insert into cvterm (name,definition,cv_id,dbxref_id) values ('skewness','sensu statistica',  (select cv_id from cv where name = 'Statistical Terms'),(select dbxref_id from dbxref where accession='Statistical Terms:skewness'));
-
-insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'Statistical Terms:kurtosis');
-insert into cvterm (name,definition,cv_id,dbxref_id) values ('kurtosis','sensu statistica',  (select cv_id from cv where name = 'Statistical Terms'),(select dbxref_id from dbxref where accession='Statistical Terms:kurtosis'));
-
-insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'Statistical Terms:chi square p');
-insert into cvterm (name,definition,cv_id,dbxref_id) values ('chi square p','sensu statistica',  (select cv_id from cv where name = 'Statistical Terms'),(select dbxref_id from dbxref where accession='Statistical Terms:chi square p'));
-
-insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'Statistical Terms:standard deviation');
-insert into cvterm (name,definition,cv_id,dbxref_id) values ('standard deviation','sensu statistica',  (select cv_id from cv where name = 'Statistical Terms'),(select dbxref_id from dbxref where accession='Statistical Terms:standard deviation'));
-
-insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'Statistical Terms:expectation maximization gaussian mean');
-insert into cvterm (name,definition,cv_id,dbxref_id) values ('expectation maximization gaussian mean','sensu statistica',  (select cv_id from cv where name = 'Statistical Terms'),(select dbxref_id from dbxref where accession='Statistical Terms:expectation maximization gaussian mean'));
-
-insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'Statistical Terms:expectation maximization p');
-insert into cvterm (name,definition,cv_id,dbxref_id) values ('expectation maximization p','sensu statistica',  (select cv_id from cv where name = 'Statistical Terms'),(select dbxref_id from dbxref where accession='Statistical Terms:expectation maximization p'));
-
-insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'Statistical Terms:histogram');
-insert into cvterm (name,definition,cv_id,dbxref_id) values ('histogram','sensu statistica',  (select cv_id from cv where name = 'Statistical Terms'),(select dbxref_id from dbxref where accession='Statistical Terms:histogram'));
-
-insert into cv (name,definition) values ('autocreated','Terms that are automatically inserted by loading software');
 
 insert into cv (name,definition) values ('chado_properties','Terms that are used in the chadoprop table to describe the state of the database');
 
@@ -232,5 +29,4 @@ insert into cvterm (name,definition,cv_id,dbxref_id) values ('version','Chado sc
                                 indexed TEXT,
                                 query TEXT,
                                 special_index TEXT
-                                );
-
+                                );

+ 32 - 0
tripal_core/chado_schema/initialize-1.3.sql

@@ -0,0 +1,32 @@
+/* For load_gff3.pl */
+
+insert into contact (name,description) values ('null','null');
+insert into cv (name) values ('null');
+insert into cv (name,definition) values ('local','Locally created terms');
+insert into cv (name,definition) values ('Statistical Terms','Locally created terms for statistics');
+insert into db (name, description) values ('null', 'Use when a database is not available.');
+
+insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'local:null');
+insert into cvterm (name,cv_id,dbxref_id) values ('null',(select cv_id from cv where name = 'null'),(select dbxref_id from dbxref where accession='local:null'));
+
+insert into pub (miniref,uniquename,type_id) values ('null','null',(select cvterm_id from cvterm where name = 'null'));
+
+insert into cv (name,definition) values ('chado_properties','Terms that are used in the chadoprop table to describe the state of the database');
+
+insert into dbxref (db_id,accession) values ((select db_id from db where name='null'), 'chado_properties:version');
+insert into cvterm (name,definition,cv_id,dbxref_id) values ('version','Chado schema version',(select cv_id from cv where name = 'chado_properties'),(select dbxref_id from dbxref where accession='chado_properties:version'));
+
+
+--this table will probably end up in general.sql
+ CREATE TABLE public.materialized_view   (       
+                                materialized_view_id SERIAL,
+                                last_update TIMESTAMP,
+                                refresh_time INT,
+                                name VARCHAR(64) UNIQUE,
+                                mv_schema VARCHAR(64),
+                                mv_table VARCHAR(128),
+                                mv_specs TEXT,
+                                indexed TEXT,
+                                query TEXT,
+                                special_index TEXT
+                                );

+ 515 - 120
tripal_core/includes/tripal_core.chado_install.inc

@@ -9,7 +9,7 @@
  *
  * @ingroup tripal_core
  */
-function tripal_core_chado_load_form() {
+function tripal_core_chado_load_form($form, $form_state) {
 
   // we want to force the version of Chado to be set properly
   $real_version = chado_get_version(TRUE);
@@ -17,6 +17,65 @@ function tripal_core_chado_load_form() {
   // get the effective version.  Pass true as second argument
   // to warn the user if the current version is not compatible
   $version = chado_get_version(FALSE, TRUE);
+  if (array_key_exists('values', $form_state)) {
+    if ($form_state['values']['action_to_do'] == "Upgrade Chado v1.2 to v1.3") {
+      $tables_list = implode(', ', array('analysis_cvterm', 'analysis_dbxref', 'analysis_pub',
+        'analysis_relationship', 'contactprop', 'dbprop', 'feature_contact',
+        'featuremap_contact', 'featuremap_dbxref', 'featuremap_organism', 'featuremapprop',
+        'featureposprop', 'library_contact', 'library_expression', 'library_expressionprop',
+        'library_featureprop', 'library_relationship', 'library_relationship_pub', 'nd_experiment_analysis',
+        'organism_cvterm', 'organism_cvtermprop', 'organism_pub', 'organism_relationship',
+        'organismprop_pub', 'phenotypeprop', 'phylotreeprop', 'project_analysis',
+        'project_dbxref', 'project_feature', 'project_stock', 'pubauthor_contact',
+        'stock_feature', 'stock_featuremap', 'stock_library', 'stockcollection_db'));
+      $items = array(
+        'PostgreSQL version 9.1 is required to perform this upgrade. If your Tripal
+         site uses an older version please upgrade before proceeding.',
+        'A major change between Chado v1.2 and v1.3 is that primary and foreign
+         keys were upgraded from integers to big integers. If your site has custom
+         materialized views that will hold data derived from fields changed to
+         big integers then you may need to alter the views to change the fields
+         from integers to big integers and repopulate those views. If you have not
+         added any materialized views you can ignore this issue.',
+        'Custom PL/pgSQL functions that expect primary and
+         foreign key fields to be integers will not work after the upgrade.
+         Those functions will need to be altered to accept big integers. If you
+         do not have any custom PL/pgSQL functions you can ignore this issue.',
+        'PostgreSQL Views that use fields that are converted to big
+         integers will cause this upgrade to fail.  You must first remove
+         those views, perform the upgrade and then recreate them with the
+         appropriate fields change to big integers. If you do not have custom
+         PostgreSQL Views you can ignore this issue.',
+        'Several new tables were added to Chado v1.3.  However, some groups have
+         added these tables to their Chado v1.2 installation.  The Tripal upgrader
+         will alter the primary and foreign keys of those tables to be "bigints"
+         if they already exist but will otherwise leave them the same.  You should
+         verify that any tables with Chado v1.3 names correctly match the v1.3 schema.
+         Otherwise you may have problems using Tripal. If you have not added any
+         Chado v1.3 tables to your Chado v1.2 database you can ignore this issue.
+         These are the newly added tables:  ' .
+         $tables_list  . '.'
+      );
+      $list = theme_item_list(array(
+        'items' => $items,
+        'title' => '',
+        'type' => 'ul',
+        'attributes' => array(),
+      ));
+      drupal_set_message('Please note: the upgrade of Chado from v1.2 to v1.3 may
+          require several fixes to your database. Please review the following
+          list to ensure a safe upgrade. The Tripal upgrader is
+          not able to fix these problems automatically: ' . $list, 'warning');
+    }
+    if ($form_state['values']['action_to_do'] == "Install Chado v1.3" or
+        $form_state['values']['action_to_do'] == "Install Chado v1.2" or
+        $form_state['values']['action_to_do'] == "Install Chado v1.11") {
+      drupal_set_message('Please note: if Chado is already installed it will
+          be removed and recreated and all data will be lost. If this is
+          desired or if this is the first time Chado has been installed
+          you can ignore this issue.', 'warning');
+    }
+  }
 
   $form['current_version'] = array(
     '#type' => 'item',
@@ -25,15 +84,23 @@ function tripal_core_chado_load_form() {
   );
 
   $form['action_to_do'] = array(
-     '#type' => 'radios',
-     '#title' => 'Installation/Upgrade Action',
-     '#options' => array(
-        'Install Chado v1.2' => t('New Install of Chado v1.2 (erases all existing Chado data if Chado already exists)'),
-        'Upgrade Chado v1.11 to v1.2' => t('Upgrade existing Chado v1.11 to v1.2 (no data is lost)'),
-        'Install Chado v1.11' => t('New Install of Chado v1.11 (erases all existing Chado data if Chado already exists)')
-     ),
-     '#description' => t('Select an action to perform. If you want to install Chado all other Tripal modules must not be installed.'),
-     '#required' => TRUE,
+    '#type' => 'radios',
+    '#title' => 'Installation/Upgrade Action',
+    '#options' => array(
+      'Install Chado v1.3' => t('New Install of Chado v1.3 (erases all existing Chado data if Chado already exists)'),
+      'Upgrade Chado v1.2 to v1.3' => t('Upgrade existing Chado v1.2 to v1.3 (no data is lost)'),
+      'Install Chado v1.2' => t('New Install of Chado v1.2 (erases all existing Chado data if Chado already exists)'),
+      'Upgrade Chado v1.11 to v1.2' => t('Upgrade existing Chado v1.11 to v1.2 (no data is lost)'),
+      'Install Chado v1.11' => t('New Install of Chado v1.11 (erases all existing Chado data if Chado already exists)'),
+    ),
+    '#description' => t('Select an action to perform. If you want to install Chado all other Tripal modules must not be installed.'),
+    '#required' => TRUE,
+    '#ajax' => array(
+      'callback' => "tripal_core_chado_load_form_ajax_callback",
+      'wrapper'  => 'tripal_core_chado_load_form',
+      'effect'   => 'fade',
+      'method'   => 'replace',
+    ),
   );
 
   $form['warning'] = array(
@@ -46,6 +113,20 @@ function tripal_core_chado_load_form() {
     '#value' => t('Install/Upgrade Chado'),
   );
 
+  $form['#prefix'] = '<div id="tripal_core_chado_load_form">';
+  $form['#suffix'] = '</div>';
+  return $form;
+}
+
+/**
+ * Ajax callback function for the gensas_job_view_panel_form.
+ *
+ * @param $form
+ * @param $form_state
+ */
+function tripal_core_chado_load_form_ajax_callback($form, $form_state) {
+  // drupal_debug($form['tree_settings']['org_table']['num_orgs']);
+
   return $form;
 }
 
@@ -54,11 +135,14 @@ function tripal_core_chado_load_form_validate($form, &$form_state) {
   // Tripal modules are installed.  This is because the install files
   // of those modules may add content to Chado and reinstalling Chado
   // removes that content which may break the modules.
-
-  if ($form_state['values']['action_to_do'] == "Install Chado v1.2" or
+  if ($form_state['values']['action_to_do'] == "Install Chado v1.3" or
+      $form_state['values']['action_to_do'] == "Install Chado v1.2" or
       $form_state['values']['action_to_do'] == "Install Chado v1.11") {
 
     $modules = system_get_info('module');
+    // The tripal_views module should not be included as it's a rquired
+    // dependency of tripal_core
+    unset($modules['tripal_views']);
     $list = array();
     foreach ($modules as $mname => $module) {
       if (array_key_exists('dependencies', $module) and in_array('tripal_core', $module['dependencies'])) {
@@ -79,6 +163,13 @@ function tripal_core_chado_load_form_validate($form, &$form_state) {
       form_set_error("action_to_do", "You are already at v1.2.  There is no need to upgrade.");
     }
   }
+  if ($form_state['values']['action_to_do'] == "Upgrade Chado v1.2 to v1.3") {
+    // Make sure we are already not at v1.3
+    $real_version = chado_get_version(TRUE);
+    if ($real_version == "1.3") {
+      form_set_error("action_to_do", "You are already at v1.3.  There is no need to upgrade.");
+    }
+  }
 }
 /**
  * Submit Load Chado Schema Form
@@ -89,7 +180,8 @@ function tripal_core_chado_load_form_submit($form, &$form_state) {
   global $user;
   $action_to_do = trim($form_state['values']['action_to_do']);
   $args = array($action_to_do);
-  tripal_add_job($action_to_do, 'tripal_core', 'tripal_core_install_chado', $args, $user->uid);
+  tripal_add_job($action_to_do, 'tripal_core',
+      'tripal_core_install_chado', $args, $user->uid);
 }
 
 /**
@@ -109,82 +201,316 @@ function tripal_core_install_chado($action) {
        :version)
   ";
 
-  if ($action == 'Install Chado v1.2') {
-    $schema_file = drupal_get_path('module', 'tripal_core') . '/chado_schema/default_schema-1.2.sql';
-    $init_file = drupal_get_path('module', 'tripal_core') . '/chado_schema/initialize-1.2.sql';
-    if (tripal_core_reset_chado_schema()) {
-      $success = tripal_core_install_sql($schema_file);
-      if ($success) {
-        print "Install of Chado v1.2 (Step 1 of 2) Successful!\n";
-      }
-      else {
-        print "Installation (Step 1 of 2) Problems!  Please check output above for errors.\n";
-        exit;
-      }
-      $success = tripal_core_install_sql($init_file);
-      if ($success) {
-        print "Install of Chado v1.2 (Step 2 of 2) Successful.\nInstallation Complete\n";
-      }
-      else {
-        print "Installation (Step 2 of 2) Problems!  Please check output above for errors.\n";
-        exit;
-      }
-      chado_query($vsql, array(':version' => '1.2')); # set the version
+  $vusql = "
+    UPDATE {chadoprop}
+    SET value = :version
+    WHERE type_id = (SELECT cvterm_id
+        FROM {cvterm} CVT
+          INNER JOIN {cv} CV on CVT.cv_id = CV.cv_id
+         WHERE CV.name = 'chado_properties' AND CVT.name = 'version')
+  ";
+
+  $transaction = db_transaction();
+  try {
+    if ($action == 'Install Chado v1.3') {
+      tripal_core_install_chado_1_3();
+      chado_query($vsql, array(':version' => '1.3'));
+    }
+    elseif ($action == 'Upgrade Chado v1.2 to v1.3') {
+      tripal_core_upgrade_chado_1_2_to_1_3();
+      chado_query($vusql, array(':version' => '1.3'));
+    }
+    elseif ($action == 'Install Chado v1.2') {
+      tripal_core_install_chado_1_2();
+      chado_query($vsql, array(':version' => '1.2'));
+    }
+    elseif ($action == 'Upgrade Chado v1.11 to v1.2') {
+      tripal_core_upgrade_chado_1_11_to_1_2();
+      chado_query($vsql, array(':version' => '1.2'));
+    }
+    elseif ($action == 'Install Chado v1.11') {
+      tripal_core_install_chado_1_11();
+    }
+  }
+  catch (Exception $e) {
+    $transaction->rollback();
+    tripal_core_chado_install_done();
+    tripal_report_error('tripal_core', TRIPAL_ERROR, $e->getMessage(), array('print' => TRUE));
+    return FALSE;
+  }
+  return TRUE;
+
+
+}
+
+/**
+ * Installs Chado v1.3.
+ */
+function tripal_core_install_chado_1_3() {
+  // Get the path to the schema and init SQL files.
+  $schema_file = drupal_get_path('module', 'tripal_core') .
+    '/chado_schema/default_schema-1.3.sql';
+  $init_file = drupal_get_path('module', 'tripal_core') .
+    '/chado_schema/initialize-1.3.sql';
+
+  // Erase the Chado schema if it exists and perform the install.
+  if (tripal_core_reset_chado_schema()) {
+    $success = tripal_core_install_sql($schema_file);
+    if ($success) {
+      print "Install of Chado v1.3 (Step 1 of 2) Successful!\n";
+    }
+    else {
+      throw new Exception("Installation (Step 1 of 2) Problems!  Please check output above for errors.");
+    }
+    $success = tripal_core_install_sql($init_file);
+    if ($success) {
+      print "Install of Chado v1.3 (Step 2 of 2) Successful.\nInstallation Complete\n";
     }
     else {
-      print "ERROR: cannot install chado.  Please check database permissions\n";
-      exit;
+      throw new Exception("Installation (Step 2 of 2) Problems!  Please check output above for errors.");
     }
   }
-  elseif ($action == 'Upgrade Chado v1.11 to v1.2') {
-    $schema_file = drupal_get_path('module', 'tripal_core') . '/chado_schema/default_schema-1.11-1.2-diff.sql';
-    $init_file = drupal_get_path('module', 'tripal_core') . '/chado_schema/upgrade-1.11-1.2.sql';
+  else {
+    throw new Exception("ERROR: cannot install chado.  Please check database permissions");
+  }
+}
+/**
+ * Installs Chado v1.2.
+ */
+function tripal_core_install_chado_1_2() {
+  // Get the path to the schema and init SQL files.
+  $schema_file = drupal_get_path('module', 'tripal_core') .
+    '/chado_schema/default_schema-1.2.sql';
+  $init_file = drupal_get_path('module', 'tripal_core') .
+    '/chado_schema/initialize-1.2.sql';
+
+  // Erase the Chado schema if it exists and perform the install.
+  if (tripal_core_reset_chado_schema()) {
     $success = tripal_core_install_sql($schema_file);
     if ($success) {
-      print "Upgrade from v1.11 to v1.2 (Step 1 of 2) Successful!\n";
+      print "Install of Chado v1.2 (Step 1 of 2) Successful!\n";
     }
     else {
-      print "Upgrade (Step 1 of 2) problems!  Please check output above for errors.\n";
-      exit;
+      throw new Exception("Installation (Step 1 of 2) Problems!  Please check output above for errors.");
     }
     $success = tripal_core_install_sql($init_file);
     if ($success) {
-      print "Upgrade from v1.11 to v1.2 (Step 2 of 2) Successful.\nUpgrade Complete!\n";
+      print "Install of Chado v1.2 (Step 2 of 2) Successful.\nInstallation Complete\n";
     }
     else {
-      print "Upgrade (Step 2 of 2) problems!  Please check output above for errors.\n";
-      exit;
+      throw new Exception("Installation (Step 2 of 2) Problems!  Please check output above for errors.");
     }
-    chado_query($vsql, array(':version' => '1.2')); # set the version
   }
-  elseif ($action == 'Install Chado v1.11') {
-    $schema_file = drupal_get_path('module', 'tripal_core') . '/chado_schema/default_schema-1.11.sql';
-    $init_file = drupal_get_path('module', 'tripal_core') . '/chado_schema/initialize-1.11.sql';
-    if (tripal_core_reset_chado_schema()) {
-      $success = tripal_core_install_sql($schema_file);
-      if ($success) {
-        print "Install of Chado v1.11 (Step 1 of 2) Successful!\n";
-      }
-      else {
-        print "Installation (Step 1 of 2) Problems!  Please check output above for errors.\n";
-        exit;
-      }
-      $success = tripal_core_install_sql($init_file);
-      if ($success) {
-        print "Install of Chado v1.11 (Step 2 of 2) Successful.\nInstallation Complete!\n";
+  else {
+    throw new Exception("ERROR: cannot install chado.  Please check database permissions");
+  }
+}
+/**
+ *
+ */
+function tripal_core_install_chado_1_11() {
+
+  // Get the path to the schema and init SQL files.
+  $schema_file = drupal_get_path('module', 'tripal_core') .
+    '/chado_schema/default_schema-1.11.sql';
+  $init_file = drupal_get_path('module', 'tripal_core') .
+    '/chado_schema/initialize-1.11.sql';
+
+  // Erase the Chado schema if it exists and perform the install.
+  if (tripal_core_reset_chado_schema()) {
+    $success = tripal_core_install_sql($schema_file);
+    if ($success) {
+      print "Install of Chado v1.11 (Step 1 of 2) Successful!\n";
+    }
+    else {
+      throw new Exception("Installation (Step 1 of 2) Problems!  Please check output above for errors.");
+    }
+    $success = tripal_core_install_sql($init_file);
+    if ($success) {
+      print "Install of Chado v1.11 (Step 2 of 2) Successful.\nInstallation Complete!\n";
+    }
+    else {
+      throw new Exception("Installation (Step 2 of 2) Problems!  Please check output above for errors.");
+    }
+  }
+  else {
+    throw new Exception("ERROR: cannot install chado.  Please check database permissions");
+  }
+}
+/**
+ * Upgrades Chado from v1.2 to v1.3
+ */
+function tripal_core_upgrade_chado_1_2_to_1_3() {
+
+  // Upgrade some of the custom tables that Tripal created that are now in
+  // Chado v1.3.  We'll do this ahead of time because the upgrade script won't
+  // upgrade tables if they already exist.
+  print "Checking for existing v1.3 tables in v1.2 and fixing bigints...\n";
+  tripal_core_upgrade_chado_1_2_to_1_3_pre_alter();
+
+  // Get the path to the diff schema and upgrade SQL files.
+  print "Incorporating additional changes...\n";
+  $diff_file = drupal_get_path('module', 'tripal_core') .
+    '/chado_schema/default_schema-1.2-1.3-diff.sql';
+
+  $success = tripal_core_install_sql($diff_file);
+  if ($success) {
+    print "Upgrade from v1.2 to v1.3 Successful!\n";
+  }
+  else {
+    throw new Exception("Upgrade problems!  Please check output above for errors.");
+  }
+}
+
+/**
+ * Upgrade custom tables that may match the tables now in Chado v1.3.
+ *
+ * There were many new tables that were added to Chado v1.3 that were
+ * suggested by the Chado user community.  Some of those were Tripal users.
+ * Therefore, to help these Tripal users upgrade more seemlessly this function
+ * checks if those custom tables already exists, and if so updates them as
+ * best it can to match.  At a minimum it will create the table if it doesn't
+ * exist and if it does it will change the primary keys and foreign keys to
+ * be big ints.
+ */
+function tripal_core_upgrade_chado_1_2_to_1_3_pre_alter() {
+
+  // Include the Chado v1.3 schema definitions.
+  module_load_include('inc', 'tripal_core', '/api/tripal_core.schema_v1.3.api');
+
+  // The list of new tables in Chado v1.3
+  $new_tables = array('analysis_cvterm', 'analysis_dbxref', 'analysis_pub', 'analysis_relationship',
+    'contactprop', 'dbprop', 'feature_contact', 'featuremap_contact', 'featuremap_dbxref',
+    'featuremap_organism', 'featuremapprop', 'featureposprop', 'library_contact',
+    'library_expression', 'library_expressionprop', 'library_featureprop',
+    'library_relationship', 'library_relationship_pub', 'nd_experiment_analysis',
+    'organism_cvterm', 'organism_cvtermprop', 'organism_pub', 'organism_relationship',
+    'organismprop_pub', 'phenotypeprop', 'phylotreeprop', 'project_analysis',
+    'project_dbxref', 'project_feature', 'project_stock', 'pubauthor_contact',
+    'stock_feature', 'stock_featuremap', 'stock_library', 'stockcollection_db',
+  );
+
+  // Get the name of the chado schema.
+  $chado_schema = tripal_get_schema_name('chado');
+
+  // Iterate through the new Chado tables and create them or if they already
+  // exist then update them.
+  foreach ($new_tables as $table) {
+
+    // Get the schema for this table.
+    $function = 'tripal_core_chado_schema_v1_3_' . $table;
+    $schema = $function();
+
+    // If the table exists then fix the pkeys and fkeys.
+    if (chado_table_exists($table)) {
+
+      // Update the primary key fields to be bigints.
+      $fields = $schema['fields'];
+      foreach ($fields as $field_name => $field) {
+        if ($field['type'] == 'serial') {
+          if (chado_column_exists($table, $field_name)) {
+            $sql = 'ALTER TABLE {' . $table . '} ALTER COLUMN ' . $field_name . ' TYPE bigint';
+            chado_query($sql);
+          }
+          else {
+            throw new Exception('Could not alter primary key to bigint: ' . $table . '.' . $field_name);
+          }
+        }
       }
-      else {
-        print "Installation (Step 2 of 2) Problems!  Please check output above for errors.\n";
-        exit;
+
+      // Update the foreign key fields to be bigints.
+      $fkeys = $schema['foreign keys'];
+      foreach ($fkeys as $fktable => $details) {
+        foreach ($details['columns'] as $leftkey => $rightkey) {
+          if (chado_column_exists($table, $leftkey)) {
+            $sql = 'ALTER TABLE {' . $table . '} ALTER COLUMN ' . $leftkey . ' TYPE bigint';
+            chado_query($sql);
+          }
+          else {
+            throw new Exception('Could not alter foreign key to bigint: ' . $table . '.' . $leftkey);
+          }
+        }
       }
+
     }
-    else {
-      print "ERROR: cannot install chado.  Please check database permissions\n";
-      exit;
+  }
+  // Now create the sequences if they don't already exist.
+  $sequences = array(
+    'analysis_cvterm_analysis_cvterm_id_seq',
+    'analysis_dbxref_analysis_dbxref_id_seq',
+    'analysis_pub_analysis_pub_id_seq',
+    'analysis_relationship_analysis_relationship_id_seq',
+    'contactprop_contactprop_id_seq',
+    'dbprop_dbprop_id_seq',
+    'feature_contact_feature_contact_id_seq',
+    'featuremap_contact_featuremap_contact_id_seq',
+    'featuremap_dbxref_featuremap_dbxref_id_seq',
+    'featuremap_organism_featuremap_organism_id_seq',
+    'featuremapprop_featuremapprop_id_seq',
+    'featureposprop_featureposprop_id_seq',
+    'library_contact_library_contact_id_seq',
+    'library_expression_library_expression_id_seq',
+    'library_expressionprop_library_expressionprop_id_seq',
+    'library_featureprop_library_featureprop_id_seq',
+    'library_relationship_library_relationship_id_seq',
+    'library_relationship_pub_library_relationship_pub_id_seq',
+    'nd_experiment_analysis_nd_experiment_analysis_id_seq',
+    'organism_cvterm_organism_cvterm_id_seq',
+    'organism_cvtermprop_organism_cvtermprop_id_seq',
+    'organism_pub_organism_pub_id_seq',
+    'organism_relationship_organism_relationship_id_seq',
+    'organismprop_pub_organismprop_pub_id_seq',
+    'phenotypeprop_phenotypeprop_id_seq',
+    'phylotreeprop_phylotreeprop_id_seq',
+    'project_analysis_project_analysis_id_seq',
+    'project_dbxref_project_dbxref_id_seq',
+    'project_feature_project_feature_id_seq',
+    'project_stock_project_stock_id_seq',
+    'pubauthor_contact_pubauthor_contact_id_seq',
+    'stock_feature_stock_feature_id_seq',
+    'stock_featuremap_stock_featuremap_id_seq',
+    'stock_library_stock_library_id_seq',
+    'stockcollection_db_stockcollection_db_id_seq'
+  );
+  foreach ($sequences as $sequence) {
+
+    // Now add in the sequences if they don't already exist. There is no
+    // PostgreSQL 'CREATE SEQUENCE IF NOT EXIST' so we're forced to do it here
+    // and these create statements were removed from the diff upgrade file.
+    if (!chado_sequence_exists($sequence)) {
+      $sql = "CREATE SEQUENCE {" . $sequence . "} START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1";
+      chado_query($sql);
     }
   }
 }
 
+/**
+ * Upgrades Chado from v1.11 to v1.2
+ */
+function tripal_core_upgrade_chado_1_11_to_1_2() {
+
+  // Get the path to the schema diff and upgarde SQL files.
+  $schema_file = drupal_get_path('module', 'tripal_core') .
+    '/chado_schema/default_schema-1.11-1.2-diff.sql';
+  $init_file = drupal_get_path('module', 'tripal_core') .
+    '/chado_schema/upgrade-1.11-1.2.sql';
+
+  $success = tripal_core_install_sql($schema_file);
+  if ($success) {
+    print "Upgrade from v1.11 to v1.2 (Step 1 of 2) Successful!\n";
+  }
+  else {
+    throw new Exception("Upgrade (Step 1 of 2) problems!  Please check output above for errors.");
+  }
+  $success = tripal_core_install_sql($init_file);
+  if ($success) {
+    print "Upgrade from v1.11 to v1.2 (Step 2 of 2) Successful.\nUpgrade Complete!\n";
+  }
+  else {
+    throw new Exception("Upgrade (Step 2 of 2) problems!  Please check output above for errors.");
+  }
+}
+
 /**
  * Reset the Chado Schema
  * This drops the current chado and chado-related schema and re-creates it
@@ -193,6 +519,10 @@ function tripal_core_install_chado($action) {
  */
 function tripal_core_reset_chado_schema() {
 
+  // determine the schema name.
+  $chado_schema = tripal_get_schema_name('chado');
+  $chado_dot = $chado_schema . '.';
+
   // drop current chado and chado-related schema
   if (chado_dbschema_exists('genetic_code')) {
     print "Dropping existing 'genetic_code' schema\n";
@@ -206,14 +536,19 @@ function tripal_core_reset_chado_schema() {
     print "Dropping existing 'frange' schema\n";
     db_query("drop schema frange cascade");
   }
-  if (chado_dbschema_exists('chado')) {
-    print "Dropping existing 'chado' schema\n";
-    db_query("drop schema chado cascade");
+  if (chado_dbschema_exists($chado_schema)) {
+    if ($chado_schema != 'chado') {
+      print "Dropping existing Chado ('$chado_schema') schema\n";
+    }
+    else {
+      print "Dropping existing 'chado' schema\n";
+    }
+    db_query("drop schema $chado_schema cascade");
   }
 
   // create the new chado schema
   print "Creating 'chado' schema\n";
-  db_query("create schema chado");
+  db_query("create schema $chado_schema");
   if (chado_dbschema_exists('chado')) {
     // before creating the plpgsql language let's check to make sure
     // it doesn't already exists
@@ -241,8 +576,12 @@ function tripal_core_install_sql($sql_file) {
 
   $chado_local = chado_dbschema_exists('chado');
 
+  // determine the schema name.
+  $chado_schema = tripal_get_schema_name('chado');
+  $chado_dot = $chado_schema . '.';
+
   if ($chado_local) {
-    db_query("set search_path to chado");
+    db_query("set search_path to $chado_schema");
   }
   print "Loading $sql_file...\n";
   $lines = file($sql_file, FILE_SKIP_EMPTY_LINES);
@@ -253,6 +592,7 @@ function tripal_core_install_sql($sql_file) {
 
   $stack = array();
   $in_string = 0;
+  $in_function = FALSE;
   $query = '';
   $i = 0;
   $success = 1;
@@ -271,96 +611,151 @@ function tripal_core_install_sql($sql_file) {
       continue;
     }
     // Find SQL for new objects
-    if (preg_match('/^\s*CREATE\s+TABLE/i', $line) and !$in_string) {
+    if (preg_match('/^\s*CREATE\s+TABLE/i', $line) and !$in_string and !$in_function) {
       $stack[] = 'table';
-      $line = preg_replace("/public\./", "chado.", $line);
+      $line = preg_replace("/public\./", $chado_dot, $line);
     }
-    if (preg_match('/^\s*ALTER\s+TABLE/i', $line) and !$in_string) {
-      $stack[] = 'alter table';
-      $line = preg_replace("/public\./", "chado.", $line);
+    if (preg_match('/^\s*ALTER\s+TABLE\s+/i', $line) and !$in_string and !$in_function) {
+      $stack[] = 'alter_table';
+      $line = preg_replace("/public\./", $chado_dot, $line);
     }
-    if (preg_match('/^\s*SET/i', $line) and !$in_string) {
+    if (preg_match('/^\s*SET/i', $line) and !$in_string and !$in_function) {
       $stack[] = 'set';
     }
-    if (preg_match('/^\s*CREATE\s+SCHEMA/i', $line) and !$in_string) {
+    if (preg_match('/^\s*CREATE\s+SCHEMA/i', $line) and !$in_string and !$in_function) {
       $stack[] = 'schema';
     }
-    if (preg_match('/^\s*CREATE\s+SEQUENCE/i', $line) and !$in_string) {
+    if (preg_match('/^\s*CREATE\s+SEQUENCE/i', $line) and !$in_string and !$in_function) {
       $stack[] = 'sequence';
-      $line = preg_replace("/public\./", "chado.", $line);
+      $line = preg_replace("/public\./", $chado_dot, $line);
     }
-    if (preg_match('/^\s*CREATE\s+(?:OR\s+REPLACE\s+)*VIEW/i', $line) and !$in_string) {
+    if (preg_match('/^\s*CREATE\s+(?:OR\s+REPLACE\s+)*VIEW/i', $line) and !$in_string and !$in_function) {
       $stack[] = 'view';
-      $line = preg_replace("/public\./", "chado.", $line);
+      $line = preg_replace("/public\./", $chado_dot, $line);
     }
-    if (preg_match('/^\s*COMMENT/i', $line) and !$in_string and sizeof($stack)==0) {
+    if (preg_match('/^\s*COMMENT/i', $line) and !$in_string and sizeof($stack)==0 and !$in_function) {
       $stack[] = 'comment';
-      $line = preg_replace("/public\./", "chado.", $line);
+      $line = preg_replace("/public\./", $chado_dot, $line);
     }
-    if (preg_match('/^\s*CREATE\s+(?:OR\s+REPLACE\s+)*FUNCTION/i', $line) and !$in_string) {
+    if (preg_match('/^\s*CREATE\s+(?:OR\s+REPLACE\s+)*FUNCTION/i', $line) and !$in_string and !$in_function) {
+      $in_function = TRUE;
       $stack[] = 'function';
-      $line = preg_replace("/public\./", "chado.", $line);
+      $line = preg_replace("/public\./", $chado_dot, $line);
     }
-    if (preg_match('/^\s*CREATE\s+INDEX/i', $line) and !$in_string) {
+    if (preg_match('/^\s*CREATE\s+INDEX/i', $line) and !$in_string and !$in_function) {
       $stack[] = 'index';
     }
-    if (preg_match('/^\s*INSERT\s+INTO/i', $line) and !$in_string) {
+    if (preg_match('/^\s*INSERT\s+INTO/i', $line) and !$in_string and !$in_function) {
       $stack[] = 'insert';
-      $line = preg_replace("/public\./", "chado.", $line);
+      $line = preg_replace("/public\./", $chado_dot, $line);
     }
-    if (preg_match('/^\s*CREATE\s+TYPE/i', $line) and !$in_string) {
+    if (preg_match('/^\s*CREATE\s+TYPE/i', $line) and !$in_string and !$in_function) {
       $stack[] = 'type';
     }
-    if (preg_match('/^\s*GRANT/i', $line) and !$in_string) {
+    if (preg_match('/^\s*GRANT/i', $line) and !$in_string and !$in_function) {
       $stack[] = 'grant';
     }
-    if (preg_match('/^\s*CREATE\s+AGGREGATE/i', $line) and !$in_string) {
+    if (preg_match('/^\s*CREATE\s+AGGREGATE/i', $line) and !$in_string and !$in_function) {
       $stack[] = 'aggregate';
     }
+    if (preg_match('/^\s*DROP\s+FUNCTION/i', $line) and !$in_string and !$in_function) {
+      $stack[] = 'drop_function';
+    }
+    if (preg_match('/^\s*DROP\s+VIEW/i', $line) and !$in_string and !$in_function) {
+      $stack[] = 'drop_view';
+    }
+    if (preg_match('/^\s*DROP\s+INDEX/i', $line) and !$in_string and !$in_function) {
+      $stack[] = 'drop_index';
+    }
+    if (preg_match('/^\s*DROP\s+SEQUENCE/i', $line) and !$in_string and !$in_function) {
+      $stack[] = 'drop_seq';
+    }
+    if (preg_match('/^\s*ALTER\s+TYPE\s+/i', $line) and !$in_string and !$in_function) {
+      $stack[] = 'alter_type';
+    }
+    if (preg_match('/^\s*ALTER\s+SEQUENCE\s+/i', $line) and !$in_string and !$in_function) {
+      $stack[] = 'alter_seq';
+    }
 
     // determine if we are in a string that spans a line
     $matches = preg_match_all("/[']/i", $line, $temp);
     $in_string = $in_string - ($matches % 2);
     $in_string = abs($in_string);
 
-    // if we've reached the end of an object the pop the stack
+    // if we've reached the end of an object then pop the stack
     if (strcmp($stack[sizeof($stack)-1], 'table') == 0 and preg_match('/\);\s*$/', $line)) {
       $type = array_pop($stack);
     }
-    if (strcmp($stack[sizeof($stack)-1], 'alter table') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
+    elseif (strcmp($stack[sizeof($stack)-1], 'alter_table') == 0 and preg_match('/;\s*$/', $line)) {
       $type = array_pop($stack);
     }
-    if (strcmp($stack[sizeof($stack)-1], 'set') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
+    elseif (strcmp($stack[sizeof($stack)-1], 'set') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
       $type = array_pop($stack);
     }
-    if (strcmp($stack[sizeof($stack)-1], 'schema') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
+    elseif (strcmp($stack[sizeof($stack)-1], 'schema') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
       $type = array_pop($stack);
     }
-    if (strcmp($stack[sizeof($stack)-1], 'sequence') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
+    elseif (strcmp($stack[sizeof($stack)-1], 'sequence') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
       $type = array_pop($stack);
     }
-    if (strcmp($stack[sizeof($stack)-1], 'view') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
+    elseif (strcmp($stack[sizeof($stack)-1], 'view') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
       $type = array_pop($stack);
     }
-    if (strcmp($stack[sizeof($stack)-1], 'comment') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
+    elseif (strcmp($stack[sizeof($stack)-1], 'comment') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
       $type = array_pop($stack);
     }
-    if (strcmp($stack[sizeof($stack)-1], 'function') == 0 and preg_match("/LANGUAGE.*?;\s+$/i", $line)) {
+    elseif (strcmp($stack[sizeof($stack)-1], 'function') == 0) {
+
+      if(preg_match('/LANGUAGE.*?;\s*$/i', $line)) {
+        $type = array_pop($stack);
+        $in_function = FALSE;
+        //print "FUNCTION DONE ($i): $line";
+      }
+      else if(preg_match('/\$_\$;\s*$/i', $line)) {
+        $type = array_pop($stack);
+        $in_function = FALSE;
+        //print "FUNCTION DONE ($i): $line";
+      }
+      else if(preg_match('/\$\$;\s*$/i', $line)) {
+        $type = array_pop($stack);
+        $in_function = FALSE;
+       // print "FUNCTION DONE ($i): $line";
+      }
+      else {
+       // print "FUNCTION ($i): $line";
+      }
+    }
+    elseif (strcmp($stack[sizeof($stack)-1], 'index') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
+      $type = array_pop($stack);
+    }
+    elseif (strcmp($stack[sizeof($stack)-1], 'insert') == 0 and preg_match('/\);\s*$/', $line)) {
+      $type = array_pop($stack);
+    }
+    elseif (strcmp($stack[sizeof($stack)-1], 'type') == 0 and preg_match('/\);\s*$/', $line)) {
       $type = array_pop($stack);
     }
-    if (strcmp($stack[sizeof($stack)-1], 'index') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
+    elseif (strcmp($stack[sizeof($stack)-1], 'grant') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
       $type = array_pop($stack);
     }
-    if (strcmp($stack[sizeof($stack)-1], 'insert') == 0 and preg_match('/\);\s*$/', $line)) {
+    elseif (strcmp($stack[sizeof($stack)-1], 'aggregate') == 0 and preg_match('/\);\s*$/', $line)) {
       $type = array_pop($stack);
     }
-    if (strcmp($stack[sizeof($stack)-1], 'type') == 0 and preg_match('/\);\s*$/', $line)) {
+    elseif (strcmp($stack[sizeof($stack)-1], 'drop_function') == 0 and preg_match('/;\s*$/i', $line)) {
       $type = array_pop($stack);
     }
-    if (strcmp($stack[sizeof($stack)-1], 'grant') == 0 and preg_match('/;\s*$/', $line) and !$in_string) {
+    elseif (strcmp($stack[sizeof($stack)-1], 'drop_view') == 0 and preg_match('/;\s*$/i', $line)) {
       $type = array_pop($stack);
     }
-    if (strcmp($stack[sizeof($stack)-1], 'aggregate') == 0 and preg_match('/\);\s*$/', $line)) {
+    elseif (strcmp($stack[sizeof($stack)-1], 'drop_index') == 0 and preg_match("/;\s*$/i", $line)) {
+      $type = array_pop($stack);
+    }
+    elseif (strcmp($stack[sizeof($stack)-1], 'drop_seq') == 0 and preg_match("/;\s*$/i", $line)) {
+      $type = array_pop($stack);
+    }
+    elseif (strcmp($stack[sizeof($stack)-1], 'alter_type') == 0 and preg_match('/;\s*$/i', $line)) {
+      $type = array_pop($stack);
+    }
+    elseif (strcmp($stack[sizeof($stack)-1], 'alter_seq') == 0 and preg_match('/;\s*$/i', $line)) {
       $type = array_pop($stack);
     }
     // if we're in a recognized SQL statement then let's keep track of lines
@@ -368,32 +763,31 @@ function tripal_core_install_sql($sql_file) {
       $query .= "$line";
     }
     else {
-      print "UNHANDLED $i, $in_string: $line";
-      tripal_core_chado_install_done();
-      return FALSE;
+      throw new Exception("UNHANDLED $i, $in_string: $line");
     }
-    if (preg_match_all("/\n/", $query, $temp) > 100) {
-      print "SQL query is too long.  Terminating:\n$query\n";
-      tripal_core_chado_install_done();
-      return FALSE;
+    if (preg_match_all("/\n/", $query, $temp) > 1000) {
+      throw new Exception("SQL query is too long.  Terminating:\n$query\n");
     }
     if ($type and sizeof($stack) == 0) {
       //print "Adding $type: line $i\n";
       // rewrite the set search_path to make 'public' be 'chado', but only if the
       // chado schema exists
       if (strcmp($type, 'set') == 0 and $chado_local) {
-        $query = preg_replace("/public/m", "chado", $query);
+        $query = preg_replace("/public/m", $chado_schema, $query);
       }
 
       // execute the statement
-      $result = db_query($query);
+      try {
+        $result = db_query($query);
+      }
+      catch (Exception $e) {
+        $error  = $e->getMessage();
+        throw new Exception("FAILED. Line  $i, $in_string\n$error:\n$query\n\n");
+      }
 
       if (!$result) {
         $error  = pg_last_error();
-        print "FAILED. Line  $i, $in_string\n$error:\n$query\n\n";
-        tripal_core_chado_install_done();
-        $success = 0;
-        return $success;
+        throw new Exception("FAILED. Line  $i, $in_string\n$error:\n$query\n\n");
       }
       $query = '';
     }
@@ -409,5 +803,6 @@ function tripal_core_install_sql($sql_file) {
  */
 function tripal_core_chado_install_done() {
 
-  db_query("set search_path to default");
+  $drupal_schema = tripal_get_schema_name('drupal');
+  db_query("set search_path to $drupal_schema");
 }

+ 1 - 1
tripal_core/includes/tripal_core.custom_tables.inc

@@ -328,7 +328,7 @@ function tripal_custom_tables_form_validate($form, &$form_state) {
         $results = db_query($sql, array(':table_id' => $table_id));
         $ct = $results->fetchObject();
         if ($ct->table_name != $schema_array['table']) {
-          $exists = db_table_exists('chado.' . $schema_array['table']);
+          $exists = chado_table_exists($schema_array['table']);
           if ($exists) {
             form_set_error($form_state['values']['schema'],
               t("The table name already exists, please choose a different name."));

+ 5 - 1
tripal_core/includes/tripal_core.jobs.inc

@@ -176,9 +176,12 @@ function tripal_jobs_report() {
     $start = tripal_get_job_start($job);
     $end = tripal_get_job_end($job);
     $cancel_link = '';
+    $execute_link = '';
     if ($job->start_time == 0 and $job->end_time == 0) {
       $cancel_link = "<a href=\"" . url("admin/tripal/tripal_jobs/cancel/" . $job->job_id) . "\">Cancel</a><br />";
+      $execute_link = "<a href=\"" . url("admin/tripal/tripal_jobs/execute/" . $job->job_id) . "\">Execute</a><br />";
     }
+
     $rerun_link = "<a href=\"" . url("admin/tripal/tripal_jobs/rerun/" . $job->job_id) . "\">Re-run</a><br />";
     $view_link ="<a href=\"" . url("admin/tripal/tripal_jobs/view/" . $job->job_id) . "\">View</a>";
     $rows[] = array(
@@ -189,7 +192,7 @@ function tripal_jobs_report() {
       $job->priority,
       $job->progress . '%',
       $job->job_status,
-      "$cancel_link $rerun_link $view_link",
+      "$execute_link $cancel_link $rerun_link $view_link",
     );
   }
 
@@ -287,6 +290,7 @@ function tripal_jobs_view($job_id) {
   $links .= l('Re-run this job', "admin/tripal/tripal_jobs/rerun/" . $job->job_id) . ' | ';
   if ($job->start_time == 0 and $job->end_time == 0) {
     $links .= l('Cancel this job', "admin/tripal/tripal_jobs/cancel/" . $job->job_id) . ' | ';
+    $links .= l('Execute this job', "admin/tripal/tripal_jobs/execute/".$job->job_id);
   }
 
   // make our start and end times more legible

+ 439 - 0
tripal_core/includes/tripal_core.search.inc

@@ -0,0 +1,439 @@
+<?php
+/**
+ * @file
+ * Adds support for Drupal indexing of Chado.
+ * It's important to note that not all of Chado is indexed but instead
+ * Only fields indicated in hook_search_include_chado_fields().
+ */
+
+/**
+ * Implements hook_search_include_chado_fields().
+ *
+ * This hook allows Tripal Admin/modules to specify which chado fields should be indexed
+ * for searching in a simple manner.
+ *
+ * @return
+ *   An array of chado fields you would like available for indexing. Each element should
+ *   be the name of the table followed by the field and separated by a period. For example.
+ *   feature.uniquename to indicate the uniquename field from the feature table.
+ */
+function tripal_core_search_include_chado_fields() {
+  return array(
+    'organism.genus',
+    'organism.species',
+  );
+}
+
+/**
+ * Implements hook_entity_property_info_alter().
+ *
+ * This is where we actually add the properties to the node entity in order to indicate
+ * which chado fields should be indexed.
+ */
+function tripal_core_entity_property_info_alter(&$info) {
+
+  // We provide a hook to allow Tripal admin to easily add fields to the search api.
+  // We want to invoke all implementations of that hook now for use below.
+  $fields_to_include = module_invoke_all('search_include_chado_fields');
+  $fields_to_include = array_unique($fields_to_include);
+
+  // Retrieve information for all nodes.
+  // We focus on nodes at this point because we need to link search results back to
+  // the entity and we have no entites for non-node chado content in Tripal2.
+  $node_info = module_invoke_all('node_info');
+
+  foreach ($node_info as $n) {
+
+    // Now keep in mind this hook is defined for ALL THE NODE TYPES and we only want
+    // to add extra support for chado so we onle care about chado node types.
+    // We can distinguish chado node types from all others by the existence of
+    // the 'chado_node_api' key which is used for all sorts of beautiful tripal/chado
+    // node integration (ie: adding properties, relationships and dbxrefs to node forms).
+    if (isset($n['chado_node_api'])) {
+      $schema = chado_get_schema($n['chado_node_api']['base_table']);
+
+      // Now we are going to start by adding some defaults. It feels safe to say, we
+      // probably want to index all the "names" so we are going to look through
+      // all the fields and if they contain "name" we are going to add them automatically.
+      foreach ($schema['fields'] as $field_name => $details) {
+
+        $machine_name = $n['chado_node_api']['base_table'] . '.' . $field_name;
+
+        // Try to create a readable label.
+        $label = ucwords(str_replace(array('.','_'),' ',$machine_name));
+
+        // We want to add all name fields and any fields previously indicated to be indexed.
+        if (preg_match('/name/', $field_name) OR in_array($machine_name, $fields_to_include)) {
+
+          if (!isset($info['node']['bundles'][ $n['base'] ]['properties'][$machine_name])) {
+            $info['node']['bundles'][ $n['base'] ]['properties'][$machine_name] = array(
+              'label' => $label,
+              'description' => (isset($details['description'])) ? $details['description'] : '',
+              'type' => ($details['type'] == 'varchar') ? 'text' : $details['type'],
+              'schema field' => '[' . $machine_name . ']',
+              // The following getter callback is a generic function that can retrieve
+              // values for any chado field.
+              'getter callback' => 'tripal_search_chado_token_getter_callback'
+            );
+          }
+        }
+      }
+
+      // We want to add any base foreign keys. This allows you to search for all features
+      // from a given organism. Furthermore, we want to add a single field for each foreign
+      // key that will span content types in order to be exposed as facets.
+      foreach ($schema['foreign keys'] as $table => $fk_details) {
+        foreach ($fk_details['columns'] as $left_field => $right_field) {
+
+          $machine_name = $n['chado_node_api']['base_table'] . '.' . $left_field;
+          $field_details = $schema['fields'][$left_field];
+
+          // Try to create a readable label.
+          $label = $table . ' (' . $machine_name . ')';
+          if (preg_match('/(\w+)_id/',$left_field,$matches)) {
+            // Key only field.
+            $key_label = ucwords(str_replace('_', ' ', $matches[1]));
+
+            // Expanded field.
+            $label = str_replace('_', ' ', $n['chado_node_api']['base_table']);
+            $label .= ' ' . str_replace('_', ' ', $matches[1]);
+            $label = ucwords($label);
+          }
+
+          $keytoken = '[BASE.' . $left_field . '>' . $table . '.' . $right_field . ']';
+          $format = chado_node_get_readable_format($keytoken);
+
+          // First, create the key version. This is best used for facets since it
+          // won't/can't be tokenized along with the other fields. This will be shared
+          // among node types to facillitate use as a facet.
+          $info['node']['properties'][$table . '.' . $right_field .' key'] = array(
+            'label' => $key_label . ' (All Content Types)',
+            'description' => (isset($field_details['description'])) ? $field_details['description'] : '',
+            'type' => 'text',
+            // We include both the token for the current node type and the token for
+            // the parent table. That way the organism node will appear in the results
+            // for the organism key.
+            'schema field' => $format,
+            // The following getter callback is a generic function that can retrieve
+            // values for any chado foreign key.
+            'getter callback' => 'tripal_search_chado_token_across_nodetypes_getter_callback'
+          );
+
+          $pretoken = '[' . $n['chado_node_api']['base_table'] . '.' . $left_field . '>' . $table . '.' . $right_field . ']';
+          $format = chado_node_get_readable_format($pretoken);
+
+          // Add a more readable version that will be tokenized so users can
+          // search for fruitfly and get all features with that as an organism.
+          $info['node']['bundles'][ $n['base'] ]['properties'][$machine_name .' expanded'] = array(
+            'label' => $label . ' (Expanded)',
+            'description' => (isset($field_details['description'])) ? $field_details['description'] : '',
+            'type' => 'text',
+            'schema field' => $format,
+            // The following getter callback is a generic function that can retrieve
+            // values for any chado foreign key.
+            'getter callback' => 'tripal_search_chado_token_getter_callback'
+          );
+        }
+      }
+    }
+  }
+
+  // Provide our own hook for altering properties to make it easier for our users.
+  drupal_alter('tripal_search_properties', $info);
+}
+
+/**
+ * Allows tripal admin to alter entity property information after it has. This is currently
+ * being used to indicate chado fields to be indexed for search.
+ *
+ * NOTE: If you simply need to add a field to be indexed, use hook_search_include_chado_fields()
+ * which provides the much easier method of simply listing fields to include.
+ *
+ * This function is most useful if you want to change the way the value is retrieved
+ * (done by changing the 'getter callback') or add your own custom computed field.
+ */
+function hook_tripal_search_properties_alter(&$info) { }
+
+/**
+ * Implements a getter callback for chado token formats.
+ *
+ * A chado token format is a string containing chado tokens.
+ *
+ * Chado tokens are expected to follow the format of tokens auto-generated using
+ *   chado_node_generate_tokens(). For example, [feature.uniquename] indicates you
+ *   should return the uniquename of a feature node and [feature.organism_id>organism.species]
+ *   indicates you should return the organism genus of the feature node.
+ *
+ * The chado token format must be stored in the 'schema field' when defining the property in
+ *  hook_entity_property_info() in order for this getter to work.
+ *
+ * @param $data
+ *   The entity object (in our case the node we need to retrieve feature properties for).
+ * @param $options
+ * @param $field_name
+ *   The machine name for the entity property.
+ * @param $info
+ *   The full property definition from entity property info.
+ *
+ * @return
+ *   A string representing the "value" of the field.
+ */
+function tripal_search_chado_token_getter_callback($data, $options, $field_name, $type, $info) {
+
+  if (isset($data->nid)) {
+    if (isset($info['schema field'])) {
+      $format = $info['schema field'];
+
+      // Determine our base table so we know if this is even the right node type.
+      if (preg_match('/\[(\w+)\.(\w+)/',$format, $matches)) {
+        $base_table = $matches[1];
+        $field_name = $matches[2];
+
+        // For some weird reason nodes of all types are trying to get a value for fields
+        // that we defined as specific to a given node type (ie: bundle). As such we need
+        // this check here to ensure this field is actually for this node type.
+        if (!isset($data->{$base_table})) return NULL;
+
+        $format = tripal_core_get_token_value_for_property($base_table, $field_name, $format, $data, $info);
+        return $format;
+      }
+      else {
+        // Not able to determine table?
+        tripal_report_error(
+          'tripal_search',
+          TRIPAL_ERROR,
+          'Unable to extract the base table from the format (:format) for :field because it didn\'t match the expected format: [tablename.field...',
+          array(':field' => $field_name, ':format' => $format)
+        );
+        return NULL;
+      }
+    }
+    else {
+      tripal_report_error(
+        'tripal_search',
+        TRIPAL_ERROR,
+        'Unable to get value for :field because the schema field was not set.',
+        array(':field' => $field_name)
+      );
+      return NULL;
+    }
+  }
+}
+
+/**
+ * Implements a getter callback for foreign keys collon between content types.
+ *
+ * @param $data
+ *   The entity object (in our case the node we need to retrieve feature properties for).
+ * @param $options
+ * @param $field_name
+ *   The machine name for the entity property.
+ * @param $info
+ *   The full property definition from entity property info.
+ *
+ * @return
+ *   A string representing the "value" of the field.
+ */
+function tripal_search_chado_token_across_nodetypes_getter_callback($data, $options, $field_name, $type, $info) {
+
+  // First, make sure this is a chado node.
+  // Assumption #1: All chado node types are prefixed with chado_
+  if (isset($data->nid)) {
+    if (preg_match('/^chado_(\w+)/',$data->type,$matches)) {
+      if (isset($info['schema field'])) {
+
+        // Assumption #2: The base table is the suffix of the node type.
+        $base_table = $matches[1];
+
+        // Substitute in the  base table for "BASE" in the schema field.
+        $format = str_replace('BASE', $base_table, $info['schema field']);
+
+        // Replace all tokens for values and return the result.
+        $format = tripal_core_get_token_value_for_property($base_table, $field_name, $format, $data, $info);
+        return $format;
+      }
+      else {
+        // Not able to determine table?
+        tripal_report_error(
+          'tripal_search',
+          TRIPAL_ERROR,
+          'Unable to extract the base table from the format (:format) for :field because it didn\'t match the expected format: [tablename.field...',
+          array(':field' => $field_name, ':format' => $format)
+        );
+      }
+    }
+    else {
+      tripal_report_error(
+        'tripal_search',
+        TRIPAL_ERROR,
+        'Unable to get value for :field because the schema field was not set.',
+        array(':field' => $field_name)
+      );
+    }
+  }
+
+  return NULL;
+}
+
+/**
+ * Retrieve values for all tokens for an entity property getter function.
+ */
+function tripal_core_get_token_value_for_property($base_table, $field_name, $format, $data, $info) {
+
+  // Determine which tokens were used in the format string
+  if (preg_match_all('/\[[^]]+\]/', $format, $used_tokens)) {
+    $used_tokens = $used_tokens[0];
+
+    // If there are no tokens then return the format as is...
+    if (empty($used_tokens)) {
+      tripal_report_error(
+        'tripal_search',
+        TRIPAL_NOTICE,
+        'Returned static text for :field since there were no tokens in the supplied format: :format',
+        array(':field' => $field_name, ':format' => $format)
+      );
+      return $format;
+    }
+
+    // Get the value of each token.
+    $null_tokens = array();
+    foreach ($used_tokens as $token) {
+      $token_info = array(
+          'name' => $info['label'],
+          'table' => $base_table,
+          'field' => $field_name,
+          'token' => $token,
+          'description' => $info['description'],
+          'location' => chado_node_get_location_from_token($token),
+      );
+
+      $value = chado_get_token_value($token_info, $data, array('supress_errors' => TRUE));
+      if (empty($value)) $null_tokens[] = $token;
+
+      // And sub it in to the format.
+      $format = str_replace($token, $value, $format);
+    }
+
+    // If none of the tokens had values then this node doesn't have this field.
+    // As such we return null so the search api doesn't bother indexing an empty format.
+    if (sizeof($used_tokens) == sizeof($null_tokens)) return NULL;
+  }
+  else {
+    tripal_report_error(
+      'tripal_search',
+      TRIPAL_NOTICE,
+      'Returned static text for :field since there were no tokens of a recognized format in the supplied format: :format',
+      array(':field' => $field_name, ':format' => $format)
+    );
+  }
+
+  return $format;
+}
+
+/**
+ * Implements hook_modules_enabled().
+ *
+ * This hook is called when ANY module is enabled. This allows us to update the
+ * the search api "Default node index" when any Tripal module is enabled thus allowing us
+ * to catch new node types right after they're created.
+ */
+function tripal_core_modules_enabled($modules) {
+  if (module_exists('search_api')) {
+    $index_enabled = db_query('SELECT enabled FROM search_api_index WHERE machine_name=:name', array(':name' => 'default_node_index'))->fetchField();
+    if ($index_enabled) {
+      tripal_search_update_default_index();
+    }
+  }
+}
+
+/**
+ * The Search API provides a default node index which has a number of
+ * node-specific fields enabled by default. We want to ensure our
+ * chado fields are also enabled by default thus making for easier
+ * enabling of Tripal search.
+ *
+ * This function should be called whenever new nodes might have been
+ * added to ensure that their fields are added as well.
+ *
+ * We should only modify the default node index if it has no database service yet.
+ * That way we ensure we don't override user changes!
+ */
+function tripal_search_update_default_index() {
+
+  // First we need the index object for the "Default node index".
+  $index_id = db_query('SELECT id FROM search_api_index WHERE machine_name=:name',
+    array(':name' => 'default_node_index'))->fetchField();
+  if (!$index_id) {
+    // ERROR
+    return FALSE;
+  }
+  $index = search_api_index_load($index_id);
+
+  // Collect all the fields already added to the search index.
+  $changes = array('options' => $index->options);
+
+  // Now we only want to update the index if it's both enabled and has no server indicated.
+  // That way we can be reasonably sure that it was been untouched by admin users.
+  if ($index->enabled == FALSE AND $index->server == NULL) {
+
+    // We need information about all the fields available to nodes before we can
+    // go crazy enabling them... That information is stored as properties of nodes
+    // so we'll grab that.
+    $info = entity_get_property_info('node');
+
+    // Now we want to loop through each node type and add all the properties for the
+    // chado node types.
+    // Assumption #1: We are assuming that all chado node types are prefixed 'chado_'.
+    foreach ($info['bundles'] as $node_type => $details) {
+      if (preg_match('/^chado_/', $node_type)) {
+
+        // Now add each chado fields to the index but only if they are not already added.
+        foreach ($details['properties'] as $field_name => $field_details) {
+          if (!isset($changes['options']['fields'][$field_name])) {
+            $changes['options']['fields'][$field_name]['type'] = ($field_details['type'] == 'varchar') ? 'text' : $field_details['type'];
+
+            // Furthermore if this is a name then we want to add a boost to ensure it carries
+            // more weight in the search results.
+            if (preg_match('/name/',$field_name)) {
+              $changes['options']['fields'][$field_name]['boost'] = '3.0';
+            }
+          }
+        }
+
+      }
+    }
+
+    // We also want to enable highlighting to ensure an excerpt is generated since this
+    // will be used in the default search view distributed with Tripal.
+    if (!isset($index->options['processors']['search_api_highlighting'])) {
+      $changes['options']['processors']['search_api_highlighting'] = array(
+        'status' => 1,
+        'weight' => 35,
+        'settings' => array(
+          'prefix' => '<strong>',
+          'suffix' => '</strong>',
+          'excerpt' => 1,
+          'excerpt_length' => 256,
+          'exclude_fields' => array(),
+          'highlight' => 'always',
+        ),
+      );
+    }
+    else {
+      $changes['options']['processors']['search_api_highlighting']['status'] = 1;
+      $changes['options']['processors']['search_api_highlighting']['settings']['excerpt'] = 1;
+    }
+
+    // Finally we save all of our changes :-).
+    search_api_index_edit($index_id, $changes);
+    drupal_set_message('The Search API "Default Node Index" was updated.');
+  }
+  else {
+    tripal_report_error(
+      'tripal_search',
+      TRIPAL_NOTICE,
+      'The Search API "Default Node Index" was not updated with Tripal Fields. If you would like to enable more Tripal/Chado fields to be indexed, edit the Field Listing for the "Default Node Index" now.'
+    );
+  }
+}
+

+ 27 - 6
tripal_core/includes/tripal_core.toc.inc

@@ -307,10 +307,11 @@ function tripal_core_node_view_build_toc(&$build) {
 
 
       // For backwards compatibility we will handle the content type fields
-      // named 'field_resource_blocks', 'field_resource_titles', and 'field_resource_links'
-      // these fields can be added on the Drupal content types page and were
-      // specifically recoginzed by Tripal v1.1.  If the mode type is "manage_type"
-      // then remove these content panes because they are node specific.
+      // named 'field_resource_blocks', 'field_resource_titles', and
+      // 'field_resource_links' these fields can be added on the Drupal content
+      // types page and were specifically recoginzed by Tripal v1.1.  If the
+      // mode type is "manage_type" then remove these content panes because
+      // they are node specific.
       if ($mode == "manage_type" and (
           $key == "field_resource_links" or
           $key == "field_resource_titles" or
@@ -337,6 +338,24 @@ function tripal_core_node_view_build_toc(&$build) {
             continue;
           }
 
+          // This field supports tokens, so we need to perform the substitutions
+          // if one is needed. Get the tokens and format
+          $base_table = preg_replace('/^chado_(.*)$/', '\1', $node_type);
+          $tokens = chado_node_generate_tokens($base_table);
+          $markup = $element['#markup'];
+          // Determine which tokens were used in the format string
+          if (preg_match_all('/\[[^]]+\]/', $markup, $used_tokens)) {
+            // Get the value for each token used
+            foreach ($used_tokens[0] as $token) {
+              $token_info = $tokens[$token];
+              if (!empty($token_info)) {
+                $value = chado_get_token_value($token_info, $node);
+                $markup = str_replace($token, $value, $markup);
+              }
+            }
+            $element['#markup'] = $markup;
+          }
+
           // Add the link to the TOC
           $parts = explode("|", $element['#markup']);
           if (count($parts) == 2) {
@@ -635,7 +654,8 @@ function tripal_core_content_type_toc_form($form, &$form_state, $content_type) {
 
   $form["#tree"] = TRUE;
 
-  // Get a single node of this type so we can get all the possible content for it
+  // Get a single node of this type so we can get all the possible content
+  // for it.
   $sql = "SELECT nid FROM {node} WHERE type = :type LIMIT 1 OFFSET 0";
   $nid = db_query($sql, array(':type' => $content_type))->fetchField();
   if (!$nid) {
@@ -794,4 +814,5 @@ function tripal_core_content_type_toc_form_submit($form, &$form_state) {
       drupal_set_message("Failed to apply TOC changes.", "error");
     }
   }
-}
+}
+

+ 2 - 3
tripal_core/tripal_core.info

@@ -3,7 +3,7 @@ description = Provides support for all Tripal modules and includes the Tripal AP
 core = 7.x
 project = tripal
 package = Tripal
-version = 7.x-2.1-beta2
+version = 7.x-2.1
 configure = admin/tripal
 
 stylesheets[all][] = theme/css/tripal.css
@@ -11,5 +11,4 @@ scripts[]          = theme/js/tripal.js
 
 dependencies[]     = views
 dependencies[]     = path
-dependencies[]     = search
-dependencies[]     = php
+dependencies[]     = php

+ 177 - 4
tripal_core/tripal_core.module

@@ -22,6 +22,7 @@ require_once 'includes/tripal_core.mviews.inc';
 require_once 'includes/tripal_core.custom_tables.inc';
 require_once 'includes/tripal_core.chado_install.inc';
 require_once 'includes/tripal_core.form_elements.inc';
+require_once 'includes/tripal_core.search.inc';
 
 // Set some global variables.
 tripal_core_set_globals();
@@ -80,11 +81,9 @@ function tripal_core_init() {
   }
 
   // add some variables for all javasript to use for building URLs
-  $theme_dir = drupal_get_path('theme', 'tripal');
   $clean_urls = variable_get('clean_url', 0);
   drupal_add_js(
     " var baseurl  = '$base_url';
-      var themedir = '$theme_dir';
       var isClean  =  $clean_urls;",
     'inline', 'header');
 
@@ -212,6 +211,16 @@ function tripal_core_menu() {
     'access arguments' => array('administer tripal'),
     'type' => MENU_CALLBACK,
   );
+
+  $items['admin/tripal/tripal_jobs/execute/%'] = array(
+    'title' => 'Jobs',
+    'description' => t('Execute an existing job'),
+    'page callback' => 'tripal_execute_job',
+    'page arguments' => array(4),
+    'access arguments' => array('administer tripal'),
+    'type' => MENU_CALLBACK,
+  );
+
   $items['admin/tripal/tripal_jobs/rerun/%'] = array(
     'title' => 'Jobs',
     'description' => t('Re-run an existing job.'),
@@ -528,7 +537,7 @@ function tripal_core_theme($existing, $type, $theme, $path) {
 
 /**
  * Implements hook_job_describe_args().
- * Describes the arguements for the tripal_populate_mview job to allow for greater
+ * Describes the arguments for the tripal_populate_mview job to allow for greater
  * readability in the jobs details pages.
  *
  * @param $callback
@@ -655,6 +664,46 @@ function tripal_core_exclude_type_by_default() {
   return array('text' => 'strlen("<field_value> ") > 250');
 }
 
+/**
+ * Adds support for tokens in the field_resource_links field.
+ *
+ * The field_resource_links field is a special field that can be manually
+ * added by the site admin for providing links on the Tripal TOC sidebar.
+ * Using tokens will allow for creation of custom links. This function
+ * will add a fieldset contiaining the list of appropriate tokens for the
+ * content type.
+ *
+ * @param unknown $element
+ * @param unknown $form_state
+ * @param unknown $context
+ */
+function tripal_core_field_widget_form_alter(&$element, &$form_state, $context) {
+
+  // If the name of the field is 'field_resource_links' then we want to
+  // add a fieldset of tokens.
+  if (isset($element['#field_name']) AND $element['#field_name'] == 'field_resource_links') {
+
+    // Add the tokens fieldset to the last element.
+    $num_elements = count($context['items']);
+    if ($num_elements == $element['#delta']) {
+      $bundle = $element['#bundle'];
+      $base_table = preg_replace('/^chado_(.*)$/', '\1', $bundle);
+      $tokens = chado_node_generate_tokens($base_table);
+      $token_list = chado_node_format_tokens($tokens);
+      $element['tokens'] = array(
+        '#type' => 'fieldset',
+        '#title' => 'Available tokens',
+        '#collapsible' => TRUE,
+        '#collapsed' => TRUE,
+        '#weight' => 100
+      );
+      $element['tokens']['tokens_table'] = array(
+        '#type' => 'item',
+        '#markup' => $token_list
+      );
+    }
+  }
+}
 
 /**
  * Imports all of the Tripal API into scope.
@@ -689,6 +738,130 @@ function tripal_core_import_api() {
   module_load_include('inc', 'tripal_core', 'api/tripal_core.mviews.api');
   module_load_include('inc', 'tripal_core', 'api/tripal_core.schema_v1.11.api');
   module_load_include('inc', 'tripal_core', 'api/tripal_core.schema_v1.2.api');
+  module_load_include('inc', 'tripal_core', 'api/tripal_core.schema_v1.3.api');
   module_load_include('inc', 'tripal_core', 'api/tripal_core.tripal_variables.api');
   module_load_include('inc', 'tripal_core', 'api/tripal_core.tripal.api');
-}
+}
+
+/**
+ * Implements hook_block_info().
+ */
+function tripal_core_block_info() {
+
+  $blocks['tripal_search'] = array(
+    'info' => t('Tripal Search Block'),
+    'cache' => DRUPAL_NO_CACHE,
+  );
+
+  return $blocks;
+}
+
+/**
+ * Implements hook_block_view().
+ */
+function tripal_core_block_view($delta = '') {
+  $block = array();
+
+  switch ($delta) {
+    case 'tripal_search':
+      $block['title'] = 'Search';
+
+      $form_render_arr = drupal_get_form('tripal_core_search_block');
+      $block['content'] = array(
+        '#markup' => drupal_render($form_render_arr),
+      );
+      break;
+  }
+
+  return $block;
+}
+
+/**
+ * A simple search box form.
+ */
+function tripal_core_search_block($form, $form_state) {
+
+  $form['wrapper'] = array(
+    '#prefix' => '<div id="search-block-form" class="container-inline">',
+    '#suffix' => '</div>',
+  );
+
+  $form['wrapper']['title'] = array(
+    '#markup' => '<h2 class="element-invisible">Search form</h2>',
+  );
+
+  $form['wrapper']['search_block_form'] = array(
+    '#title' => 'Search',
+    '#title_display' => 'invisible',
+    '#type' => 'textfield',
+    '#size' => 15,
+    '#maxlength' => 128,
+    '#attributes' =>array('placeholder' => t(variable_get('tripal_search_placeholder', 'Keywords')))
+  );
+
+  $form['wrapper']['submit'] = array(
+    '#type' => 'submit',
+    '#value' => 'Search',
+    '#prefix' => '<div class="form-actions form-wrapper" id="edit-actions">',
+    '#suffix' => '</div>'
+  );
+
+  return $form;
+}
+
+/**
+ * Submit for tripal_core_search_block form.
+ */
+function tripal_core_search_block_submit($form, &$form_state) {
+
+  $form_state['redirect'] = array(
+    variable_get('tripal_search_block_url', 'search/data'),
+    array(
+      'query' => array(
+        'keywords' => $form_state['values']['search_block_form']
+      ),
+    ),
+  );
+
+}
+
+/**
+ * Implements hook_block_configure().
+ */
+function tripal_core_block_configure ($delta = '') {
+  $form = array();
+
+  $form['search_url'] = array(
+    '#type' => 'textfield',
+    '#title' => 'Search Page URL',
+    '#description' => 'The URL for the page you would like to redirect to when the user
+        clicks "Search". It is expected that this page will be a view with an exposed
+        filter having a "Filter Identifier" (in "More" fieldset on the edit filter form)
+        of "keywords".',
+    '#default_value' => variable_get('tripal_search_block_url', 'search/data'),
+  );
+
+  $form['search_placeholder'] = array(
+    '#type' => 'textfield',
+    '#title' => 'Placeholder Text',
+    '#description' => 'Change the text that shows up within the search box until the user enters any of their own text.',
+    '#default_value' => variable_get('tripal_search_placeholder', 'Keywords'),
+  );
+
+  return $form;
+}
+
+/**
+ * Implements hook_block_save().
+ */
+function tripal_core_block_save($delta = '', $edit = array()) {
+
+  // We simply want to save this information in a Drupal variable for use in the form submit.
+  if (!empty($edit['search_url'])) {
+    variable_set('tripal_search_block_url', $edit['search_url']);
+  }
+
+  if (!empty($edit['search_placeholder'])) {
+    variable_set('tripal_search_placeholder', $edit['search_placeholder']);
+  }
+}

+ 2 - 2
tripal_core/tripal_core.views.inc

@@ -134,8 +134,8 @@ function tripal_core_views_data_jobs($data) {
 
   // Arguments
   $data['tripal_jobs']['arguments'] = array(
-    'title' => t('Arguements'),
-    'help' => t('Any arguements passed to the callback.'),
+    'title' => t('arguments'),
+    'help' => t('Any arguments passed to the callback.'),
     'field' => array(
       'handler' => 'views_handler_field',
       'click sortable' => TRUE, // This is use by the table display plugin.

+ 100 - 4
tripal_core/tripal_core.views_default.inc

@@ -21,6 +21,16 @@ function tripal_core_views_default_views() {
   $view = tripal_core_admin_defaultview_mviews();
   $views[$view->name] = $view;
 
+  // We only want to make this view available if the Search API module is installed
+  // and the "Default Node Index has been enabled.
+  if (module_exists('search_api')) {
+    $index_enabled = db_query('SELECT enabled FROM search_api_index WHERE machine_name=:name', array(':name' => 'default_node_index'))->fetchField();
+    if ($index_enabled) {
+      $view = tripal_core_search_default_node_index();
+      $views[$view->name] = $view;
+    }
+  }
+
   return $views;
 }
 
@@ -235,12 +245,20 @@ function tripal_core_admin_defaultview_jobs() {
   $handler->display->display_options['fields']['nothing_3']['alter']['make_link'] = TRUE;
   $handler->display->display_options['fields']['nothing_3']['alter']['path'] = 'admin/tripal/tripal_jobs/cancel/[job_id]';
   /* Field: Global: Custom text */
+  $handler->display->display_options['fields']['nothing_4']['id'] = 'nothing_4';
+  $handler->display->display_options['fields']['nothing_4']['table'] = 'views';
+  $handler->display->display_options['fields']['nothing_4']['field'] = 'nothing';
+  $handler->display->display_options['fields']['nothing_4']['label'] = 'Execute link';
+  $handler->display->display_options['fields']['nothing_4']['exclude'] = TRUE;
+  $handler->display->display_options['fields']['nothing_4']['alter']['text'] = 'Execute';
+  $handler->display->display_options['fields']['nothing_4']['alter']['make_link'] = TRUE;
+  $handler->display->display_options['fields']['nothing_4']['alter']['path'] = 'admin/tripal/tripal_jobs/execute/[job_id]';
+  /* Field: Global: Custom text */
   $handler->display->display_options['fields']['nothing_1']['id'] = 'nothing_1';
   $handler->display->display_options['fields']['nothing_1']['table'] = 'views';
   $handler->display->display_options['fields']['nothing_1']['field'] = 'nothing';
   $handler->display->display_options['fields']['nothing_1']['label'] = 'Action';
-  $handler->display->display_options['fields']['nothing_1']['alter']['text'] = '[nothing_2]<br />
-  [nothing_3]';
+  $handler->display->display_options['fields']['nothing_1']['alter']['text'] = '[nothing_4]<br />[nothing_2]<br />[nothing_3]';
   $handler->display->display_options['fields']['nothing_1']['element_class'] = 'short-column';
   $handler->display->display_options['fields']['nothing_1']['element_label_class'] = 'short-column';
   /* Filter criterion: Tripal Jobs: Job Name */
@@ -317,7 +335,7 @@ function tripal_core_admin_defaultview_custom_tables() {
   $view->core = 7;
   $view->api_version = '3.0';
   $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
-  
+
   /* Display: Master */
   $handler = $view->new_display('default', 'Master', 'default');
   $handler->display->display_options['title'] = 'Custom Tables';
@@ -416,7 +434,7 @@ function tripal_core_admin_defaultview_custom_tables() {
     1 => 0,
     3 => 0,
   );
-  
+
   /* Display: Page */
   $handler = $view->new_display('page', 'Page', 'page');
   $handler->display->display_options['path'] = 'admin/tripal/schema/custom_tables/tables';
@@ -698,3 +716,81 @@ function tripal_core_admin_defaultview_mviews() {
 
   return $view;
 }
+
+/**
+ * Provides a default search view for the Search API "Default Node Index".
+ */
+function tripal_core_search_default_node_index() {
+
+  $view = new view();
+  $view->name = 'search_api_default_node_search';
+  $view->description = 'A default keyword-based search view using the search API "Default node index".';
+  $view->tag = 'search';
+  $view->base_table = 'search_api_index_default_node_index';
+  $view->human_name = 'Search';
+  $view->core = 7;
+  $view->api_version = '3.0';
+  $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
+
+  /* Display: Master */
+  $handler = $view->new_display('default', 'Master', 'default');
+  $handler->display->display_options['title'] = 'Search';
+  $handler->display->display_options['use_more_always'] = FALSE;
+  $handler->display->display_options['access']['type'] = 'none';
+  $handler->display->display_options['cache']['type'] = 'none';
+  $handler->display->display_options['query']['type'] = 'views_query';
+  $handler->display->display_options['exposed_form']['type'] = 'input_required';
+  $handler->display->display_options['exposed_form']['options']['submit_button'] = 'Search';
+  $handler->display->display_options['exposed_form']['options']['expose_sort_order'] = FALSE;
+  $handler->display->display_options['exposed_form']['options']['text_input_required'] = '';
+  $handler->display->display_options['exposed_form']['options']['text_input_required_format'] = 'filtered_html';
+  $handler->display->display_options['pager']['type'] = 'full';
+  $handler->display->display_options['pager']['options']['items_per_page'] = '25';
+  $handler->display->display_options['pager']['options']['offset'] = '0';
+  $handler->display->display_options['pager']['options']['id'] = '0';
+  $handler->display->display_options['pager']['options']['quantity'] = '9';
+  $handler->display->display_options['style_plugin'] = 'default';
+  $handler->display->display_options['row_plugin'] = 'fields';
+  /* Field: Content: Rendered Node */
+  $handler->display->display_options['fields']['rendered_entity']['id'] = 'rendered_entity';
+  $handler->display->display_options['fields']['rendered_entity']['table'] = 'views_entity_node';
+  $handler->display->display_options['fields']['rendered_entity']['field'] = 'rendered_entity';
+  $handler->display->display_options['fields']['rendered_entity']['label'] = '';
+  $handler->display->display_options['fields']['rendered_entity']['element_label_colon'] = FALSE;
+  $handler->display->display_options['fields']['rendered_entity']['link_to_entity'] = 1;
+  $handler->display->display_options['fields']['rendered_entity']['display'] = 'view';
+  $handler->display->display_options['fields']['rendered_entity']['view_mode'] = 'teaser';
+  $handler->display->display_options['fields']['rendered_entity']['bypass_access'] = 0;
+  /* Sort criterion: Search: Relevance */
+  $handler->display->display_options['sorts']['search_api_relevance']['id'] = 'search_api_relevance';
+  $handler->display->display_options['sorts']['search_api_relevance']['table'] = 'search_api_index_default_node_index';
+  $handler->display->display_options['sorts']['search_api_relevance']['field'] = 'search_api_relevance';
+  $handler->display->display_options['sorts']['search_api_relevance']['order'] = 'DESC';
+  /* Filter criterion: Search: Fulltext search */
+  $handler->display->display_options['filters']['search_api_views_fulltext']['id'] = 'search_api_views_fulltext';
+  $handler->display->display_options['filters']['search_api_views_fulltext']['table'] = 'search_api_index_default_node_index';
+  $handler->display->display_options['filters']['search_api_views_fulltext']['field'] = 'search_api_views_fulltext';
+  $handler->display->display_options['filters']['search_api_views_fulltext']['operator'] = 'OR';
+  $handler->display->display_options['filters']['search_api_views_fulltext']['exposed'] = TRUE;
+  $handler->display->display_options['filters']['search_api_views_fulltext']['expose']['operator_id'] = 'search_api_views_fulltext_op';
+  $handler->display->display_options['filters']['search_api_views_fulltext']['expose']['label'] = 'Keywords';
+  $handler->display->display_options['filters']['search_api_views_fulltext']['expose']['operator'] = 'search_api_views_fulltext_op';
+  $handler->display->display_options['filters']['search_api_views_fulltext']['expose']['identifier'] = 'keywords';
+  $handler->display->display_options['filters']['search_api_views_fulltext']['expose']['remember_roles'] = array(
+    2 => '2',
+    1 => 0,
+    3 => 0,
+  );
+
+  /* Display: Page */
+  $handler = $view->new_display('page', 'Page', 'page');
+  $handler->display->display_options['path'] = 'chado';
+  $handler->display->display_options['menu']['type'] = 'normal';
+  $handler->display->display_options['menu']['title'] = 'Search';
+  $handler->display->display_options['menu']['description'] = 'General keyword search of all content.';
+  $handler->display->display_options['menu']['weight'] = '0';
+  $handler->display->display_options['menu']['context'] = 0;
+  $handler->display->display_options['menu']['context_only_inline'] = 0;
+
+  return $view;
+}

+ 259 - 204
tripal_cv/api/tripal_cv.api.inc

@@ -128,30 +128,31 @@ function tripal_get_cv_select_options() {
  * Retrieves a chado controlled vocabulary term variable
  *
  * @param $identifier
- *   An array with the key stating what the identifier is. Supported keys (only one of the
- *   following unique keys are required):
- *    - cvterm_id: the chado cv.cvterm_id primary key
- *    - name: the chado cvterm.name field (assume unique)
- *   There are also some specially handled keys. They are:
- *    - cv_id:  an integer indicating the cv_id or an array with 'name' => the name of the cv.
- *    - synonym: an array with 'name' => the name of the synonym of the cvterm you want
- *        returned; 'cv_id' => the cv_id of the synonym; 'cv_name' => the name of the cv
- *        of the synonym
- *    - property: An array/object describing the property to select records for. It
- *      should at least have either a type_name (if unique across cvs) or type_id. Other
- *      supported keys include: cv_id/cv_name (of the type), value and rank
+ *   An array apropriate for use with the chado_generate_var for uniquely
+ *   identifying a cvterm record. Alternativley, there are also some specially
+ *   handled keys. They are:
+ *    - cv_id:  an integer indicating the cv_id or an array with 'name' => the
+ *      name of the cv.
+ *    - synonym: an array with 'name' => the name of the synonym of the cvterm
+ *      you want returned; 'cv_id' => the cv_id of the synonym; 'cv_name' =>
+ *      the name of the cv of the synonym
+ *    - property: An array/object describing the property to select records
+ *      for. It should at least have either a type_name (if unique across cvs)
+ *      or type_id. Other supported keys include: cv_id/cv_name (of the type),
+ *      value and rank
  * @param $options
  *   An array of options. Supported keys include:
- *     - Any keys supported by chado_generate_var(). See that function definition for
- *       additional details.
+ *     - Any keys supported by chado_generate_var(). See that function
+ *       definition for additional details.
  *
- * NOTE: the $identifier parameter can really be any array similar to $values passed into
- *   chado_select_record(). It should fully specify the cvterm record to be returned.
+ * NOTE: the $identifier parameter can really be any array similar to $values
+ *   passed into chado_select_record(). It should fully specify the cvterm
+ *   record to be returned.
  *
  * @return
- *   If unique values were passed in as an identifier then an object describing the cvterm
- *   will be returned (will be a chado variable from chado_generate_var()). Otherwise,
- *   FALSE will be returned.
+ *   If unique values were passed in as an identifier then an object describing
+ *   the cvterm will be returned (will be a chado variable from
+ *   chado_generate_var()). Otherwise, FALSE will be returned.
  *
  * @ingroup tripal_cv_api
  */
@@ -379,55 +380,70 @@ function tripal_insert_cv($name, $definition) {
 }
 
 /**
- *  Add's a controlled vocabulary term to the cvterm table.
+ *  Add's a controlled vocabulary term to Chado.
  *
- *  If the parent CV does not exist then
- *  that too is added to the CV table.  If the cvterm is a relationship term
- *  then the $is_relationship argument should be set.  The function will try
- *  to first find the relationship in the relationship ontology for updating and
- *  if it can't be found will add the relationship to the __global CV.  All terms
- *  must also have a corresponding database.  This is specified in the term's
- *  ID just before the colon (e.g. GO:003824).  If the database does not exist
- *  in the DB table then it will be added automatically.  The accession (the
- *  value just after the colon in the term's ID) will be added to the dbxref
- *  table.  If the CVterm already exists and $update is set (default) then the
- *  cvterm is updated.  If the CVTerm already exists and $update is not set, then
- *  no changes are made and the CVTerm object is returned.
+ *  This function will add a cvterm record (and a dbxref record if appropriate
+ *  values are provided). If the parent vocabulary does not exist then
+ *  that also is added to the cv table.  If the cvterm is a relationship term
+ *  then the 'is_relationship' value should be set.  All
+ *  terms must also have a corresponding database.  This is specified in the
+ *  term's ID just before the colon (e.g. GO:003824).  If the database does not
+ *  exist in the DB table then it will be added automatically.  The accession
+ *  (the value just after the colon in the term's ID) will be added to the
+ *  dbxref table.  If the CVterm already exists and $update is set (default)
+ *  then the cvterm is updated.  If the CVTerm already exists and $update is
+ *  not set, then no changes are made and the CVTerm object is returned.
  *
  * @param $term
  *   An associative array with the following keys:
- *    - id: the term accession. must be of the form <DB>:<ACCESSION>, where <DB> is the
- *        name of the database to which the cvterm belongs and the <ACCESSION> is the
- *        term's accession number in the database.
+ *    - id: the term accession. must be of the form <DB>:<ACCESSION>, where
+ *      <DB> is the name of the database to which the cvterm belongs and the
+ *      <ACCESSION> is the term's accession number in the database.
  *    - name: the name of the term. usually meant to be human-readable.
- *    - namespace: the CV name for the term. DEPRECATED. Please use cv_name instead.
  *    - is_obsolete: is present and set to 1 if the term is defunct
  *    - definition: the definition of the term
- *    - cv_name: The CV name to which the term belongs.  If this arugment is null or not
- *        provided then the function tries to find a record in the CV table with the same
- *        name provided in the $term[namespace].  If this field is provided then it
- *        overrides what the value in $term[namespace]
- *    - is_relationship: If this term is a relationship term then this value should be 1.
- *    - db_name: In some cases the database name will not be part of the $term['id'] and it
- *        needs to be explicitly set.  Use this argument only if the database name
- *        cannot be specififed in the term ID (e.g. <DB>:<ACCESSION>).
+ *    - cv_name: The CV name to which the term belongs.  If this arugment is
+ *        null or not provided then the function tries to find a record in the
+ *        CV table with the same name provided in the $term[namespace].  If
+ *        this field is provided then it overrides what the value in
+ *        $term[namespace]
+ *    - is_relationship: If this term is a relationship term then this value
+ *        should be 1.
+ *    - db_name: In some cases the database name will not be part of the
+ *        $term['id'] and it needs to be explicitly set.  Use this argument
+ *        only if the database name cannot be specififed in the term ID
+ *        (e.g. <DB>:<ACCESSION>).
  * @param $options
  *   An associative array with the following keys:
- *    - update_existing: By default this is TRUE.  If the term exists it is automatically updated.
+ *    - update_existing: By default this is TRUE.  If the term exists it is
+ *      automatically updated.
  *
  * @return
- *   A CVTerm object
+ *   A cvterm object
  *
- * @ingroup tripal_cv_api
+ * @ingroup tripal_chado_api
  */
 function tripal_insert_cvterm($term, $options = array()) {
 
+  // get the term properties
+  $id = (isset($term['id'])) ? $term['id'] : '';
+  $name = '';
+  $cvname = '';
+  $definition = '';
+  $is_obsolete = 0;
+  $accession = '';
+
   // Set Defaults
   if (isset($term['cv_name'])) {
-    $defaultcv = $term['cv_name'];
+    $cvname = $term['cv_name'];
   }
   else {
-    $defaultcv = '_global';
+    $cvname = 'local';
+  }
+  // Namespace is deprecated but must be supported for backwards
+  // compatability
+  if (array_key_exists('namespace', $term)) {
+    $cvname = $term['namespace'];
   }
 
   if (isset($term['is_relationship'])) {
@@ -451,14 +467,6 @@ function tripal_insert_cvterm($term, $options = array()) {
     $update = 1;
   }
 
-  // get the term properties
-  $id = (isset($term['id'])) ? $term['id'] : '';
-  $name = '';
-  $cvname = '';
-  $definition = '';
-  $is_obsolete = 0;
-  $accession = '';
-
   if (array_key_exists('name', $term)) {
     $name = $term['name'];
   }
@@ -466,12 +474,7 @@ function tripal_insert_cvterm($term, $options = array()) {
     $name = $id;
   }
 
-  if (array_key_exists('namespace', $term)) {
-    $cvname = $term['namespace'];
-  }
-  else {
-    $cvname = $defaultcv;
-  }
+
   if (array_key_exists('definition', $term)) {
     $definition = preg_replace('/^\"(.*)\"/', '\1', $term['definition']);
   }
@@ -492,7 +495,7 @@ function tripal_insert_cvterm($term, $options = array()) {
     $id = $name;
   }
 
-  // get the accession and the database from the cvterm id
+  // Get the accession and the database from the cvterm id.
   if ($dbname) {
     $accession = $id;
   }
@@ -502,7 +505,8 @@ function tripal_insert_cvterm($term, $options = array()) {
     $dbname = preg_replace('/^(.+?):.*$/', '\1', $id);
   }
 
-  // check that we have a database name, give a different message if it's a relationship
+  // Check that we have a database name, give a different message if it's a
+  // relationship.
   if ($is_relationship and !$dbname) {
     tripal_report_error('tripal_cv', TRIPAL_WARNING, "A database name is not provided for this relationship term: $id", NULL);
     return 0;
@@ -512,7 +516,7 @@ function tripal_insert_cvterm($term, $options = array()) {
     return 0;
   }
 
-  // make sure the CV name exists
+  // Make sure the CV name exists
   $cv = tripal_get_cv(array('name' => $cvname));
   if (!$cv) {
     $cv = tripal_insert_cv($cvname, '');
@@ -522,10 +526,10 @@ function tripal_insert_cvterm($term, $options = array()) {
     return 0;
   }
 
-  // this SQL statement will be used a lot to find a cvterm so just set it
+  // This SQL statement will be used a lot to find a cvterm so just set it
   // here for easy reference below.  Because CV terms can change their names
   // but accessions don't change, the following SQL finds cvterms based on
-  // their accession rather than the name
+  // their accession rather than the name.
   $cvtermsql = "
     SELECT CVT.name, CVT.cvterm_id, CV.cv_id, CV.name as cvname,
       DB.name as dbname, DB.db_id, DBX.accession
@@ -536,7 +540,7 @@ function tripal_insert_cvterm($term, $options = array()) {
     WHERE DBX.accession = :accession and DB.name = :name
   ";
 
-  // add the database. The function will just return the DB object if the
+  // Add the database. The function will just return the DB object if the
   // database already exists.
   $db = tripal_get_db(array('name' => $dbname));
   if (!$db) {
@@ -547,8 +551,8 @@ function tripal_insert_cvterm($term, $options = array()) {
     return 0;
   }
 
-  // the cvterm table has two unique dependencies. We need to check both.
-  // first check the (name, cv_id, is_obsolete) constraint
+  // The cvterm table has two unique dependencies. We need to check both.
+  // first check the (name, cv_id, is_obsolete) constraint.
   $values = array(
     'name' => $name,
     'is_obsolete' => $is_obsolete,
@@ -556,99 +560,96 @@ function tripal_insert_cvterm($term, $options = array()) {
       'name' => $cvname,
     ),
   );
-  $options = array('statement_name' => 'sel_cvterm_c1');
-  $result = chado_select_record('cvterm', array('*'), $values, $options);
-
-  // if the constraint is met then let's check it to see if
-  // the database name matches the one we have been provided
+  $result = chado_select_record('cvterm', array('*'), $values);
   if (count($result) == 1) {
     $cvterm = $result[0];
 
-    // get the dbxref record
+    // Get the dbxref record.
     $values = array('dbxref_id' => $cvterm->dbxref_id);
-    $options = array('statement_name' => 'sel_dbxref_id');
-    $result = chado_select_record('dbxref', array('*'), $values, $options);
+    $result = chado_select_record('dbxref', array('*'), $values);
     $dbxref = $result[0];
+    if (!$dbxref) {
+      tripal_report_error('tripal_cv', TRIPAL_ERROR,
+          'Unable to access the dbxref record for the :term cvterm. Term Record: !record',
+          array(':term' => $name, '!record' => print_r($cvterm, TRUE))
+      );
+      return FALSE;
+    }
 
-    // get the db
+    // Get the db.
     $values = array('db_id' => $dbxref->db_id);
-    $options = array('statement_name' => 'sel_db_id');
-    $result = chado_select_record('db', array('*'), $values, $options);
+    $result = chado_select_record('db', array('*'), $values);
     $db_check = $result[0];
 
-    // the database name for this existing term does not match that of the
-    // one provided to this function.  The CV name matches otherwise we
-    // wouldn't have made it this far. So, let's swap the database for
-    // this term
-    if ($db_check->name != $db->name) {
-
-      // look to see if the correct dbxref record already exists for this database
-      $values = array(
-        'db_id' => $db->db_id,
-        'accession' => $accession,
-      );
-      $options = array('statement_name' => 'sel_dbxref_idac');
-      $result = chado_select_record('dbxref', array('*'), $values, $options);
-
-      // if we already have a good dbxref then we want to update our cvterm
-      // to use this dbxref
-      if (count($result) > 0) {
-        $dbxref = $result[0];
-        $match = array('cvterm_id' => $cvterm->cvterm_id);
-        $values = array('dbxref_id' => $dbxref->dbxref_id);
-        $options = array('statement_name' => 'upd_cvterm_db');
-        $success = chado_update_record('cvterm', $match, $values, $options);
-        if (!$success) {
-          tripal_report_error('tripal_cv', TRIPAL_WARNING, "Failed to correct the dbxref id for the cvterm " .
-            "'$name' (id: $accession), for database $dbname", NULL);
-          return 0;
-        }
-      }
-      // if we don't have the record then we want to delete our cvterm and let the code
-      // below recreate it with the correct info
-      else {
-        $match = array('cvterm_id' => $cvterm->cvterm_id);
-        $options = array('statement_name' => 'del_cvterm_cv');
-        chado_delete_record('cvterm', $match, $options);
-      }
-    }
-
-    // check that the accession matches.  Sometimes an OBO can define the same term
+    //     // The database name for this existing term does not match that of the
+    //     // one provided to this function.  The CV name matches otherwise we
+    //     // wouldn't have made it this far. So, let's swap the database for
+    //     // this term.
+    //     if ($db_check->name != $db->name) {
+
+    //       // Look to see if the correct dbxref record already exists for this
+    //       // database.
+    //       $values = array(
+    //         'db_id' => $db->db_id,
+    //         'accession' => $accession,
+    //       );
+    //       $result = chado_select_record('dbxref', array('*'), $values);
+
+    //       // If we already have a good dbxref then we want to update our cvterm
+    //       // to use this dbxref.
+    //       if (count($result) > 0) {
+    //         $dbxref = $result[0];
+    //         $match = array('cvterm_id' => $cvterm->cvterm_id);
+    //         $values = array('dbxref_id' => $dbxref->dbxref_id);
+    //         $success = chado_update_record('cvterm', $match, $values);
+    //         if (!$success) {
+    //           tripal_report_error('tripal_cv', TRIPAL_WARNING, "Failed to correct the dbxref id for the cvterm " .
+    //             "'$name' (id: $accession), for database $dbname", NULL);
+    //           return 0;
+    //         }
+    //       }
+    //       // If we don't have the dbxref then we want to delete our cvterm and let
+    //       // the code below recreate it with the correct info.
+    //       else {
+    //         $match = array('cvterm_id' => $cvterm->cvterm_id);
+    //         chado_delete_record('cvterm', $match);
+    //       }
+    //     }
+
+    // Check that the accession matches.  Sometimes an OBO can define a term
     // multiple times but with different accessions.  If this is the case we
     // can't do an insert or it will violate the constraint in the cvterm table.
-    // so we'll need to add the record to the cvterm_dbxref table instead
+    // So we'll need to add the record to the cvterm_dbxref table instead.
     if ($dbxref->accession != $accession) {
 
-      // get/add the dbxref fort his term
+      // Get/add the dbxref for his term.
       $dbxref_new =  tripal_insert_dbxref(array(
         'db_id' => $db->db_id,
         'accession' => $accession
       ));
       if (!$dbxref_new) {
         tripal_report_error('tripal_cv', TRIPAL_WARNING, "Failed to find or insert the dbxref record for cvterm, " .
-          "$name (id: $accession), for database $dbname", NULL);
+            "$name (id: $accession), for database $dbname", NULL);
         return 0;
       }
 
-      // check to see if the cvterm_dbxref record already exists
+      // Check to see if the cvterm_dbxref record already exists.
       $values = array(
         'cvterm_id' => $cvterm->cvterm_id,
         'dbxref_id' => $dbxref_new->dbxref_id,
         'is_for_definition' => 1,
       );
-      $options = array('statement_name' => 'sel_cvtermdbxref_cvdbis');
-      $result = chado_select_record('cvterm_dbxref', array('*'), $values, $options);
+      $result = chado_select_record('cvterm_dbxref', array('*'), $values);
 
       // if the cvterm_dbxref record does not exists then add it
       if (count($result)==0) {
         $options = array(
-          'statement_name' => 'ins_cvtermdbxref_cvdbis',
           'return_record' => FALSE,
         );
         $success = chado_insert_record('cvterm_dbxref', $values, $options);
         if (!$success) {
           tripal_report_error('tripal_cv', TRIPAL_WARNING, "Failed to find or insert the cvterm_dbxref record for a " .
-            "duplicated cvterm:  $name (id: $accession), for database $dbname", NULL);
+              "duplicated cvterm:  $name (id: $accession), for database $dbname", NULL);
           return 0;
         }
       }
@@ -658,86 +659,121 @@ function tripal_insert_cvterm($term, $options = array()) {
       return $cvterm;
     }
 
-    // continue on, we've fixed the record if the db_id did not match,
-    // we can now perform and updated if we need to.
-  }
+    // Continue on, we've fixed the record if the db_id did not match.
+    // We can now perform and updated if we need to.
+    }
 
-  // get the CVterm record
-  $result = chado_query($cvtermsql, array(':accession' => $accession, ':name' => $dbname));
-  $cvterm = $result->fetchObject();
-  if (!$cvterm) {
+    // get the CVterm record
+    $result = chado_query($cvtermsql, array(':accession' => $accession, ':name' => $dbname));
+    $cvterm = $result->fetchObject();
+    if (!$cvterm) {
 
-    // check to see if the dbxref exists if not, add it
-    $dbxref =  tripal_insert_dbxref(array(
-      'db_id' => $db->db_id,
-      'accession' => $accession
-    ));
-    if (!$dbxref) {
-      tripal_report_error('tripal_cv', TRIPAL_WARNING, "Failed to find or insert the dbxref record for cvterm, " .
-        "$name (id: $accession), for database $dbname", NULL);
-      return 0;
-    }
+      // Check to see if the dbxref exists if not, add it.
+      $dbxref =  tripal_insert_dbxref(array(
+        'db_id' => $db->db_id,
+        'accession' => $accession
+      ));
+      if (!$dbxref) {
+        tripal_report_error('tripal_cv', TRIPAL_WARNING, "Failed to find or insert the dbxref record for cvterm, " .
+            "$name (id: $accession), for database $dbname", NULL);
+        return 0;
+      }
 
-    // check to see if the dbxref already has an entry in the cvterm table
-    // this is the second constraint in the cvterm table
-    $values = array('dbxref_id' => $dbxref->dbxref_id);
-    $options = array('statement_name' => 'sel_cvterm_db');
-    $check = chado_select_record('cvterm', array('cvterm_id'), $values, $options);
-    if (count($check) == 0) {
-      // now add the cvterm
-      $ins_values = array(
-        'cv_id'                => $cv->cv_id,
-        'name'                 => $name,
-        'definition'           => $definition,
-        'dbxref_id'            => $dbxref->dbxref_id,
-        'is_obsolete'          => $is_obsolete,
-        'is_relationshiptype'  => $is_relationship,
+      // Check to see if the dbxref already has an entry in the cvterm table.
+      $values = array('dbxref_id' => $dbxref->dbxref_id);
+      $check = chado_select_record('cvterm', array('cvterm_id'), $values);
+      if (count($check) == 0) {
+        // now add the cvterm
+        $ins_values = array(
+          'cv_id'                => $cv->cv_id,
+          'name'                 => $name,
+          'definition'           => $definition,
+          'dbxref_id'            => $dbxref->dbxref_id,
+          'is_obsolete'          => $is_obsolete,
+          'is_relationshiptype'  => $is_relationship,
+        );
+        $success = chado_insert_record('cvterm', $ins_values);
+        if (!$success) {
+          if (!$is_relationship) {
+            tripal_report_error('tripal_cv', TRIPAL_WARNING, "Failed to insert the term: $name ($dbname)", NULL);
+            return 0;
+          }
+          else {
+            tripal_report_error('tripal_cv', TRIPAL_WARNING, "Failed to insert the relationship term: $name (cv: " . $cvname . " db: $dbname)", NULL);
+            return 0;
+          }
+        }
+      }
+      // This dbxref already exists in the cvterm table.
+      else {
+        tripal_report_error('tripal_cv', TRIPAL_WARNING, "The dbxref already exists for another cvterm record: $name (cv: " . $cvname . " db: $dbname)", NULL);
+        return 0;
+      }
+      $result = chado_query($cvtermsql, array(':accession' => $accession, ':name' => $dbname));
+      $cvterm = $result->fetchObject();
+    }
+    // Update the cvterm.
+    elseif ($update) {
+
+      // First, basic update of the term.
+      $match = array('cvterm_id' => $cvterm->cvterm_id);
+      $upd_values = array(
+        'name'                => $name,
+        'definition'          => $definition,
+        'is_obsolete'         => $is_obsolete,
+        'is_relationshiptype' => $is_relationship,
       );
-      $ins_options = array('statement_name' => 'ins_cvterm_all');
-      $success = chado_insert_record('cvterm', $ins_values, $ins_options);
+      $success = chado_update_record('cvterm', $match, $upd_values);
       if (!$success) {
-        if (!$is_relationship) {
-          tripal_report_error('tripal_cv', TRIPAL_WARNING, "Failed to insert the term: $name ($dbname)", NULL);
+        tripal_report_error('tripal_cv', TRIPAL_WARNING, "Failed to update the term: $name", NULL);
+        return 0;
+      }
+
+      // Second, check that the dbxref has not changed and if it has then update it.
+      $checksql = "
+        SELECT cvterm_id
+        FROM {cvterm} CVT
+          INNER JOIN {dbxref} DBX on CVT.dbxref_id = DBX.dbxref_id
+          INNER JOIN {db} DB on DBX.db_id = DB.db_id
+          INNER JOIN {cv} CV on CV.cv_id = CVT.cv_id
+        WHERE DBX.accession = :accession and DB.name = :dbname and CVT.name = :term and CV.name = :cvname
+      ";
+      $check = chado_query($checksql, array(':accession' => $dbxref->accession, ':dbname' => $dbname, ':term' => $name, ':cvname' => $cvname))->fetchObject();
+      if (!$check) {
+
+        // check to see if the dbxref exists if not, add it.
+        $dbxref =  tripal_insert_dbxref(array(
+          'db_id' => $db->db_id,
+          'accession' => $accession
+        ));
+        if (!$dbxref) {
+          tripal_report_error('tripal_chado', TRIPAL_WARNING, "Failed to find or insert the dbxref record for cvterm, " .
+              "$name (id: $accession), for database $dbname", NULL);
           return 0;
         }
-        else {
-          tripal_report_error('tripal_cv', TRIPAL_WARNING, "Failed to insert the relationship term: $name (cv: " . $cvname . " db: $dbname)", NULL);
+
+        $match = array('cvterm_id' => $cvterm->cvterm_id);
+        $upd_values = array(
+          'dbxref_id' => $dbxref->dbxref_id,
+        );
+        $success = chado_update_record('cvterm', $match, $upd_values);
+        if (!$success) {
+          tripal_report_error('tripal_chado', TRIPAL_WARNING, "Failed to update the term $name with new accession $db:$accession", NULL);
           return 0;
         }
       }
+
+      // Finally grab the updated details.
+      $result = chado_query($cvtermsql, array(':accession' => $accession, ':name' => $dbname));
+      $cvterm = $result->fetchObject();
     }
-    // this dbxref already exists in the cvterm table
     else {
-      tripal_report_error('tripal_cv', TRIPAL_WARNING, "The dbxref already exists for another cvterm record: $name (cv: " . $cvname . " db: $dbname)", NULL);
-      return 0;
+      // do nothing, we have the cvterm but we don't want to update
     }
-    $result = chado_query($cvtermsql, array(':accession' => $accession, ':name' => $dbname));
-    $cvterm = $result->fetchObject();
-  }
-  // upate the cvterm
-  elseif ($update) {
-    $match = array('cvterm_id' => $cvterm->cvterm_id);
-    $upd_values = array(
-      'name'                => $name,
-      'definition'          => $definition,
-      'is_obsolete'         => $is_obsolete,
-      'is_relationshiptype' => $is_relationship,
-    );
-    $upd_options = array('statement_name' => 'upd_cvterm_nadeisis');
-    $success = chado_update_record('cvterm', $match, $upd_values, $upd_options);
-    if (!$success) {
-      tripal_report_error('tripal_cv', TRIPAL_WARNING, "Failed to update the term: $name", NULL);
-      return 0;
-    }
-    $result = chado_query($cvtermsql, array(':accession' => $accession, ':name' => $dbname));
-    $cvterm = $result->fetchObject();
-  }
-  else {
-     // do nothing, we have the cvterm but we don't want to update
+    // return the cvterm
+    return $cvterm;
   }
-  // return the cvterm
-  return $cvterm;
-}
+
 
 /**
  * This function allows other modules to programatically
@@ -835,11 +871,13 @@ function tripal_insert_obo($name, $path) {
     return $obo_id;
   }
   else {
-    $record = new stdClass;
-    $record->name = $name;
-    $record->path = $path;
-    drupal_write_record('tripal_cv_obo', $record);
-    return $record->obo_id;
+    $obo_id = db_insert('tripal_cv_obo')
+      ->fields(array(
+        'name' => $name,
+        'path' => $path,
+      ))
+      ->execute();
+    return $obo_id;
   }
 }
 
@@ -859,9 +897,14 @@ function tripal_insert_obo($name, $path) {
  */
 function tripal_autocomplete_cvterm($cv_id, $string = '') {
   $sql = "
-    SELECT cvterm_id, name
-    FROM {cvterm}
-    WHERE cv_id = :cv_id and lower(name) like lower(:name)
+    SELECT CVT.cvterm_id, CVT.name
+    FROM {cvterm} CVT
+    WHERE CVT.cv_id = :cv_id and lower(CVT.name) like lower(:name)
+    UNION
+    SELECT CVT2.cvterm_id, CVTS.synonym as name
+    FROM {cvterm} CVT2
+      INNER JOIN {cvtermsynonym} CVTS ON CVTS.cvterm_id = CVT2.cvterm_id
+    WHERE CVT2.cv_id = :cv_id and lower(CVTS.synonym) like lower(:name)
     ORDER by name
     LIMIT 25 OFFSET 0
   ";
@@ -1040,7 +1083,19 @@ function tripal_set_default_cv($table, $field, $cv_name, $cv_id = FALSE) {
 }
 
 /**
- * Retreives the default vocabulary for a given table and field
+ * Retreives the default vocabulary for a given table and field.
+ *
+ * Each table in Chado that has a 'type_id' (or foreign key constraint to
+ * the cvterm table) will have a default vocabulary assigned. This indicates to
+ * Tripal that terms in that vocabulary are used to set the type_id for that
+ * table. An example where this is used is the
+ * tripal_get_cvterm_select_options() function which generates a list of options
+ * for a select box used in a Drupal form.  The select box will list the terms
+ * from the default vocabulary in the drop down.
+ *
+ * This function uses the Chado table and field name (e.g. 'type_id') to
+ * retreive the vocabulary assgined.
+ *
  * @param $table
  *   The name of the table that contains a field with a foreign key
  *   relationship to the cvterm table
@@ -1112,4 +1167,4 @@ function tripal_get_cvterm_default_select_options($table, $field, $field_desc) {
   }
 
   return $options;
-}
+}

+ 44 - 0
tripal_cv/api/tripal_cv.schema.api.inc

@@ -6,6 +6,7 @@
 
 /**
  * Implements hook_chado_schema_v1_2_tripal_obo_temp()
+ *
  * Purpose: To describe the structure of 'tripal_obo_temp' to tripal
  * @see chado_insert_record()
  * @see chado_update_record()
@@ -44,4 +45,47 @@ function tripal_cv_chado_schema_v1_2_tripal_obo_temp() {
     ),
   );
   return $schema;
+}
+
+/**
+ * Implements hook_chado_schema_v1_3_tripal_obo_temp()
+ *
+ * Purpose: To describe the structure of 'tripal_obo_temp' to tripal
+ * @see chado_insert_record()
+ * @see chado_update_record()
+ * @see chado_select_record()
+ *
+ * @return
+ *    An array describing the 'tripal_obo_temp' table
+ *
+ * @ingroup tripal_chado_v1.3_schema_api
+ */
+function tripal_cv_chado_schema_v1_3_tripal_obo_temp() {
+  $schema = array(
+    'table' => 'tripal_obo_temp',
+    'fields' => array(
+      'id' => array(
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => TRUE,
+      ),
+      'stanza' => array(
+        'type' => 'text',
+        'not null' => TRUE,
+      ),
+      'type' => array(
+        'type' => 'varchar',
+        'length' => '50',
+        'not null' => TRUE,
+      ),
+    ),
+    'indexes' => array(
+      'tripal_obo_temp_idx0' => array('id'),
+      'tripal_obo_temp_idx0' => array('type'),
+    ),
+    'unique keys' => array(
+      'tripal_obo_temp_uq0' => array('id'),
+    ),
+  );
+  return $schema;
 }

+ 236 - 0
tripal_cv/files/legacy_ro.obo

@@ -0,0 +1,236 @@
+format-version: 1.2
+date: 20:03:2009 11:58
+saved-by: cjm
+auto-generated-by: cjm
+default-namespace: relationship
+remark: <p>This ontology contains logical relations to be shared across the different OBO ontologies. Each OBO ontology is free to extend this set with relations specific to the biology within that ontology</p><div class="notes"><p>In the definitions, variables c, d, ..., p, q, ... range over instances of continuants and processes respectively. C, D, ..., P, Q, ... range over the corresponding classes</p><p> For a discussion of instance-level relations and also of additional axioms needed to infer transitivity and other properties of the relations listed above see <a href="http://genomebiology.com/2005/6/5/R46">http://genomebiology.com/2005/6/5/R46</a> or the OBO relations page hosted at <a href="http://obo.sourceforge.net/relationship">http://obo.sourceforge.net/relationship</a></div>
+idspace: OBO_REL http://www.obofoundry.org/ro/ro.owl# "OBO Relation ontology official home on OBO Foundry"
+remark: cvs version $Revision: 1.14 $
+remark: release version 1.01
+
+[Typedef]
+id: OBO_REL:is_a
+alt_id: OBO_REL:0000001
+name: is_a
+builtin: true
+def: "For continuants: C is_a C' if and only if: given any c that instantiates C at a time t, c instantiates C' at t. For processes: P is_a P' if and only if: that given any p that instantiates P, then p instantiates P'." [PMID:15892874]
+comment: The is_a relationship is considered axiomatic by the obo file format specification. In the representation of obo in OWL, where obo terms are represented as OWL classes, is_a is mapped on to the subClassOf axiom
+exact_synonym: "is_subtype_of" []
+xref: owl:subClassOf
+is_reflexive: true
+is_anti_symmetric: true
+is_transitive: true
+
+[Typedef]
+id: OBO_REL:part_of
+alt_id: OBO_REL:0000002
+name: part_of
+def: "For continuants: C part_of C' if and only if: given any c that instantiates C at a time t, there is some c' such that c' instantiates C' at time t, and c *part_of* c' at t. For processes: P part_of P' if and only if: given any p that instantiates P at a time t, there is some p' such that p' instantiates P' at time t, and p *part_of* p' at t. (Here *part_of* is the instance-level part-relation.)" [PMID:15892874]
+comment: Parthood as a relation between instances: The primitive instance-level relation p part_of p1 is illustrated in assertions such as: this instance of rhodopsin mediated phototransduction part_of this instance of visual perception.    This relation satisfies at least the following standard axioms of mereology: reflexivity (for all p, p part_of p); anti-symmetry (for all p, p1, if p part_of p1 and p1 part_of p then p and p1 are identical); and transitivity (for all p, p1, p2, if p part_of p1 and p1 part_of p2, then p part_of p2). Analogous axioms hold also for parthood as a relation between spatial regions.    For parthood as a relation between continuants, these axioms need to be modified to take account of the incorporation of a temporal argument. Thus for example the axiom of transitivity for continuants will assert that if c part_of c1 at t and c1 part_of c2 at t, then also c part_of c2 at t.    Parthood as a relation between classes: To define part_of as a relation between classes we again need to distinguish the two cases of continuants and processes, even though the explicit reference to instants of time now falls away. For continuants, we have C part_of C1 if and only if any instance of C at any time is an instance-level part of some instance of C1 at that time, as for example in: cell nucleus part_ of cell.
+inverse_of_on_instance_level: OBO_REL:has_part
+is_reflexive: true
+is_anti_symmetric: true
+is_transitive: true
+
+[Typedef]
+id: OBO_REL:has_part
+alt_id: OBO_REL:0000003
+name: has_part
+inverse_of_on_instance_level: OBO_REL:part_of
+is_reflexive: true
+is_anti_symmetric: true
+is_transitive: true
+
+[Typedef]
+id: OBO_REL:integral_part_of
+alt_id: OBO_REL:0000004
+name: integral_part_of
+is_a: OBO_REL:part_of
+def: "C integral_part_of C' if and only if: C part_of C' AND C' has_part C" [PMID:15892874]
+inverse_of: OBO_REL:has_integral_part
+is_reflexive: true
+is_anti_symmetric: true
+is_transitive: true
+
+[Typedef]
+id: OBO_REL:has_integral_part
+alt_id: OBO_REL:0000005
+name: has_integral_part
+is_a: OBO_REL:has_part
+inverse_of: OBO_REL:integral_part_of
+is_reflexive: true
+is_anti_symmetric: true
+is_transitive: true
+
+[Typedef]
+id: OBO_REL:proper_part_of
+alt_id: OBO_REL:0000006
+name: proper_part_of
+is_a: OBO_REL:part_of
+def: "As for part_of, with the additional constraint that subject and object are distinct" [PMID:15892874]
+inverse_of_on_instance_level: OBO_REL:has_proper_part
+is_transitive: true
+
+[Typedef]
+id: OBO_REL:has_proper_part
+alt_id: OBO_REL:0000007
+name: has_proper_part
+is_a: OBO_REL:has_part
+inverse_of_on_instance_level: OBO_REL:proper_part_of
+is_transitive: true
+
+[Typedef]
+id: OBO_REL:located_in
+alt_id: OBO_REL:0000008
+name: located_in
+def: "C located_in C' if and only if: given any c that instantiates C at a time t, there is some c' such that: c' instantiates C' at time t and c *located_in* c'. (Here *located_in* is the instance-level location relation.)" [PMID:15892874]
+comment: Location as a relation between instances: The primitive instance-level relation c located_in r at t reflects the fact that each continuant is at any given time associated with exactly one spatial region, namely its exact location. Following we can use this relation to define a further instance-level location relation - not between a continuant and the region which it exactly occupies, but rather between one continuant and another. c is located in c1, in this sense, whenever the spatial region occupied by c is part_of the spatial region occupied by c1.    Note that this relation comprehends both the relation of exact location between one continuant and another which obtains when r and r1 are identical (for example, when a portion of fluid exactly fills a cavity), as well as those sorts of inexact location relations which obtain, for example, between brain and head or between ovum and uterus
+inverse_of_on_instance_level: OBO_REL:location_of
+is_transitive: true
+is_reflexive: true
+
+[Typedef]
+id: OBO_REL:location_of
+alt_id: OBO_REL:0000009
+name: location_of
+inverse_of_on_instance_level: OBO_REL:located_in
+is_transitive: true
+is_reflexive: true
+
+[Typedef]
+id: OBO_REL:contained_in
+alt_id: OBO_REL:0000010
+name: contained_in
+inverse_of_on_instance_level: OBO_REL:contains
+def: "C contained_in C' if and only if: given any instance c that instantiates C at a time t, there is some c' such that: c' instantiates C' at time t and c located_in c' at t, and it is not the case that c *overlaps* c' at t. (c' is a conduit or cavity.)" [PMID:15892874]
+comment: Containment obtains in each case between material and immaterial continuants, for instance: lung contained_in thoracic cavity; bladder contained_in pelvic cavity. Hence containment is not a transitive relation.    If c part_of c1 at t then we have also, by our definition and by the axioms of mereology applied to spatial regions, c located_in c1 at t. Thus, many examples of instance-level location relations for continuants are in fact cases of instance-level parthood. For material continuants location and parthood coincide. Containment is location not involving parthood, and arises only where some immaterial continuant is involved. To understand this relation, we first define overlap for continuants as follows:    c1 overlap c2 at t =def for some c, c part_of c1 at t and c part_of c2 at t. The containment relation on the instance level can then be defined (see definition):
+
+[Typedef]
+id: OBO_REL:contains
+alt_id: OBO_REL:0000011
+name: contains
+inverse_of_on_instance_level: OBO_REL:contained_in
+
+[Typedef]
+id: OBO_REL:adjacent_to
+alt_id: OBO_REL:0000012
+name: adjacent_to
+def: "C adjacent to C' if and only if: given any instance c that instantiates C at a time t, there is some c' such that: c' instantiates C' at time t and c and c' are in spatial proximity" [PMID:15892874]
+comment: Note that adjacent_to as thus defined is not a symmetric relation, in contrast to its instance-level counterpart. For it can be the case that Cs are in general such as to be adjacent to instances of C1 while no analogous statement holds for C1s in general in relation to instances of C. Examples are: nuclear membrane adjacent_to cytoplasm; seminal vesicle adjacent_to urinary bladder; ovary adjacent_to parietal pelvic peritoneum
+instance_level_is_transitive: true
+
+[Typedef]
+id: OBO_REL:transformation_of
+alt_id: OBO_REL:0000013
+name: transformation_of
+def: "Relation between two classes, in which instances retain their identity yet change their classification by virtue of some kind of transformation. Formally: C transformation_of C' if and only if given any c and any t, if c instantiates C at time t, then for some t', c instantiates C' at t' and t' earlier t, and there is no t2 such that c instantiates C at t2 and c instantiates C' at t2." [PMID:15892874]
+comment: When an embryonic oenocyte (a type of insect cell) is transformed into a larval oenocyte, one and the same continuant entity preserves its identity while instantiating distinct classes at distinct times. The class-level relation transformation_of obtains between continuant classes C and C1 wherever each instance of the class C is such as to have existed at some earlier time as an instance of the distinct class C1 (see Figure 2 in paper). This relation is illustrated first of all at the molecular level of granularity by the relation between mature RNA and the pre-RNA from which it is processed, or between (UV-induced) thymine-dimer and thymine dinucleotide. At coarser levels of granularity it is illustrated by the transformations involved in the creation of red blood cells, for example, from reticulocyte to erythrocyte, and by processes of development, for example, from larva to pupa, or from (post-gastrular) embryo to fetus or from child to adult. It is also manifest in pathological transformations, for example, of normal colon into carcinomatous colon. In each such case, one and the same continuant entity instantiates distinct classes at different times in virtue of phenotypic changes.
+is_transitive: true
+
+[Typedef]
+id: OBO_REL:transformed_into
+alt_id: OBO_REL:0000014
+name: transformed_into
+comment: Obsoleted
+is_obsolete: true
+
+[Typedef]
+id: OBO_REL:derives_from
+alt_id: OBO_REL:0000015
+name: derives_from
+def: "Derivation on the instance level (*derives_from*) holds between distinct material continuants when one succeeds the other across a temporal divide in such a way that at least a biologically significant portion of the matter of the earlier continuant is inherited by the later. We say that one class C derives_from class C' if instances of C are connected to instances of C' via some chain of instance-level derivation relations. Example: osteocyte derives_from osteoblast. Formally: C derives_immediately_from C' if and only if: given any c and any t, if c instantiates C at time t, then there is some c' and some t', such that c' instantiates C' at t' and t' earlier-than t and c *derives_from* c'. C derives_from C' if and only if: there is an chain of immediate derivation relations connecting C to C'." [PMID:15892874]
+comment: Derivation as a relation between instances. The temporal relation of derivation is more complex. Transformation, on the instance level, is just the relation of identity: each adult is identical to some child existing at some earlier time. Derivation on the instance-level is a relation holding between non-identicals. More precisely, it holds between distinct material continuants when one succeeds the other across a temporal divide in such a way that at least a biologically significant portion of the matter of the earlier continuant is inherited by the later. Thus we will have axioms to the effect that from c derives_from c1 we can infer that c and c1 are not identical and that there is some instant of time t such that c1 exists only prior to and c only subsequent to t. We will also be able to infer that the spatial region occupied by c as it begins to exist at t overlaps with the spatial region occupied by c1 as it ceases to exist in the same instant.
+exact_synonym: "derived_from" []
+inverse_of_on_instance_level: OBO_REL:derived_into
+is_transitive: true
+
+[Typedef]
+id: OBO_REL:derived_into
+alt_id: OBO_REL:0000016
+name: derived_into
+inverse_of_on_instance_level: OBO_REL:derives_from
+is_transitive: true
+
+[Typedef]
+id: OBO_REL:preceded_by
+alt_id: OBO_REL:0000017
+name: preceded_by
+def: "P preceded_by P' if and only if: given any process p that instantiates P at a time t, there is some process p' such that p' instantiates P' at time t', and t' is earlier than t. " [PMID:15892874]
+comment: An example is: translation preceded_by transcription; aging preceded_by development (not however death preceded_by aging). Where derives_from links classes of continuants, preceded_by links classes of processes. Clearly, however, these two relations are not independent of each other. Thus if cells of type C1 derive_from cells of type C, then any cell division involving an instance of C1 in a given lineage is preceded_by cellular processes involving an instance of C.    The assertion P preceded_by P1 tells us something about Ps in general: that is, it tells us something about what happened earlier, given what we know about what happened later. Thus it does not provide information pointing in the opposite direction, concerning instances of P1 in general; that is, that each is such as to be succeeded by some instance of P. Note that an assertion to the effect that P preceded_by P1 is rather weak; it tells us little about the relations between the underlying instances in virtue of which the preceded_by relation obtains. Typically we will be interested in stronger relations, for example in the relation immediately_preceded_by, or in relations which combine preceded_by with a condition to the effect that the corresponding instances of P and P1 share participants, or that their participants are connected by relations of derivation, or (as a first step along the road to a treatment of causality) that the one process in some way affects (for example, initiates or regulates) the other.
+inverse_of_on_instance_level: OBO_REL:precedes
+is_transitive: true
+
+[Typedef]
+id: OBO_REL:precedes
+alt_id: OBO_REL:0000018
+name: precedes
+inverse_of_on_instance_level: OBO_REL:preceded_by
+is_transitive: true
+
+[Typedef]
+id: OBO_REL:has_participant
+alt_id: OBO_REL:0000019
+name: has_participant
+def: "P has_participant C if and only if: given any process p that instantiates P there is some continuant c, and some time t, such that: c instantiates C at t and c participates in p at t" [PMID:15892874]
+comment: Has_participant is a primitive instance-level relation between a process, a continuant, and a time at which the continuant participates in some way in the process. The relation obtains, for example, when this particular process of oxygen exchange across this particular alveolar membrane has_participant this particular sample of hemoglobin at this particular time.
+inverse_of_on_instance_level: OBO_REL:participates_in
+
+[Typedef]
+id: OBO_REL:participates_in
+alt_id: OBO_REL:0000020
+name: participates_in
+inverse_of_on_instance_level: OBO_REL:has_participant
+
+[Typedef]
+id: OBO_REL:has_agent
+alt_id: OBO_REL:0000021
+name: has_agent
+is_a: OBO_REL:has_participant
+def: "As for has_participant, but with the additional condition that the component instance is causally active in the relevant process" [PMID:15892874]
+inverse_of_on_instance_level: OBO_REL:agent_in
+
+[Typedef]
+id: OBO_REL:agent_in
+alt_id: OBO_REL:0000022
+name: agent_in
+is_a: OBO_REL:participates_in
+inverse_of_on_instance_level: OBO_REL:has_agent
+
+[Typedef]
+id: OBO_REL:instance_of
+alt_id: OBO_REL:0000023
+name: instance_of
+builtin: true
+def: "A relation between an instance and a class. For components: a primitive relation between a component instance and a class which it instantiates at a specific time. For processes: a primitive relation, between a process instance and a class which it instantiates, holding independently of time" [PMID:15892874]
+comment: The instance_of relationship is considered axiomatic by the obo file format specification; ie it is taken for granted. The is_a relation is still included in this ontology for completeness
+
+[Typedef]
+id: OBO_REL:has_improper_part
+alt_id: OBO_REL:0000024
+name: has_improper_part
+is_a: OBO_REL:has_part
+inverse_of_on_instance_level: OBO_REL:improper_part_of
+comment: See reasons for obsoletion of improper_part_of
+is_reflexive: true
+is_transitive: true
+is_obsolete: true
+
+[Typedef]
+id: OBO_REL:improper_part_of
+alt_id: OBO_REL:0000025
+name: improper_part_of
+is_a: OBO_REL:part_of
+def: "As for part_of, with the additional constraint that subject and object may be identical" [PMID:15892874]
+comment: OBSOLETE. The definition is "As for part_of, with the additional constraint that subject and object may be identical". However, part_of is already reflexive, therefore improper_part_of is identical to part_of. If read differently, as "improper_part_of is part_of but not proper_part_of",improper_part_of becomes identity. So, improper_part_of is either identical to part_of or to identity, and not an intuitive synonym for either of them. [Robert Hoehndorf]
+inverse_of_on_instance_level: OBO_REL:has_improper_part
+is_reflexive: true
+is_transitive: true
+is_obsolete: true
+
+
+[Typedef]
+id: OBO_REL:relationship
+name: relationship
+def: "A relationship between two classes (terms). Relationships between classes are expressed in terms of relations on underlying instances." [GOC:cjm]
+is_obsolete: true
+comment: this relation was superfluous, so it has been obsoleted

+ 1 - 5
tripal_cv/includes/tripal_cv.cvterm_form.inc

@@ -37,11 +37,7 @@ function tripal_cv_cvterm_edit_form($form, &$form_state) {
     $cv_id = $form_state['build_info']['args'][0];
     $cvterm_id = $form_state['build_info']['args'][1];
     if ($form_state['build_info']['args'][1]) {
-      $result = db_select('chado.cvterm','c')
-        ->fields('c', array('name'))
-        ->condition('c.cvterm_id',$cvterm_id)
-        ->execute();
-      $cvterm_name = $result->fetchObject()->name;
+      $cvterm_name = chado_query('SELECT name FROM {cvterm} WHERE cvterm_id=:id', array(':id' => $cvterm_id))->fetchField();
       $step = 1;
     }
   }

+ 4 - 18
tripal_cv/includes/tripal_cv.obo_loader.inc

@@ -105,7 +105,7 @@ function tripal_cv_obo_form($form, &$form_state) {
       $matches = array();
       if (preg_match('/\{(.*?)\}/', $uobo_file, $matches)) {
         $modpath = drupal_get_path('module', $matches[1]);
-        $uobo_file = '/' . preg_replace('/\{.*?\}/', $modpath, $uobo_file);
+        $uobo_file = preg_replace('/\{.*?\}/', $modpath, $uobo_file);
       }
     }
     // We don't want the previous value to remain. We want the new default to
@@ -955,26 +955,12 @@ function tripal_cv_obo_add_relationship($cvterm, $defaultcv, $rel,
     'is_obsolete' => 0,
     'cv_name' => $defaultcv,
     'is_relationship' => TRUE,
-    'db_naame' => $default_db
+    'db_name' => $default_db
   );
   $relcvterm = tripal_insert_cvterm($term, array('update_existing' => FALSE));
 
   if (!$relcvterm) {
-    // if the relationship term couldn't be found in the default_db provided
-    // then do on more check to find it in the relationship ontology
-    $term = array(
-      'name' => $rel,
-      'id' => "OBO_REL:$rel",
-      'definition' => '',
-      'is_obsolete' => 0,
-      'cv_name' => $defaultcv,
-      'is_relationship' => TRUE,
-      'db_name' => 'OBO_REL'
-    );
-    $relcvterm = tripal_insert_cvterm($term, array('update_existing' => FALSE));
-    if (!$relcvterm) {
-      tripal_cv_obo_quiterror("Cannot find the relationship term in the current ontology or in the relationship ontology: $rel\n");
-    }
+    tripal_cv_obo_quiterror("Cannot find the relationship term in the current ontology: $rel\n");
   }
 
   // get the object term
@@ -1433,7 +1419,7 @@ function tripal_cv_obo_add_dbxref($db_id, $accession, $version='', $description=
       tripal_cv_obo_quiterror("Failed to insert the dbxref record $accession");
       return FALSE;
     }
-    $result = chado_select_record('dbxref', array('dbxref_id'), $values, $options);
+    $result = chado_select_record('dbxref', array('dbxref_id'), $values);
   }
   return $result[0];
 }

+ 1 - 1
tripal_cv/tripal_cv.info

@@ -3,7 +3,7 @@ description = Supports the Controlled Vocabulary (CV) tables of Chado by providi
 core = 7.x
 project = tripal
 package = Tripal
-version = 7.x-2.1-beta2
+version = 7.x-2.1
 configure = admin/tripal/chado/tripal_cv
 
 dependencies[] = tripal_core

+ 51 - 8
tripal_cv/tripal_cv.install

@@ -73,9 +73,9 @@ function tripal_cv_install() {
 function tripal_cv_uninstall() {
 
   // drop the tripal_obo_temp table
-  if (db_table_exists('chado.tripal_obo_temp')) {
-    $sql = "DROP TABLE chado.tripal_obo_temp";
-    db_query($sql);
+  if (chado_table_exists('tripal_obo_temp')) {
+    $sql = "DROP TABLE {tripal_obo_temp}";
+    chado_query($sql);
   }
 }
 
@@ -90,7 +90,7 @@ function tripal_cv_create_tripal_obo_temp() {
   // do not want to use the Tripal Custom Table API because we don't want it to appear in the
   // list of custom tables.  It needs to be available for the Tripal Chado API so we create it
   // here and then define it in the tripal_cv/api/tripal_cv.schema.api.inc
-  if (!db_table_exists('chado.tripal_obo_temp')) {
+  if (!chado_table_exists('tripal_obo_temp')) {
     $sql = "
       CREATE TABLE {tripal_obo_temp} (
         id character varying(255) NOT NULL,
@@ -203,10 +203,12 @@ function tripal_cv_add_cv_root_mview() {
         'not null' => TRUE,
       ),
       'cvterm_id' => array(
+        'size' => 'big',
         'type' => 'int',
         'not null' => TRUE,
       ),
       'cv_id' => array(
+        'size' => 'big',
         'type' => 'int',
         'not null' => TRUE,
       ),
@@ -244,10 +246,10 @@ function tripal_cv_add_obo_defaults() {
 
   // Insert commonly used ontologies into the tables.
   $ontologies = array(
-    array('Relationship Ontology', 'http://purl.obolibrary.org/obo/ro.obo'),
+//    array('Relationship Ontology', 'http://purl.obolibrary.org/obo/ro.obo'),
 //    array('Relationship Ontology (older deprecated version)', 'http://www.obofoundry.org/ro/ro.obo'),
-    array('Sequence Ontology', 'https://raw.githubusercontent.com/The-Sequence-Ontology/SO-Ontologies/master/so-xp-simple.obo'),
-    array('Gene Ontology', 'http://www.geneontology.org/ontology/gene_ontology.obo'),
+    array('Sequence Ontology', 'http://purl.obolibrary.org/obo/so.obo'),
+    array('Gene Ontology', 'http://purl.obolibrary.org/obo/go.obo'),
 //    array('Cell Ontology', 'https://raw.githubusercontent.com/obophenotype/cell-ontology/master/cl.obo'),
 //    array('Plant Structure Ontology', 'http://palea.cgrb.oregonstate.edu/viewsvn/Poc/trunk/ontology/OBO_format/po_anatomy.obo?view=co'),
 //    array('Plant Growth and Development Stages Ontology', 'http://palea.cgrb.oregonstate.edu/viewsvn/Poc/trunk/ontology/OBO_format/po_temporal.obo?view=co')
@@ -320,6 +322,47 @@ function tripal_cv_update_7201() {
   }
 }
 
+/**
+ * Changes the URLs for OBOs.
+ */
+function tripal_cv_update_7202() {
+  // Make sure we have the full API loaded this will help during a
+  // site upgrade when the tripal_core module is disabled.
+  module_load_include('module', 'tripal_core', 'tripal_core');
+  tripal_core_import_api();
+
+  // add in the new tripal_cv_defaults table
+  try {
+
+    // Convert the OBO's to their appropriate PURL link
+    db_update('tripal_cv_obo')
+      ->fields(array(
+        'path' => 'http://purl.obolibrary.org/obo/so.obo',
+      ))
+      ->condition('name', 'Sequence Ontology')
+      ->execute();
+
+    db_update('tripal_cv_obo')
+      ->fields(array(
+        'path' => 'http://purl.obolibrary.org/obo/go.obo',
+      ))
+      ->condition('name', 'Gene Ontology')
+      ->execute();
+
+    db_update('tripal_cv_obo')
+      ->fields(array(
+        'name' => 'Relationship Ontology (legacy)',
+        'path' => '{tripal_cv}/files/legacy_ro.obo',
+      ))
+      ->condition('name', 'Relationship Ontology')
+      ->execute();
+  }
+  catch (\PDOException $e) {
+    $error = $e->getMessage();
+    throw new DrupalUpdateException('Failed to create tripal_cv_defaults table: '. $error);
+  }
+}
+
 /**
  * Implementation of hook_update_dependencies().
  *
@@ -332,4 +375,4 @@ function tripal_cv_update_dependencies() {
   $dependencies = array();
 
   return $dependencies;
-}
+}

+ 1 - 1
tripal_cv/tripal_cv.module

@@ -154,7 +154,7 @@ function tripal_cv_menu() {
     'type' => MENU_CALLBACK,
   );
   $items['admin/tripal/chado/tripal_cv/cvterm/auto_name/%/%'] = array(
-    'page callback' => 'tripal_cv_cvterm_name_autocomplete',
+    'page callback' => 'tripal_autocomplete_cvterm',
     'page arguments' => array(6, 7),
     'access arguments' => array('administer controlled vocabularies'),
     'type' => MENU_CALLBACK,

+ 8 - 6
tripal_db/api/tripal_db.api.inc

@@ -141,7 +141,7 @@ function tripal_get_db_select_options() {
 
   $options = array();
   $options[] = 'Select a Database';
-  
+
   foreach ($dbs as $db) {
     $options[$db->db_id] = $db->name;
   }
@@ -179,10 +179,12 @@ function tripal_get_db_select_options() {
  * @endcode
  *
  * @param $identifier
- *   An array with the key stating what the identifier is. Supported keys (only one of the
- *   following unique keys is required):
- *    - dbxref_id: the chado dbxref.dbxref_id primary key
- *    - accession: the chado dbxref.accession field (assume unique)
+ *   An array apropriate for use with the chado_generate_var for uniquely
+ *   identifying a dbxref record. Alternatively, there are also some specially
+ *   handled keys. They are:
+ *    - property: An array/object describing the property to select records for. It
+ *      should at least have either a type_name (if unique across cvs) or type_id. Other
+ *      supported keys include: cv_id/cv_name (of the type), value and rank
  *   There are also some specially handled keys. They are:
  *    - property: An array/object describing the property to select records for. It
  *      should at least have either a type_name (if unique across cvs) or type_id. Other
@@ -240,7 +242,7 @@ function tripal_get_dbxref($identifiers, $options = array()) {
     $property = $identifiers['property'];
     unset($identifiers['property']);
     $dbxref = chado_get_record_with_property(
-      array('table' => 'dbxref', 'base_records' => $identifiers), 
+      array('table' => 'dbxref', 'base_records' => $identifiers),
       array('type_name' => $property),
       $options
     );

+ 1 - 1
tripal_db/tripal_db.info

@@ -3,7 +3,7 @@ description = Supports the database cross-reference tables of Chado by providing
 core = 7.x
 project = tripal
 package = Tripal
-version = 7.x-2.1-beta2
+version = 7.x-2.1
 configure = admin/tripal/chado/tripal_db
 
 dependencies[] = tripal_core

+ 1 - 1
tripal_db/tripal_db.views_default.inc

@@ -47,7 +47,7 @@ function tripal_db_defaultview_admin_db_listing() {
   $handler->display->display_options['title'] = 'Databases';
   $handler->display->display_options['use_more_always'] = FALSE;
   $handler->display->display_options['access']['type'] = 'perm';
-  $handler->display->display_options['access']['perm'] = 'access chado_db content';
+  $handler->display->display_options['access']['perm'] = 'administer db cross-references';
   $handler->display->display_options['cache']['type'] = 'none';
   $handler->display->display_options['query']['type'] = 'views_query';
   $handler->display->display_options['exposed_form']['type'] = 'input_required';

+ 1 - 1
tripal_example/includes/tripal_example.chado_node.inc

@@ -70,7 +70,7 @@ function tripal_example_node_info() {
  * value is TRUE then access is granted regardless of any other rules that might
  * be implemented by other modules.
  */
-function chado_example_node_access($node, $op, $account) {
+function tripal_example_node_access($node, $op, $account) {
   $node_type = $node;
   if (is_object($node)) {
     $node_type = $node->type;

+ 1 - 1
tripal_example/tripal_example.info

@@ -26,7 +26,7 @@ package = Tripal Extensions
 ; Follow these instructions when specifying the version:
 ; https://drupal.org/node/1015226
 ;
-version = 7.x-2.1-beta2
+version = 7.x-2.1
 
 ;
 ; Style-sheets containing CSS that should always be available for the

+ 158 - 153
tripal_feature/api/tripal_feature.api.inc

@@ -45,59 +45,67 @@ function tripal_reverse_compliment_sequence($sequence) {
 }
 
 /**
- * Retrieves the sequences for a given feature. If a feature has multiple alignments
- *  or multiple relationships then multiple sequences will be returned.
+ * Retrieves the sequences for a given feature.
+ *
+ * If a feature has multiple alignments or multiple relationships then
+ * multiple sequences will be returned.
  *
  * @param $feature
  *   An associative array describing the feature. Valid keys include:
- *    - feature_id: The feature_id of the feature for which the sequence will be retrieved
+ *    - feature_id: The feature_id of the feature for which the sequence will
+ *      be retrieved
  *    - name: The feature name. This will appear on the FASTA definition line
- *    - parent_id:  (optional) only retrieve a sequence if 'derive_from_parent' is true 
- *        and the parent matches this ID.
- *    - featureloc_id: (optional) only retrieve a sequence if 'derive_from_parent' is 
- *        true and the alignment is defined with this featureloc_id
+ *    - parent_id:  (optional) only retrieve a sequence if 'derive_from_parent'
+ *      is true and the parent matches this ID.
+ *    - featureloc_id: (optional) only retrieve a sequence if 'derive_from_parent' is
+ *      true and the alignment is defined with this featureloc_id
  * @param $options
  *   An associative array of options. Valid keys include:
- *    - width: Indicate the number of bases to use per line.  A new line will be added
- *        after the specified number of bases on each line.
- *    - is_html: Set to '1' if  the sequence is meant to be displayed on a web page.
- *        This will cause a <br> tag to separate lines of the FASTA sequence. 
- *    - derive_from_parent: Set to '1' if the sequence should be obtained from the parent
- *        to which this feature is aligned.
- *    - aggregate: Set to '1' if the sequence should only contain sub features, excluding
- *        intro sub feature sequence.  For example, set this option to obtain just
- *        the coding sequence of an mRNA.
- *    - upstream: An integer specifing the number of upstream bases to include in the output
- *    - downstream: An integer specifying the number of downstream bases to include in the
- *        output.
- *    - sub_feature_types: Only include sub features (or child features) of the types
- *        provided in the array
- *    - relationship_type: If a relationship name is provided (e.g. sequence_of) then any
- *        sequences that are in relationships of this type with matched sequences are also included
- *    - relationship_part: If a relationship is provided in the preceeding argument then
- *        the rel_part must be either 'object' or 'subject' to indicate which side of the
- *        relationship the matched features belong
+ *    - width: Indicate the number of bases to use per line.  A new line will
+ *      be added after the specified number of bases on each line.
+ *    - is_html: Set to '1' if  the sequence is meant to be displayed on a web
+ *      page. This will cause a <br> tag to separate lines of the FASTA sequence.
+ *    - derive_from_parent: Set to '1' if the sequence should be obtained from
+ *      the parent to which this feature is aligned.
+ *    - aggregate: Set to '1' if the sequence should only contain sub features,
+ *      excluding intro sub feature sequence.  For example, set this option to
+ *      obtain just the coding sequence of an mRNA.
+ *    - upstream: An integer specifing the number of upstream bases to include
+ *      in the output
+ *    - downstream: An integer specifying the number of downstream bases to
+ *      include in the output.
+ *    - sub_feature_types: Only include sub features (or child features) of
+ *      the types provided in the array
+ *    - relationship_type: If a relationship name is provided (e.g. sequence_of)
+ *      then any sequences that are in relationships of this type with matched
+ *      sequences are also included
+ *    - relationship_part: If a relationship is provided in the preceeding
+ *      argument then the rel_part must be either 'object' or 'subject' to
+ *      indicate which side of the relationship the matched features belong
  *
  * @return
  *   an array of matching sequence in the following keys for each sequence:
- *      'types'         => an array of feature types that were used to derive the sequence (e.g. from an aggregated sequence)
+ *      'types'         => an array of feature types that were used to derive
+ *         the sequence (e.g. from an aggregated sequence)
  *      'upstream'      => the number of upstream bases included in the sequence
- *      'downstream'    => the number of downstream bases included in the sequence
+ *      'downstream'    => the number of downstream bases included in the
+ *        sequence
  *      'defline'       => the definintion line used to create a FASTA sequence
  *      'residues'      => the residues
- *      'featureloc_id' => the featureloc_id if the sequences is from an alignment
+ *      'featureloc_id' => the featureloc_id if the sequences is from an
+ *        alignment
  *
  * @ingroup tripal_feature_api
  */
 function tripal_get_feature_sequences($feature, $options) {
 
-  // default values for finding the feature
+  // Default values for finding the feature.
   $feature_id         = array_key_exists('feature_id', $feature)     ? $feature['feature_id']     : 0;
   $parent_id          = array_key_exists('parent_id', $feature)      ? $feature['parent_id']      : 0;
   $featureloc_id      = array_key_exists('featureloc_id', $feature)  ? $feature['featureloc_id']  : 0;
   $feature_name       = array_key_exists('name', $feature)           ? $feature['name']           : '';
 
-  // default values for building the sequence
+  // Default values for building the sequence.
   $num_bases_per_line = array_key_exists('width', $options)              ? $options['width']              : 50;
   $derive_from_parent = array_key_exists('derive_from_parent', $options) ? $options['derive_from_parent'] : 0;
   $aggregate          = array_key_exists('aggregate', $options)          ? $options['aggregate']          : 0;
@@ -107,8 +115,15 @@ function tripal_get_feature_sequences($feature, $options) {
   $relationship       = array_key_exists('relationship_type', $options)  ? $options['relationship_type']  : '';
   $rel_part           = array_key_exists('relationship_part', $options)  ? $options['relationship_part']  : '';
   $is_html            = array_key_exists('is_html', $options)            ? $options['is_html']            : 0;
-  
-  // make sure the sub_features variable is an array
+
+  if (!$upstream) {
+    $upstream = 0;
+  }
+  if (!$downstream) {
+    $downstream = 0;
+  }
+
+  // Make sure the sub_features variable is an array.
   if (!is_array($sub_features)) {
     tripal_report_error('tripal_feature', TRIPAL_ERROR,
       "'sub_features' option must be an array for function tripal_get_feature_sequences().",
@@ -117,9 +132,9 @@ function tripal_get_feature_sequences($feature, $options) {
     return array();
   }
 
-  // if a relationship was specified then retreive and the sequences that
-  // have the given relationship and the recurse to extract the appropriate 
-  // sequence
+  // If a relationship was specified then retreive and the sequences that
+  // have the given relationship and the recurse to extract the appropriate
+  // sequence.
   if ($rel_part == "object" or $rel_part == "subject") {
     if ($rel_part == "subject") {
       $sql = '
@@ -154,7 +169,7 @@ function tripal_get_feature_sequences($feature, $options) {
     $sequences = '';
     while ($feature = $features->fetchObject()) {
 
-      // recurse and get the sequences for these in the relationship
+      // Recurse and get the sequences for these in the relationship.
       if ($rel_part == "subject") {
         $defline = "$feature_name, $relationship, $feature->uniquename $feature->feature_type ($feature->genus $feature->species)";
       }
@@ -163,23 +178,23 @@ function tripal_get_feature_sequences($feature, $options) {
       }
       return tripal_get_feature_sequences(
         array(
-          'feature_id' => $feature->feature_id, 
+          'feature_id' => $feature->feature_id,
           'name' => $defline,
           'parent_id' => $parent_id,
         ),
         array(
-          'width' => $num_bases_per_line, 
-          'derive_from_parent' => $derive_from_parent, 
-          'aggregate' => $aggregate, 
-          'upstream' => $upstream, 
-          'downstream' => $downstream, 
-          'sub_features' => $sub_features, 
+          'width' => $num_bases_per_line,
+          'derive_from_parent' => $derive_from_parent,
+          'aggregate' => $aggregate,
+          'upstream' => $upstream,
+          'downstream' => $downstream,
+          'sub_features' => $sub_features,
         )
       );
     }
   }
 
-  // prepare the queries we're going to use later during the render phase
+  // Prepare the queries we're going to use later during the render phase
   // This SQL statement uses conditionals in the select clause to handle
   // cases cases where the alignment is in the reverse direction and when
   // the upstream and downstream extensions go beyond the lenght of the
@@ -187,7 +202,7 @@ function tripal_get_feature_sequences($feature, $options) {
   $parent_sql ='
     SELECT featureloc_id, srcname, srcfeature_id, strand, srctypename, typename,
       fmin, fmax, upstream, downstream, adjfmin, adjfmax,
-      substring(residues from (adjfmin + 1) for (upstream + (fmax - fmin) + downstream))  as residues,
+      substring(residues from (cast(adjfmin as int4) + 1) for cast((upstream + (fmax - fmin) + downstream) as int4))  as residues,
       genus, species
     FROM (
       SELECT
@@ -251,7 +266,7 @@ function tripal_get_feature_sequences($feature, $options) {
         INNER JOIN {organism} OO  on OF.organism_id   = OO.organism_id
       WHERE SF.feature_id = :feature_id and NOT (OF.residues = \'\' or OF.residues IS NULL)) as tbl1
   ';
-  // this query is meant to get all of the sub features of any given
+  // This query is meant to get all of the sub features of any given
   // feature (arg #1) and order them as they appear on the reference
   // feature (arg #2).
   $sfsql = '
@@ -264,7 +279,7 @@ function tripal_get_feature_sequences($feature, $options) {
     WHERE FR.object_id = :feature_id and PF.feature_id = :srcfeature_id
     ORDER BY FL.fmin ASC
   ';
-  // for counting the number of children
+  // For counting the number of children.
   $fsql ='
     SELECT count(*) as num_children
     FROM {feature_relationship} FR
@@ -275,26 +290,30 @@ function tripal_get_feature_sequences($feature, $options) {
     WHERE FR.object_id = :feature_id and PF.feature_id = :srcfeature_id
   ';
 
-  // the array to be returned
+  // The array to be returned.
   $sequences = array();
-  
-  // if we need to get the sequence from the parent then do so now.
+
+  // If we need to get the sequence from the parent then do so now.
   if ($derive_from_parent) {
 
-    // execute the query to get the sequence from the parent
+    // Execute the query to get the sequence from the parent.
     $parents = chado_query($parent_sql, array(':upstream' => $upstream, ':downstream' => $downstream, ':feature_id' => $feature_id));
     while ($parent = $parents->fetchObject()) {
-      
-      // if the user specified a particular parent and this one doesn't match then skip it
+
+      // If the user specified a particular parent and this one doesn't
+      // match then skip it.
       if ($parent_id and $parent_id != $parent->srcfeature_id) {
         continue;
       }
-      // if the user specified a particular featureloc_id and this one doesn't match then skip it
+      // if the user specified a particular featureloc_id and this one
+      // doesn't match then skip it.
       if ($featureloc_id and $featureloc_id != $parent->featureloc_id) {
         continue;
       }
-      $seq = '';  // initialize the sequence for each parent
+      // Initialize the sequence for each parent.
+      $seq = '';
       $notes = '';
+      $types = array();
 
       // if we are to aggregate then we will ignore the feature returned
       // by the query above and rebuild it using the sub features
@@ -304,17 +323,16 @@ function tripal_get_feature_sequences($feature, $options) {
         $children = chado_query($sfsql, array(':feature_id' => $feature_id, ':srcfeature_id' => $parent->srcfeature_id));
         $num_children = chado_query($fsql, array(':feature_id' => $feature_id, ':srcfeature_id' => $parent->srcfeature_id))->fetchField();
 
-        // iterate through the sub features and concat their sequences. They
+        // Iterate through the sub features and concat their sequences. They
         // should already be in order.
-        $types = array();
         $i = 0;
         while ($child = $children->fetchObject()) {
-          // if the callee has specified that only certain sub features should be
+          // If the callee has specified that only certain sub features should be
           // included then continue if this child is not one of those allowed
-          // subfeatures
+          // subfeatures.
           if (count($sub_features) > 0 and !in_array($child->type_name, $sub_features)) {
             $i++;
-             continue;
+            continue;
           }
 
           // keep up with the types
@@ -360,7 +378,7 @@ function tripal_get_feature_sequences($feature, $options) {
             if ($subseq->srcfeature_id == $parent->srcfeature_id) {
               $seq .= $subseq->residues;
             }
-            if ($subseq->upstream > 0 ) { 
+            if ($subseq->upstream > 0 ) {
               $notes .= "Includes " . $subseq->upstream . " bases upstream.  ";
             }
             if ($subseq->downstream > 0) {
@@ -403,9 +421,9 @@ function tripal_get_feature_sequences($feature, $options) {
         $notes .= "Excludes all bases but those of type(s): " . implode(', ', $types) . ". " ;
       }
 
-      // construct the definition line for this feature.
-      // to construct the defline we need a featureloc record, so we'll create one using
-      // the information we have
+      // Construct the definition line for this feature. To construct the
+      // defline we need a featureloc record, so we'll create one using
+      // the information we have.
       $featureloc = new stdClass;
       $featureloc->feature_id = $feature;
       $featureloc->fmin = $parent->adjfmin;
@@ -417,10 +435,10 @@ function tripal_get_feature_sequences($feature, $options) {
       $featureloc->srcfeature_id->organism_id = new stdClass;
       $featureloc->srcfeature_id->organism_id->genus = $parent->genus;
       $featureloc->srcfeature_id->organism_id->species = $parent->species;
-      // get a proper feature object
+      // Get a proper feature object.
       $f = chado_generate_var('feature', array('feature_id' => $feature_id));
       $defline = tripal_get_fasta_defline($f, $notes, $featureloc, '', $length);
-      
+
       $sequences[] = array(
         'types'         => $types,
         'upstream'      => $parent->upstream,
@@ -432,12 +450,14 @@ function tripal_get_feature_sequences($feature, $options) {
       );
     }
   }
-  // if we are not getting the sequence from the parent sequence then
-  // use what comes through from the feature record
+  // If we are not getting the sequence from the parent sequence then
+  // use what comes through from the feature record.
   else {
-    $sql = "SELECT * FROM {feature} F WHERE feature_id = :feature_id";
-    $values = chado_query($sql, array(':feature_id' => $feature_id))->fetchObject();
-    $residues = $values->residues;
+
+    $f = chado_generate_var('feature', array('feature_id' => $feature_id));
+    $f = chado_expand_var($f, 'field', 'feature.residues');
+
+    $residues = $f->residues;
     $length = strlen($residues);
     if ($is_html) {
       $residues = wordwrap($residues, $num_bases_per_line, "<br>", TRUE);
@@ -445,14 +465,13 @@ function tripal_get_feature_sequences($feature, $options) {
     else {
       $residues = wordwrap($residues, $num_bases_per_line, "\r\n", TRUE);
     }
-    
+
     // get the definintion line for this feature
-    $f = chado_generate_var('feature', array('feature_id' => $feature_id));
     $defline = tripal_get_fasta_defline($f, '', NULL, '', $length);
 
     // add to the sequence array
     $sequences[] = array(
-      'types'      => $values->type,
+      'types'      => $f->type_id->name,
       'upstream'   => 0,
       'downstream' => 0,
       'defline'    => $defline,
@@ -465,49 +484,52 @@ function tripal_get_feature_sequences($feature, $options) {
 }
 
 /**
- * Retreives or prints multiple sequences from features found using the options provided.
  *
  * @param $options
  *   An associative array of options for selecting a feature. Valid keys include:
- *    - org_commonname: The common name of the organism for which sequences should be retrieved
+ *    - org_commonname: The common name of the organism for which sequences
+ *      should be retrieved
  *    - genus: The genus of the organism for which sequences should be retrieved
- *    - species: The species of the organism for which sequences should be retrieved
- *    - analysis_name: The name of an analysis to which sequences belong. Only those that are
- *        associated with the analysis will be retrieved.
+ *    - species: The species of the organism for which sequences should be
+ *      retrieved
+ *    - analysis_name: The name of an analysis to which sequences belong. Only
+ *      those that are associated with the analysis will be retrieved.
  *    - type: The type of feature (a sequence ontology term).
  *    - feature_name: the name of the feature. Can be an array of feature names.
- *    - feature_uname: the uniquename of the feature.  Can be an array of feature unique names.
- *    - upstream: An integer specifing the number of upstream bases to include in the output
- *    - downstream: An integer specifying the number of downstream bases to include in the
- *        output.
- *    - derive_from_parent: Set to '1' if the sequence should be obtained from the parent
- *        to which this feature is aligned.
- *    - aggregate: Set to '1' if the sequence should only contain sub features, excluding
- *        intro sub feature sequence.  For example, set this option to obtain just
- *        the coding sequence of an mRNA.
- *    - sub_feature_types: Only include sub features (or child features) of the types
- *        provided in the array
- *    - relationship_type: If a relationship name is provided (e.g. sequence_of) then any
- *        sequences that are in relationships of this type with matched sequences are also included
- *    - relationship_part: If a relationship is provided in the preceeding argument then
- *        the rel_part must be either 'object' or 'subject' to indicate which side of the
- *        relationship the matched features belong
- *    - width: Indicate the number of bases to use per line.  A new line will be added
- *        after the specified number of bases on each line.
- *    - is_html: Set to '1' if  the sequence is meant to be displayed on a web page.
- *        This will cause a <br> tag to separate lines of the FASTA sequence. 
- *    - print: Set to TRUE to print the sequences rather otherwise an array
- *        of sequences will be returned.  
+ *    - feature_uname: the uniquename of the feature.  Can be an array of
+ *      feature unique names.
+ *    - upstream: An integer specifing the number of upstream bases to include
+ *      in the output
+ *    - downstream: An integer specifying the number of downstream bases to
+ *      include in the output.
+ *    - derive_from_parent: Set to '1' if the sequence should be obtained from
+ *      the parent to which this feature is aligned.
+ *    - aggregate: Set to '1' if the sequence should only contain sub features,
+ *      excluding intro sub feature sequence.  For example, set this option to
+ *      obtain just the coding sequence of an mRNA.
+ *    - sub_feature_types: Only include sub features (or child features) of
+ *      the types provided in the array
+ *    - relationship_type: If a relationship name is provided (e.g. sequence_of)
+ *      then any sequences that are in relationships of this type with matched
+ *      sequences are also included
+ *    - relationship_part: If a relationship is provided in the preceeding
+ *      argument then the rel_part must be either 'object' or 'subject' to
+ *      indicate which side of the relationship the matched features belong
+ *    - width: Indicate the number of bases to use per line.  A new line will
+ *      be added after the specified number of bases on each line.
+ *    - is_html: Set to '1' if  the sequence is meant to be displayed on a
+ *      web page. This will cause a <br> tag to separate lines of the FASTA
+ *      sequence.
  * @return
- *   Returns an array of sequences unless the option 'print' is used.  If 'print is used
- *   then nothing is returned but sequences are printed to STDOUT.  If returned, the 
- *   sequences will be in an array with the following keys for each sequence:
- *      'types'         => an array of feature types that were used to derive the sequence (e.g. from an aggregated sequence)
- *      'upstream'      => the number of upstream bases included in the sequence
- *      'downstream'    => the number of downstream bases included in the sequence
+ *   Returns an array of sequences. The sequences will be in an array with the
+ *   following keys for each sequence:
+ *      'types'         => an array of feature types that were used to derive
+ *         the sequence (e.g. from an aggregated sequence)
+ *      'upstream'      => the number of upstream bases in the sequence
+ *      'downstream'    => the number of downstream bases in the sequence
  *      'defline'       => the definintion line used to create a FASTA sequence
  *      'residues'      => the residues
- *      'featureloc_id' => the featureloc_id if the sequences is from an alignment
+ *      'featureloc_id' => the featureloc_id if from an alignment
  *
  * @ingroup tripal_feature_api
  */
@@ -529,13 +551,6 @@ function tripal_get_bulk_feature_sequences($options) {
   $num_bases_per_line = array_key_exists('width', $options)              ? $options['width']              : 50;
   $upstream           = array_key_exists('upstream', $options)           ? $options['upstream']       : 0;
   $downstream         = array_key_exists('downstream', $options)         ? $options['downstream']     : 0;
-  $print              = array_key_exists('print', $options)              ? $options['print']              : FALSE;
-
-  $sub_features = explode(',', $child);
-
-  if (!$output_format) {
-    $output_format = 'fasta_txt';
-  }
 
   if (!$type and !$feature_name and !$genus) {
     print "Please provide a type, feature name or genus\n";
@@ -544,13 +559,18 @@ function tripal_get_bulk_feature_sequences($options) {
 
   // get the list of features
   $vars = array();
-  $sql  = "SELECT DISTINCT F.feature_id, F.name, F.uniquename, O.genus, O.species, CVT.name as feature_type " .
-      "FROM {feature} F " .
-      "  INNER JOIN {organism} O on O.organism_id = F.organism_id " .
-      "  INNER JOIN {cvterm} CVT on CVT.cvterm_id = F.type_id ";
+  $sql  = "
+    SELECT DISTINCT F.feature_id, F.name, F.uniquename,
+      O.genus, O.species, CVT.name as feature_type
+    FROM {feature} F
+      INNER JOIN {organism} O on O.organism_id = F.organism_id
+      INNER JOIN {cvterm} CVT on CVT.cvterm_id = F.type_id
+  ";
   if ($analysis_name) {
-    $sql .= "  INNER JOIN {analysisfeature} AF on AF.feature_id = F.feature_id " .
-        "  INNER JOIN {analysis} A on AF.analysis_id = A.analysis_id ";
+    $sql .= "
+      INNER JOIN {analysisfeature} AF on AF.feature_id = F.feature_id
+      INNER JOIN {analysis} A on AF.analysis_id = A.analysis_id
+    ";
   }
   $sql .= "WHERE (1=1) ";
   if ($org_commonname) {
@@ -607,35 +627,20 @@ function tripal_get_bulk_feature_sequences($options) {
   $num_seqs = 0;
   $q = chado_query($sql, $vars);
 
-
   $sequences = array();
   while ($feature = $q->fetchObject()) {
-
     // get the sequences
     $seqs = tripal_get_feature_sequences(array('feature_id' => $feature->feature_id), $options);
-
-    if ($print) {
-      foreach ($seqs as $seq) {
-        print ">" . $seq['defline'] . "\n";
-        print $seq['residues'] . "\n";
-      }
-    }
-    else {
-      $sequences = array_merge($sequences, $seqs);
-    }
+    $sequences = array_merge($sequences, $seqs);
     $num_seqs++;
   }
-  if (!$print) {
-    return $seqs;
-  }
-  elseif ($num_seqs == 0) {
-    print "No Sequences Found";
-  }
+
+  return $sequences;
 }
 
 /**
  * Returns a definition line that can be used in a FASTA file
- * 
+ *
  * @param $feature
  *   A single feature object containing all the fields from the chado.feature table.
  *   Best case is to provide an object generated by the chado_generate_var() function.
@@ -650,13 +655,13 @@ function tripal_get_bulk_feature_sequences($options) {
  *   Optional: the type of sequence. By default the feature type is used.
  * @param $length
  *   Optional: the length of the sequence
- *   
+ *
  * @return
  *   A string of the format: uniquename|name|type|feature_id
- *   or if an alignment:  srcfeature_name:fmin..fmax[+-]; alignment of uniquename|name|type|feature_id 
+ *   or if an alignment:  srcfeature_name:fmin..fmax[+-]; alignment of uniquename|name|type|feature_id
  */
 function tripal_get_fasta_defline($feature, $notes = '', $featureloc = NULL, $type = '', $length = 0) {
-    
+
   // make sure the featureloc object has the srcfeature if not, then add it
   if ($featureloc) {
     if (!is_object($featureloc->srcfeature_id)) {
@@ -670,18 +675,18 @@ function tripal_get_fasta_defline($feature, $notes = '', $featureloc = NULL, $ty
   if (!is_object($feature->organism_id)) {
     $feature->organism_id = chado_generate_var('organism', array('organism_id' => $feature->organism_id));
   }
-  
+
   // if a type is not provided then use the default type
   if (!$type) {
     $type = $feature->type_id->name;
   }
-  
+
   // construct the definition line
-  $defline = $feature->uniquename . " " . 
+  $defline = $feature->uniquename . " " .
              'ID=' . $feature->uniquename . "|" .
-             'Name=' . $feature->name . "|" . 
+             'Name=' . $feature->name . "|" .
              'organism=' . $feature->organism_id->genus . " " . $feature->organism_id->species .  "|" .
-             'type=' . $type . '|'; 
+             'type=' . $type . '|';
   if ($length > 0) {
     $defline .= "length=" . $length . "bp|";
   }
@@ -698,14 +703,14 @@ function tripal_get_fasta_defline($feature, $notes = '', $featureloc = NULL, $ty
 
 /**
  * Returns a string representing a feature location in an alignment
- *  
+ *
  * @param unknown $featureloc
  *   A single featureloc object generated using chado_generate_var that
  *   contains a record from the chado.featureloc table.
  */
 function tripal_get_location_string($featureloc) {
   $feature = $featureloc->feature_id;
-  
+
   $strand = '';
   if ($featureloc->strand == 1) {
     $strand = '+';
@@ -713,7 +718,7 @@ function tripal_get_location_string($featureloc) {
   elseif ($featureloc->strand == -1) {
     $strand = '-';
   }
-  
-  return $featureloc->srcfeature_id->name . ":" . ($featureloc->fmin + 1) . ".." . $featureloc->fmax .  $strand;  
+
+  return $featureloc->srcfeature_id->name . ":" . ($featureloc->fmin + 1) . ".." . $featureloc->fmax .  $strand;
 }
 

+ 5 - 9
tripal_feature/includes/tripal_feature.chado_node.inc

@@ -370,12 +370,11 @@ function chado_feature_validate($node, $form, &$form_state) {
  *
  * @ingroup tripal_feature
  */
-function chado_feature_node_access($node, $op, $account) {
+function tripal_feature_node_access($node, $op, $account) {
   $node_type = $node;
   if (is_object($node)) {
     $node_type = $node->type;
   }
-
   if($node_type == 'chado_feature') {
     if ($op == 'create') {
       if (!user_access('create chado_feature content', $account)) {
@@ -434,10 +433,10 @@ function chado_feature_insert($node) {
 
     // get the feature type id
     $values = array(
-        'cv_id' => array(
+      'cv_id' => array(
             'name' => 'sequence'
-        ),
-        'name' => $node->feature_type
+      ),
+      'name' => $node->feature_type
     );
     $type = chado_select_record('cvterm', array('cvterm_id'), $values);
 
@@ -772,10 +771,7 @@ function tripal_feature_node_presave($node) {
         $organism_id = $node->feature->organism_id;
         $name        = $node->feature->name;
         $uname       = $node->feature->uniquename;
-        $type_id     = $node->feature->type_id;
-        $values = array('cvterm_id' => $type_id);
-        $ftype = chado_select_record('cvterm', array('name'), $values);
-        $type = $ftype[0]->name;
+        $type        = $node->feature->cvtname;
       }
 
       $values = array('organism_id' => $organism_id);

+ 43 - 26
tripal_feature/includes/tripal_feature.fasta_loader.inc

@@ -389,7 +389,7 @@ function tripal_feature_load_fasta($dfile, $organism_id, $type, $re_name, $re_un
   $db_id, $rel_type, $re_subject, $parent_type, $method, $uid, $analysis_id, $match_type,
   $job = NULL) {
   $transaction = db_transaction();
-  print "\nNOTE: Loading of this GFF file is performed using a database transaction. \n" .
+  print "\nNOTE: Loading of this Fasta file is performed using a database transaction. \n" .
      "If the load fails or is terminated prematurely then the entire set of \n" .
      "insertions/updates is rolled back and will not be found in the database\n\n";
   try {
@@ -410,10 +410,11 @@ function tripal_feature_load_fasta($dfile, $organism_id, $type, $re_name, $re_un
     }
 
     // Second, if there is a parent type then get that.
+    $parentcvterm = NULL;
     if ($parent_type) {
       $parentcvterm = chado_query($cvtermsql, array(':cvname' => 'sequence', ':name' => $parent_type,':synonym' => $parent_type))->fetchObject();
       if (!$parentcvterm) {
-        tripal_report_error("T_fasta_loader", TRIPAL_ERROR, "Cannot find the paretne term type: '%type'", array(
+        tripal_report_error("T_fasta_loader", TRIPAL_ERROR, "Cannot find the parent term type: '%type'", array(
           '%type' => $parentcvterm
         ));
         return 0;
@@ -421,6 +422,7 @@ function tripal_feature_load_fasta($dfile, $organism_id, $type, $re_name, $re_un
     }
 
     // Third, if there is a relationship type then get that.
+    $relcvterm = NULL;
     if ($rel_type) {
       $relcvterm = chado_query($cvtermsql, array(':cvname' => 'sequence',':name' => $rel_type,':synonym' => $rel_type))->fetchObject();
       if (!$relcvterm) {
@@ -460,7 +462,10 @@ function tripal_feature_load_fasta($dfile, $organism_id, $type, $re_name, $re_un
     $num_seqs = 0;
     $prev_pos = 0;
     $set_start = FALSE;
+    $intv_read = 0;
+    $line_num = 0;
     while ($line = fgets($fh)) {
+      $line_num++;
       $num_read += strlen($line);
       $intv_read += strlen($line);
 
@@ -472,6 +477,7 @@ function tripal_feature_load_fasta($dfile, $organism_id, $type, $re_name, $re_un
         $defline = preg_replace("/^>/", '', $line);
 
         // Get the feature name if a regular expression is provided.
+        $name = "";
         if ($re_name) {
           if (!preg_match("/$re_name/", $defline, $matches)) {
             tripal_report_error('trp-fasta', TRIPAL_ERROR, "ERROR: Regular expression for the feature name finds nothing. Line %line.", array(
@@ -506,6 +512,7 @@ function tripal_feature_load_fasta($dfile, $organism_id, $type, $re_name, $re_un
         }
 
         // Get the feature uniquename if a regular expression is provided.
+        $uname = "";
         if ($re_uname) {
           if (!preg_match("/$re_uname/", $defline, $matches)) {
             tripal_report_error('trp-fasta', TRIPAL_ERROR, "ERROR: Regular expression for the feature unique name finds nothing. Line %line.", array(
@@ -515,7 +522,7 @@ function tripal_feature_load_fasta($dfile, $organism_id, $type, $re_name, $re_un
         }
         // If the match_type is name and no regular expression was provided
         // then use the first word as the name, otherwise, we don't set the
-        // unqiuename.
+        // uniquename.
         elseif (strcmp($match_type, 'Unique name') == 0) {
           if (preg_match("/^\s*(.*?)[\s\|].*$/", $defline, $matches)) {
             $uname = trim($matches[1]);
@@ -527,19 +534,25 @@ function tripal_feature_load_fasta($dfile, $organism_id, $type, $re_name, $re_un
         }
 
         // Get the accession if a regular expression is provided.
-        preg_match("/$re_accession/", $defline, $matches);
-        if (strlen($matches[1]) > $dbxref_tbl['fields']['accession']['length']) {
-          tripal_report_error('trp-fasta', TRIPAL_WARNING, "WARNING: Regular expression retrieves an accession too long for the feature name. " .
-             "Cannot add cross reference. Line %line.", array('%line' => $i
-            ));
-        }
-        else {
-          $accession = trim($matches[1]);
+        $accession = "";
+        if (!empty($re_accession)) {
+            preg_match("/$re_accession/", $defline, $matches);
+            if (strlen($matches[1]) > $dbxref_tbl['fields']['accession']['length']) {
+              tripal_report_error('trp-fasta', TRIPAL_WARNING, "WARNING: Regular expression retrieves an accession too long for the feature name. " .
+                 "Cannot add cross reference. Line %line.", array('%line' => $i
+                ));
+            }
+            else {
+              $accession = trim($matches[1]);
+            }
         }
 
         // Get the relationship subject
-        preg_match("/$re_subject/", $line, $matches);
-        $subject = trim($matches[1]);
+        $subject = "";
+        if (!empty($re_subject)) {
+            preg_match("/$re_subject/", $line, $matches);
+            $subject = trim($matches[1]);
+        }
 
         // Add the details to the sequence.
         $seqs[$num_seqs] = array(
@@ -566,18 +579,18 @@ function tripal_feature_load_fasta($dfile, $organism_id, $type, $re_name, $re_un
         $intv_read = 0;
         $percent = sprintf("%.2f", ($num_read / $filesize) * 100);
         if ($name) {
-          print "Parsing Line $i (" . $percent . "%). Memory: " . number_format(memory_get_usage()) .
+          print "Parsing Line $line_num (" . $percent . "%). Memory: " . number_format(memory_get_usage()) .
              " bytes.\r";
         }
         else {
-          print "Parsing Line $i (" . $percent . "%). Memory: " . number_format(memory_get_usage()) .
+          print "Parsing Line $line_num (" . $percent . "%). Memory: " . number_format(memory_get_usage()) .
              " bytes.\r";
         }
         tripal_set_job_progress($job, intval(($num_read / $filesize) * 100));
       }
     }
     $percent = sprintf("%.2f", ($num_read / $filesize) * 100);
-    print "Parsing Line $i (" . $percent . "%). Memory: " . number_format(memory_get_usage()) .
+    print "Parsing Line $line_num (" . $percent . "%). Memory: " . number_format(memory_get_usage()) .
        " bytes.\r";
     tripal_set_job_progress($job, 50);
 
@@ -586,9 +599,9 @@ function tripal_feature_load_fasta($dfile, $organism_id, $type, $re_name, $re_un
 
     // Now that we know where the sequences are in the file we need to add them.
     print "\nStep 2: Importing sequences\n";
-    for ($i = 0; $i < $num_seqs; $i++) {
-      $seq = $seqs[$i];
-      print "Importing " . ($i + 1) . " of $num_seqs. ";
+    for ($j = 0; $j < $num_seqs; $j++) {
+      $seq = $seqs[$j];
+      print "Importing " . ($j + 1) . " of $num_seqs. ";
       if ($name) {
         print "Current feature: " . $seq['name'] . ".\n";
       }
@@ -596,6 +609,7 @@ function tripal_feature_load_fasta($dfile, $organism_id, $type, $re_name, $re_un
         print "Current feature: " . $seq['uname'] . ".\n";
       }
 
+      $source = NULL;
       tripal_feature_load_fasta_feature($fh, $seq['name'], $seq['uname'], $db_id, $seq['accession'], $seq['subject'], $rel_type, $parent_type, $analysis_id, $organism_id, $cvterm, $source, $method, $re_name, $match_type, $parentcvterm, $relcvterm, $seq['seq_start'], $seq['seq_end']);
     }
     tripal_set_job_progress($job, 100);
@@ -666,7 +680,7 @@ function tripal_feature_load_fasta_feature($fh, $name, $uname, $db_id, $accessio
 
   // If we don't have a feature and we're doing an insert then do the insert.
   $inserted = 0;
-  if (!$feature and (strcmp($method, 'Insert only') == 0 or strcmp($method, 'Insert and update') == 0)) {
+  if (!isset($feature) and (strcmp($method, 'Insert only') == 0 or strcmp($method, 'Insert and update') == 0)) {
     // If we have a unique name but not a name then set them to be the same
     if (!$uname) {
       $uname = $name;
@@ -711,7 +725,7 @@ function tripal_feature_load_fasta_feature($fh, $name, $uname, $db_id, $accessio
   }
 
   // if we don't have a feature and the user wants to do an update then fail
-  if (!$feature and (strcmp($method, 'Update only') == 0 or
+  if (!isset($feature) and (strcmp($method, 'Update only') == 0 or
      drupal_strcmp($method, 'Insert and update') == 0)) {
     tripal_report_error('T_fasta_loader', TRIPAL_ERROR, "Failed to find feature '%name' ('%uname') while matching on " .
       drupal_strtolower($match_type), array('%name' => $name,'%uname' => $uname));
@@ -912,7 +926,7 @@ function tripal_feature_load_fasta_residues($fh, $feature_id, $seq_start, $seq_e
   fseek($fh, $seq_start, SEEK_SET);
   $chunk_size = 100000000;
   $chunk = '';
-  $seqlen = ($seq_end - $seq_start) + 1;
+  $seqlen = ($seq_end - $seq_start);
 
   // Calculate the interval at which we updated the precent complete.
   $interval = intval($seqlen * 0.01);
@@ -938,9 +952,11 @@ function tripal_feature_load_fasta_residues($fh, $feature_id, $seq_start, $seq_e
   // get a specific bytes read then append the sequence to the one in the
   // database.
   print "Sequence complete: 0%. Memory: " . number_format(memory_get_usage()) . " bytes. \r";
+  $partial_seq_size = 0;
   while ($line = fgets($fh)) {
     $num_read += strlen($line) + 1;
     $chunk_intv_read += strlen($line) + 1;
+    $partial_seq_size += strlen($line);
     $intv_read += strlen($line) + 1;
     $chunk .= trim($line);
 
@@ -956,7 +972,8 @@ function tripal_feature_load_fasta_residues($fh, $feature_id, $seq_start, $seq_e
       if (!$success) {
         return FALSE;
       }
-      $total_seq_size += strlen($chunk);
+      $total_seq_size += $partial_seq_size;
+      $partial_seq_size = 0;
       $chunk = '';
       $chunk_intv_read = 0;
     }
@@ -967,7 +984,7 @@ function tripal_feature_load_fasta_residues($fh, $feature_id, $seq_start, $seq_e
       $intv_read = 0;
     }
 
-    // If we've reached the ned of the sequence then break out of the loop
+    // If we've reached the end of the sequence then break out of the loop
     if (ftell($fh) == $seq_end) {
       break;
     }
@@ -985,7 +1002,7 @@ function tripal_feature_load_fasta_residues($fh, $feature_id, $seq_start, $seq_e
     if (!$success) {
       return FALSE;
     }
-    $total_seq_size += strlen($chunk);
+    $total_seq_size += $partial_seq_size;
     $chunk = '';
     $chunk_intv_read = 0;
   }
@@ -995,7 +1012,7 @@ function tripal_feature_load_fasta_residues($fh, $feature_id, $seq_start, $seq_e
   chado_query($sql, array(':feature_id' => $feature_id
   ));
 
-  $percent = sprintf("%.2f", ($num_read / $seqlen) * 100);
+  $percent = sprintf("%.2f", ($total_seq_size / $seqlen) * 100);
   print "Sequence complete: " . $percent . "%. Memory: " . number_format(memory_get_usage()) .
      " bytes. \r";
 }

+ 94 - 17
tripal_feature/includes/tripal_feature.gff_loader.inc

@@ -92,13 +92,57 @@ function tripal_feature_gff3_load_form() {
       you may specify the name of the attribute to use for the name."),
   );
 
-  $form['import_options'] = array(
+  // Advanced Options
+  $form['advanced'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Advanced Options'),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+  );
+
+  $form['advanced']['protein_names'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Protein Names'),
+    '#collapsible' => TRUE,
+    '#collapsed' => FALSE,
+    '#weight' => 5,
+  );
+
+  $form['advanced']['protein_names']['re_help'] = array(
+    '#type' => 'item',
+    '#markup' => t('A regular expression is an advanced method for extracting information from a string of text.
+                   If your GFF3 file does not contain polypeptide (or protein) features, but contains CDS features, proteins will be automatically created.
+                   By default the loader will give each protein a name based on the name of the corresponding mRNA followed by the "-protein" suffix.
+                   If you want to customize the name of the created protein, you can use the following regex.')
+  );
+  $form['advanced']['protein_names']['re_mrna'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Regular expression for the mRNA name'),
+    '#required' => FALSE,
+    '#description' => t('Enter the regular expression that will extract portions of
+       the mRNA unique name. For example, for a
+       mRNA with a unique name finishing by -RX (e.g. SPECIES0000001-RA),
+       the regular expression would be, "^(.*?)-R([A-Z]+)$".')
+  );
+  $form['advanced']['protein_names']['re_protein'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Replacement string for the protein name'),
+    '#required' => FALSE,
+    '#description' => t('Enter the replacement string that will be used to create
+       the protein name based on the mRNA regular expression. For example, for a
+       mRNA regular expression "^(.*?)-R()[A-Z]+)$", the corresponding protein regular
+       expression would be "$1-P$2".')
+  );
+
+  $form['advanced']['import_options'] = array(
     '#type' => 'fieldset',
     '#title' => t('Import Options'),
-    '#collapsed' => TRUE
+    '#collapsible' => TRUE,
+    '#collapsed' => FALSE,
+    '#weight' => 0,
   );
 
-  $form['import_options']['use_transaction']= array(
+  $form['advanced']['import_options']['use_transaction']= array(
     '#type' => 'checkbox',
     '#title' => t('Use a transaction'),
     '#required' => FALSE,
@@ -108,14 +152,14 @@ function tripal_feature_gff3_load_form() {
       of failure will be present in the database.'),
     '#default_value' => 1,
   );
-  $form['import_options']['add_only']= array(
+  $form['advanced']['import_options']['add_only']= array(
     '#type' => 'checkbox',
     '#title' => t('Import only new features'),
     '#required' => FALSE,
     '#description' => t('The job will skip features in the GFF file that already
                          exist in the database and import only new features.'),
   );
-  $form['import_options']['update']= array(
+  $form['advanced']['import_options']['update']= array(
     '#type' => 'checkbox',
     '#title' => t('Import all and update'),
     '#required' => FALSE,
@@ -145,7 +189,7 @@ function tripal_feature_gff3_load_form() {
 //     '#description' => t('Features present in the GFF file that exist in the database
 //                          will be removed rather than imported'),
 //   );
-  $form['import_options']['create_organism']= array(
+  $form['advanced']['import_options']['create_organism']= array(
     '#type' => 'checkbox',
     '#title' => t('Create organism'),
     '#required' => FALSE,
@@ -156,12 +200,14 @@ function tripal_feature_gff3_load_form() {
        Otherwise lines with an oraganism attribute where the organism is not present in the database will be skipped.'),
   );
 
-  $form['targets'] = array(
+  $form['advanced']['targets'] = array(
     '#type' => 'fieldset',
     '#title' => t('Targets'),
-    '#collapsed' => TRUE
+    '#collapsible' => TRUE,
+    '#collapsed' => FALSE,
+    '#weight' => 1,
   );
-  $form['targets']['adesc'] = array(
+  $form['advanced']['targets']['adesc'] = array(
     '#markup' => t("When alignments are represented in the GFF file (e.g. such as
        alignments of cDNA sequences to a whole genome, or blast matches), they are
        represented using two feature types: 'match' (or cDNA_match, EST_match, etc.)
@@ -172,7 +218,7 @@ function tripal_feature_gff3_load_form() {
        The options here will apply to all targets unless the organism and type are explicity
        set in the GFF file using the 'target_organism' and 'target_type' attributes."),
   );
-  $form['targets']['target_organism_id'] = array(
+  $form['advanced']['targets']['target_organism_id'] = array(
     '#title'       => t('Target Organism'),
     '#type'        => t('select'),
     '#description' => t("Optional. Choose the organism to which target sequences belong.
@@ -183,7 +229,7 @@ function tripal_feature_gff3_load_form() {
       attribute in the GFF file."),
     '#options'     => $organisms,
   );
-  $form['targets']['target_type'] = array(
+  $form['advanced']['targets']['target_type'] = array(
     '#title'       => t('Target Type'),
     '#type'        => t('textfield'),
     '#description' => t("Optional. If the unique name for a target sequence is not unique (e.g. a protein
@@ -191,7 +237,7 @@ function tripal_feature_gff3_load_form() {
        the targets are of different types then the type must be specified using the 'target_type=type' attribute
        in the GFF file. This must be a valid Sequence Ontology (SO) term."),
   );
-  $form['targets']['create_target']= array(
+  $form['advanced']['targets']['create_target']= array(
     '#type' => 'checkbox',
     '#title' => t('Create Target'),
     '#required' => FALSE,
@@ -230,6 +276,8 @@ function tripal_feature_gff3_load_form_validate($form, &$form_state) {
   $line_number   = trim($form_state['values']['line_number']);
   $landmark_type   = trim($form_state['values']['landmark_type']);
   $alt_id_attr   = trim($form_state['values']['alt_id_attr']);
+  $re_mrna = trim($form_state['values']['re_mrna']);
+  $re_protein = trim($form_state['values']['re_protein']);
 
 
 
@@ -256,6 +304,21 @@ function tripal_feature_gff3_load_form_validate($form, &$form_state) {
   if ($line_number and !is_numeric($line_number) or $line_number < 0) {
     form_set_error('line_number', t("Please provide an integer line number greater than zero."));
   }
+
+  if (!($re_mrna and $re_protein) and ($re_mrna or $re_protein)) {
+    form_set_error('re_uname', t("You must provide both a regular expression for mRNA and a replacement string for protein"));
+  }
+
+  // check the regular expression to make sure it is valid
+  set_error_handler(function() {}, E_WARNING);
+  $result_re = preg_match("/" . $re_mrna . "/", null);
+  $result = preg_replace("/" . $re_mrna . "/", $re_protein, null);
+  restore_error_handler();
+  if ($result_re === FALSE) {
+    form_set_error('re_mrna', 'Invalid regular expression.');
+  } else if ($result === FALSE) {
+    form_set_error('re_protein', 'Invalid replacement string.');
+  }
 }
 
 /**
@@ -281,12 +344,14 @@ function tripal_feature_gff3_load_form_submit($form, &$form_state) {
   $landmark_type   = trim($form_state['values']['landmark_type']);
   $alt_id_attr   = trim($form_state['values']['alt_id_attr']);
   $create_organism = $form_state['values']['create_organism'];
+  $re_mrna = trim($form_state['values']['re_mrna']);
+  $re_protein = trim($form_state['values']['re_protein']);
 
 
   $args = array($gff_file, $organism_id, $analysis_id, $add_only,
     $update, $refresh, $remove, $use_transaction, $target_organism_id,
     $target_type, $create_target, $line_number, $landmark_type, $alt_id_attr,
-    $create_organism);
+    $create_organism, $re_mrna, $re_protein);
 
   $type = '';
   if ($add_only) {
@@ -375,6 +440,10 @@ function tripal_feature_gff3_load_form_submit($form, &$form_state) {
  *   Check this box to automatically add the organism to the database if it does
  *   not already exists. Otherwise lines with an oraganism attribute where the
  *   organism is not present in the database will be skipped.
+ * @param $re_mrna A
+ *          regular expression to extract portions from mRNA id
+ * @param $re_protein A
+ *          replacement string to generate the protein id
  * @param $job
  *  The tripal job_id.  Only used by the Tripal Jobs subsystem.
  *
@@ -383,8 +452,8 @@ function tripal_feature_gff3_load_form_submit($form, &$form_state) {
 function tripal_feature_load_gff3($gff_file, $organism_id, $analysis_id,
   $add_only = 0, $update = 1, $refresh = 0, $remove = 0, $use_transaction = 1,
   $target_organism_id = NULL, $target_type = NULL,  $create_target = 0,
-  $start_line = 1, $landmark_type = '', $alt_id_attr = '', $create_organism = FALSE,
-  $job = NULL) {
+  $start_line = 1, $landmark_type = '', $alt_id_attr = '',  $create_organism = FALSE,
+  $re_mrna = '', $re_protein = '', $job = NULL) {
 
   $ret = array();
   $date = getdate();
@@ -925,8 +994,16 @@ function tripal_feature_load_gff3($gff_file, $organism_id, $analysis_id,
           // protein.
           if (!$result->protein_id) {
             // Get details about this protein
-            $uname = $result->uniquename . '-protein';
-            $name =  $result->name;
+            if ($re_mrna and $re_protein) {
+              // We use a regex to generate protein name from mRNA name
+              $uname = preg_replace("/$re_mrna/", $re_protein, $result->uniquename);
+              $name =  $result->name;
+            }
+            else {
+              // No regex, use the default '-protein' suffix
+              $uname = $result->uniquename . '-protein';
+              $name =  $result->name;
+            }
             $values = array(
               'parent_id' => $result->feature_id,
               'fmin' => $result->fmin

+ 239 - 208
tripal_feature/includes/tripal_feature.seq_extract.inc

@@ -9,169 +9,149 @@
  *
  * @ingroup tripal_feature
  */
-function tripal_feature_seq_extract_page() {
-
-  if ($_SESSION['tripal_feature_seq_extract']['download']) {
-    $genus      = $_SESSION['tripal_feature_seq_extract']['genus'];
-    $species    = $_SESSION['tripal_feature_seq_extract']['species'];
-    $analysis   = $_SESSION['tripal_feature_seq_extract']['analysis'];
-    $ftype      = $_SESSION['tripal_feature_seq_extract']['ftype'];
-    $fnames     = $_SESSION['tripal_feature_seq_extract']['fnames'];
-    $upstream   = $_SESSION['tripal_feature_seq_extract']['upstream'];
-    $downstream = $_SESSION['tripal_feature_seq_extract']['downstream'];
-    $format     = $_SESSION['tripal_feature_seq_extract']['format'];
-    $use_parent = $_SESSION['tripal_feature_seq_extract']['use_parent'];
-    $aggregate  = $_SESSION['tripal_feature_seq_extract']['aggregate'];
-    $agg_types  = $_SESSION['tripal_feature_seq_extract']['agg_types'];
-
-    unset($_SESSION['tripal_feature_seq_extract']['download']);
-
-    if ($format == 'fasta_html') {
-      drupal_add_http_header('Content-Type: text/html');
-    }
-    else {
-      drupal_add_http_header('Content-Type: text');
-      drupal_add_http_header('Content-Disposition: attachment; filename="sequences.fasta.txt"');
-    }
+function tripal_feature_seq_extract_download() {
 
-    tripal_get_bulk_feature_sequences(array(
-      'genus' => $genus, 
-      'species' => $species, 
-      'analysis_name' => $analysis,
-      'type' => $ftype, 
-      'feature_name' => $fnames['items_array'], 
-      'upstream' => $upstream, 
-      'downstream' => $downstream, 
-      'print' => 1,
-      'output_format' => $format, 
-      'derive_from_parent' => $use_parent, 
-      'aggregate' => $aggregate,
-      'sub_feature_types' => $agg_types
-    ));
-
-    return;
+  if (!array_key_exists('tripal_feature_seq_extract', $_SESSION)) {
+    drupal_goto('find/sequences');
   }
 
+  $genus      = $_SESSION['tripal_feature_seq_extract']['genus'];
+  $species    = $_SESSION['tripal_feature_seq_extract']['species'];
+  $analysis   = $_SESSION['tripal_feature_seq_extract']['analysis'];
+  $ftype      = $_SESSION['tripal_feature_seq_extract']['ftype'];
+  $fnames     = $_SESSION['tripal_feature_seq_extract']['fnames'];
+  $upstream   = $_SESSION['tripal_feature_seq_extract']['upstream'];
+  $downstream = $_SESSION['tripal_feature_seq_extract']['downstream'];
+  $format     = $_SESSION['tripal_feature_seq_extract']['format'];
+  $use_parent = $_SESSION['tripal_feature_seq_extract']['use_parent'];
+  $aggregate  = $_SESSION['tripal_feature_seq_extract']['aggregate'];
+  $agg_types  = $_SESSION['tripal_feature_seq_extract']['agg_types'];
+
+  // Split the sub features and remove any surrounding white space
+  $agg_types = preg_split("/[\n|,]/", $agg_types);
+  for ($i = 0; $i < count($agg_types); $i++) {
+    $agg_types[$i] = trim($agg_types[$i]);
+  }
 
-  // generate the search form
-  $output .= '';
-  if (user_access('administer tripal')) {
-    $output .= tripal_set_message("Administrators, the " . 
-        l('organism_feature_count', 'admin/tripal/schema/mviews') . " and " .
-        l('analysis_organism', 'admin/tripal/schema/mviews') . " materialized
-        views must be populated before using this form.  Those views should be re-populated
-        when new data is added.");
+
+
+  header('Content-Type: text; utf-8');
+  if ($ftype == 'polypeptide') {
+    header('Content-Disposition: attachment; filename="sequences.fna"');
+  }
+  else {
+    header('Content-Disposition: attachment; filename="sequences.fnn"');
   }
-  $output .= "<div id=\"tripal-feature-seq-extract-form-block\">";
-  $output .= drupal_get_form('tripal_feature_seq_extract_form');
-  $output .= "</div>";
-  return $output;
-}
 
-/**
- * Theme the Form to choose which features to extract sequence for
- *
- * @ingroup tripal_feature
- */
-function theme_tripal_feature_seq_extract_form($form, &$form_state) {
-  $rows = array(
-    0 => array(
-      array('data' => drupal_render($form['description']), 'colspan' => 3),
-    ),
-    1 => array(
-      drupal_render($form['genus']),
-      drupal_render($form['species']) ,
-      drupal_render($form['ftype']),
-    ),
-    2 => array(
-      array('data' => drupal_render($form['analysis']), 'colspan' => 3),
-      //drupal_render($form['format']),
-    ),
-    3 => array(
-      array('data' =>  drupal_render($form['fnames']), 'colspan' => 2),
-      drupal_render($form['upstream']) . drupal_render($form['downstream']) ,
-    ),
-    4 => array(
-      array(
-        'data' =>  drupal_render($form['advanced']),
-        'colspan' => 3,
-      ),
-    ),
-    5 => array(
-      array(
-        'data' =>  drupal_render($form['retrieve_btn']) . drupal_render($form['reset_btn']),
-        'colspan' => 3,
-      ),
-    ),
-  );
-  $headers = array();
-  $table = theme('table', $headers, $rows, array('id' => 'tripal-feature-seq-extract-form-table', 'border' => '0'));
+  $seqs = tripal_get_bulk_feature_sequences(array(
+    'genus' => $genus,
+    'species' => $species,
+    'analysis_name' => $analysis,
+    'type' => $ftype,
+    'feature_name' => $fnames['items_array'],
+    'upstream' => $upstream,
+    'downstream' => $downstream,
+    'output_format' => $format,
+    'derive_from_parent' => $use_parent,
+    'aggregate' => $aggregate,
+    'sub_feature_types' => $agg_types,
+    'width' => 60
+  ));
+
+  if (count($seqs) == 0) {
+    print ">No sequences found that match the criteria.";
+  }
 
-  $markup .= $table;
-  $form['criteria'] = array(
-    '#markup' =>  $markup,
-    '#weight' => -10,
-  );
-  return drupal_render($form);
+  foreach ($seqs as $seq) {
+    print ">" . $seq['defline'] . "\r\n";
+    print $seq['residues'] . "\r\n";
+  }
 }
 
+
+
 /**
  * Form to choose which features to extract sequence for
  *
  * @ingroup tripal_feature
  */
-function tripal_feature_seq_extract_form(&$form_state = NULL) {
-  tripal_core_ahah_init_form();
+function tripal_feature_seq_extract_form($form, &$form_state) {
+
+  $form['#true'] = TRUE;
+
+  // Intialize the defaults
+  $dgenus      = '';
+  $dspecies    = '';
+  $danalysis   = '';
+  $dftype      = '';
+  $dfnames     = '';
+  $dupstream   = '';
+  $ddownstream = '';
+  $duse_parent = '';
+  $daggregate  = '';
+  $dagg_types  = '';
+
+  if (array_key_exists('tripal_feature_seq_extract', $_SESSION)) {
+    $dgenus      = $_SESSION['tripal_feature_seq_extract']['genus'];
+    $dspecies    = $_SESSION['tripal_feature_seq_extract']['species'];
+    $danalysis   = $_SESSION['tripal_feature_seq_extract']['analysis'];
+    $dftype      = $_SESSION['tripal_feature_seq_extract']['ftype'];
+    $dfnames     = $_SESSION['tripal_feature_seq_extract']['fnames'];
+    $dupstream   = $_SESSION['tripal_feature_seq_extract']['upstream'];
+    $ddownstream = $_SESSION['tripal_feature_seq_extract']['downstream'];
+    $duse_parent = $_SESSION['tripal_feature_seq_extract']['use_parent'];
+    $daggregate  = $_SESSION['tripal_feature_seq_extract']['aggregate'];
+    $dagg_types  = $_SESSION['tripal_feature_seq_extract']['agg_types'];
+  }
 
   // we want to allow the query string to provide values for the form
-  if ($_GET['fnames']) {
-    $form_state['values']['fnames']['items'] = $_GET['fnames'];
+  if (array_key_exists('fnames', $_GET) and $_GET['fnames']) {
+    $dfnames = $_GET['fnames'];
   }
-  if ($_GET['genus']) {
-    $form_state['values']['genus'] = $_GET['genus'];
+  if (array_key_exists('genus', $_GET) and $_GET['genus']) {
+    $dgenus = $_GET['genus'];
   }
-  if ($_GET['species']) {
-    $form_state['values']['species'] = $_GET['species'];
+  if (array_key_exists('species', $_GET) and $_GET['species']) {
+    $dspecies = $_GET['species'];
   }
-  if ($_GET['ftype']) {
-    $form_state['values']['ftype'] = $_GET['ftype'];
+  if (array_key_exists('ftype', $_GET) and $_GET['ftype']) {
+    $dftype = $_GET['ftype'];
   }
-  if ($_GET['analysis']) {
-    $form_state['values']['analysis'] = $_GET['analysis'];
+  if (array_key_exists('analysis', $_GET) and $_GET['analysis']) {
+    $danalysis = $_GET['analysis'];
   }
-  if ($_GET['upstream']) {
-    $form_state['values']['upstream'] = $_GET['upstream'];
+  if (array_key_exists('upstream', $_GET) and $_GET['upstream']) {
+    $dupstream = $_GET['upstream'];
   }
-  if ($_GET['downstream']) {
-    $form_state['values']['downstream'] = $_GET['downstream'];
+  if (array_key_exists('downstream', $_GET) and $_GET['downstream']) {
+    $ddownstream = $_GET['downstream'];
   }
-  if ($_GET['use_parent']) {
-    $form_state['values']['use_parent'] = $_GET['use_parent'];
+  if (array_key_exists('use_parent', $_GET) and $_GET['use_parent']) {
+    $duse_parent = $_GET['use_parent'];
   }
-  if ($_GET['aggregate']) {
-    $form_state['values']['aggregate'] = $_GET['aggregate'];
+  if (array_key_exists('aggregate', $_GET) and $_GET['aggregate']) {
+    $daggregate = $_GET['aggregate'];
   }
-  if ($_GET['agg_types']) {
-    $form_state['values']['agg_types'] = $_GET['agg_types'];
+  if (array_key_exists('agg_types', $_GET) and $_GET['agg_types']) {
+    $dagg_types = $_GET['agg_types'];
   }
 
-  // get defaults
-  $dgenus      = isset($form_state['values']['genus'])      ? $form_state['values']['genus']      : $_SESSION['tripal_feature_seq_extract']['genus'];
-  $dspecies    = isset($form_state['values']['species'])    ? $form_state['values']['species']    : $_SESSION['tripal_feature_seq_extract']['species'];
-  $danalysis   = isset($form_state['values']['analysis'])   ? $form_state['values']['analysis']   : $_SESSION['tripal_feature_seq_extract']['analysis'];
-  $dftype      = isset($form_state['values']['ftype'])      ? $form_state['values']['ftype']      : $_SESSION['tripal_feature_seq_extract']['ftype'];
-  $dfnames     = isset($form_state['values']['fnames'])     ? $form_state['values']['fnames']     : $_SESSION['tripal_feature_seq_extract']['fnames'];
-  $dupstream   = isset($form_state['values']['upstream'])   ? $form_state['values']['upstream']   : $_SESSION['tripal_feature_seq_extract']['upstream'];
-  $ddownstream = isset($form_state['values']['downstream']) ? $form_state['values']['downstream'] : $_SESSION['tripal_feature_seq_extract']['downstream'];
-  $dformat     = isset($form_state['values']['format'])     ? $form_state['values']['format']     : 'fasta_txt';
-  $duse_parent = isset($form_state['values']['use_parent']) ? $form_state['values']['use_parent'] : $_SESSION['tripal_feature_seq_extract']['use_parent'];
-  $daggregate  = isset($form_state['values']['aggregate'])  ? $form_state['values']['aggregate']  : $_SESSION['tripal_feature_seq_extract']['aggregate'];
-  $dagg_types  = isset($form_state['values']['agg_types'])  ? $form_state['values']['agg_types']  : $_SESSION['tripal_feature_seq_extract']['agg_types'];
-
-
-  $form = array();
+  // get defaults from the form state
+  if (array_key_exists('values', $form_state)) {
+    $dgenus      = $form_state['values']['genus'];
+    $dspecies    = $form_state['values']['species'];
+    $danalysis   = $form_state['values']['analysis'];
+    $dftype      = $form_state['values']['ftype'];
+    $dfnames     = $form_state['values']['fnames'];
+    $dupstream   = $form_state['values']['upstream'];
+    $ddownstream = $form_state['values']['downstream'];
+    $dformat     = $form_state['values']['format'];
+    $duse_parent = $form_state['values']['use_parent'];
+    $daggregate  = $form_state['values']['aggregate'];
+    $dagg_types  = $form_state['values']['agg_types'];
+  }
 
-  // because we're using Tripal's file_upload_combo form element we
+  // Because we're using Tripal's file_upload_combo form element we
   // need to allow the form to upload files
   $form['#attributes']['enctype'] = 'multipart/form-data';
   $form['#method'] = 'POST';
@@ -199,9 +179,9 @@ function tripal_feature_seq_extract_form(&$form_state = NULL) {
     '#default_value' => $dgenus,
     '#multiple'      => FALSE,
     '#description'   => t('The organism\'s genus. If specified, features for all organism with this genus will be retrieved.'),
-    '#ahah' => array(
-      'path'    => 'find/sequences/ajax',
-      'wrapper' => 'tripal-feature-seq-extract-form-block',
+    '#ajax' => array(
+      'callback'    => 'tripal_feature_seq_extract_form_ajax_callback',
+      'wrapper' => 'tripal-feature-seq-extract-form',
       'event'   => 'change',
       'method'  => 'replace',
     ),
@@ -228,9 +208,9 @@ function tripal_feature_seq_extract_form(&$form_state = NULL) {
     '#default_value' => $dspecies,
     '#multiple'      => FALSE,
     '#description'   => t('The organism\'s species name. If specified, features for all organisms with this species will be retrieved.  Please first select a genus'),
-    '#ahah' => array(
-      'path'    => 'find/sequences/ajax',
-      'wrapper' => 'tripal-feature-seq-extract-form-block',
+    '#ajax' => array(
+      'callback'    => 'tripal_feature_seq_extract_form_ajax_callback',
+      'wrapper' => 'tripal-feature-seq-extract-form',
       'event'   => 'change',
       'method'  => 'replace',
     ),
@@ -294,39 +274,37 @@ function tripal_feature_seq_extract_form(&$form_state = NULL) {
     '#options'       => $ftype,
     '#multiple'      => FALSE,
     '#default_value' => $dftype,
-    '#description'   => t('The type of feature to retrieve (e.g. mRNA). All features that match this type will be retrieved.'),
+    '#description'   => t('The type of feature to retrieve (e.g. mRNA). All
+        features that match this type will be retrieved.'),
   );
 
   $form['fnames'] = array(
     '#title'         => t('Feature Name'),
     '#type'          => 'file_upload_combo',
     '#default_value' => $dfnames,
-    '#description'   => t('The names of the features to retrieve. Separate each with a new line or comma. Leave blank to retrieve all features matching other criteria.'),
+    '#description'   => t('The names of the features to retrieve. Separate each
+         with a new line or comma. Leave blank to retrieve all features
+        matching other criteria.'),
     '#rows'          => 8
   );
   $form['upstream'] = array(
     '#title'         => t('Upstream Bases'),
     '#type'          => 'textfield',
-    '#description'   => t('A numeric value specifying the number of upstream bases to include. Only works if the feature is aligned to a larger sequence.'),
+    '#description'   => t('A numeric value specifying the number of upstream
+         bases to include. Only works if the feature is aligned to a larger
+         sequence.'),
     '#default_value' => $dupstream,
     '#size'          => 5,
   );
   $form['downstream'] = array(
     '#title'         => t('Downstream Bases'),
     '#type'          => 'textfield',
-    '#description'   => t('A numeric value specifying the number of downstream bases to incldue.  Only works if the feature is aligned to a larger sequence.'),
+    '#description'   => t('A numeric value specifying the number of downstream
+        bases to incldue.  Only works if the feature is aligned to a larger
+        sequence.'),
     '#default_value' => $ddownstream,
     '#size'          => 5,
   );
-  $form['format'] = array(
-    '#title'         => t('Output Format'),
-    '#type'          => 'hidden',
-    '#default_value' => $dformat,
-    '#options'       => array(
-      'fasta_html'  => 'FASTA (in browser)',
-      'fasta_txt'   => 'FASTA (download)',
-    ),
-  );
   $form['advanced'] = array(
     '#type' => 'fieldset',
     '#title' => 'Advanced',
@@ -338,64 +316,115 @@ function tripal_feature_seq_extract_form(&$form_state = NULL) {
     '#title'         => t('Use Parent'),
     '#type'          => 'checkbox',
     '#default_value' => $duse_parent,
-    '#description'   => t('Check this box to retrieve the sequence from the parent in an alignment rather than the feature itself. This is useful if the same feature is aligned to multiple parents and you would like to retrieve the underlying sequence from each parent.'),
+    '#description'   => t('Check this box to retrieve the sequence from the
+        parent in an alignment rather than the feature itself. This is useful
+        if the same feature is aligned to multiple parents and you would like
+        to retrieve the underlying sequence from each parent.'),
   );
   $form['advanced']['aggregate'] = array(
     '#title'         => t('Aggregate'),
     '#type'          => 'checkbox',
     '#default_value' => $daggregate,
-    '#description'   => t('Check this box to aggregate sub features into a single sequence.  This is useful, for example, for obtaining CDS sequence from an mRNA. Rather than retrieve the mRNA sequence, the sub features of the mRNA will be aggregated and that will be returned.')
+    '#description'   => t('Check this box to aggregate sub features into a
+        single sequence.  This is useful, for example, for obtaining CDS
+        sequence from an mRNA. Rather than retrieve the mRNA sequence, the
+        sub features of the mRNA will be aggregated and that will be returned.')
   );
   $form['advanced']['agg_types'] = array(
     '#title'         => t('Types to aggregate'),
     '#type'          => 'textarea',
     '#default_value' => $dagg_types,
-    '#description'   => t('Set this argument to the type of children to aggregate.  This is useful in the case where a gene has exons, CDSs and UTRs.  In this case, you may only want to aggregate CDSs and exclude exons.  If you want to aggregate both CDSs and UTRs you could specify both.')
+    '#description'   => t('Set this argument to the type of children to
+        aggregate.  This is useful in the case where a gene has exons, CDSs
+        and UTRs.  In this case, you may only want to aggregate CDSs and
+        exclude exons.  If you want to aggregate both CDSs and UTRs you
+        could specify both.  Please place each type on a new line.')
   );
   $form['retrieve_btn'] = array(
     '#type' => 'submit',
-    '#value' => 'Retrieve',
-  );
-  $form['reset_btn'] = array(
-    '#type' => 'submit',
-    '#value' => 'Reset',
+    '#name' => 'retrieve',
+    '#value' => 'Retrieve Sequences',
   );
+
+  if (user_access('administer tripal')) {
+    $notice = tripal_set_message("Administrators, the " .
+        l('organism_feature_count', 'admin/tripal/schema/mviews') . " and " .
+        l('analysis_organism', 'admin/tripal/schema/mviews') . " materialized
+        views must be populated before using this form.  Those views should be re-populated
+        when new data is added.", TRIPAL_NOTICE, array('return_html' => TRUE));
+  }
+
+  $form['#prefix'] = '<div id="tripal-feature-seq-extract-form">';
+  $form['#suffix'] = $notice . '</div>';
+
   return $form;
 }
 
 /**
- * AJAX callback
+ * Theme the Form to choose which features to extract sequence for
  *
  * @ingroup tripal_feature
  */
-function tripal_feature_seq_extract_form_ahah_update() {
-  $status = TRUE;
-
-  // prepare and render the form. If no form is returned that means
-  // we got here by an AHAH call after the form has been submitted.  This
-  // is possible because results are downloaded and the page is not refreshed
-  // but the form_id goes away.  So, we need to rebuild the form in this case.
-  // otherwise, if the form already exists we just theme it.
-  $form = tripal_core_ahah_prepare_form();
-  if ($form) {
-    $data = theme('tripal_feature_seq_extract_form', $form);
-  }
-  else {
-    $data = drupal_get_form('tripal_feature_seq_extract_form');
-  }
+function theme_tripal_feature_seq_extract_form(&$variables) {
+  $form = $variables['form'];
+
+  $headers = array();
+  $rows = array(
+    0 => array(
+      array('data' => drupal_render($form['description']), 'colspan' => 3),
+    ),
+    1 => array(
+      drupal_render($form['genus']),
+      drupal_render($form['species']) ,
+      drupal_render($form['ftype']),
+    ),
+    2 => array(
+      array('data' => drupal_render($form['analysis']), 'colspan' => 3),
+      //drupal_render($form['format']),
+    ),
+    3 => array(
+      array('data' =>  drupal_render($form['fnames']), 'colspan' => 2),
+      drupal_render($form['upstream']) .
+      drupal_render($form['downstream']) .
+      drupal_render($form['format']),
+    ),
+    4 => array(
+      array(
+        'data' =>  drupal_render($form['advanced']),
+        'colspan' => 3,
+      ),
+    ),
+    5 => array(
+      array(
+        'data' =>  drupal_render($form['retrieve_btn']) . drupal_render($form['reset_btn']),
+        'colspan' => 3,
+      ),
+    ),
+  );
+
+  $table_vars = array(
+    'header' => $headers,
+    'rows' => $rows,
+    'attributes' => array(
+      'id' => 'tripal-feature-seq-extract-form-table',
+      'border' => '0'
+    ),
+    'sticky' => FALSE,
+    'colgroups' => array(),
+    'empty' => '',
+  );
 
-  // bind javascript events to the new objects that will be returned
-  // so that AHAH enabled elements will work.
-  $settings = tripal_core_ahah_bind_events();
-
-  // return the updated JSON
-  drupal_json(
-    array(
-      'status'   => $status,
-      'data'     => $data,
-      'settings' => $settings,
-    )
+  $form['rendered_form'] = array(
+    '#type' => 'item',
+    '#markup' => theme('table', $table_vars),
   );
+  return drupal_render_children($form);
+}
+/**
+ * Ajax function which returns the form via ajax
+ */
+function tripal_feature_seq_extract_form_ajax_callback($form, &$form_state) {
+  return $form;
 }
 
 /**
@@ -411,22 +440,27 @@ function tripal_feature_seq_extract_form_validate($form, &$form_state) {
   $fnames     = $form_state['values']['fnames'];
   $upstream   = $form_state['values']['upstream'];
   $downstream = $form_state['values']['downstream'];
-  $format     = $form_state['values']['format'];
   $use_parent = $form_state['values']['use_parent'];
   $aggregate  = $form_state['values']['aggregate'];
   $agg_types  = $form_state['values']['agg_types'];
-  $op         = $form_state['values']['op'];
 
-  if ($op == 'Retrieve') {
-    if ($upstream and !preg_match('/^\d+$/', $upstream)) {
-      form_set_error('upstream', 'Please enter a positive numeric value for the upstream bases');
-    }
-     if ($downstream and !preg_match('/^\d+$/', $downstream)) {
-      form_set_error('downstream', 'Please enter a positive numeric value for the downstream bases');
-    }
-    if (!$genus and !$species and !$ftype and !$fnames) {
-      form_set_error('', 'Please provide a feature name, a feature type or a genus.');
-    }
+  if ($upstream and !preg_match('/^\d+$/', $upstream)) {
+    form_set_error('upstream', 'Please enter a positive numeric value for the upstream bases');
+  }
+   if ($downstream and !preg_match('/^\d+$/', $downstream)) {
+    form_set_error('downstream', 'Please enter a positive numeric value for the downstream bases');
+  }
+  if (!$genus and !$species and !$ftype and !$fnames) {
+    form_set_error('', 'Please provide a feature name, a feature type or a genus.');
+  }
+  if ($ftype == 'polypeptide' and $upstream) {
+    form_set_error('upstream', 'When the sequence type is protein the upstream value must be unset.');
+  }
+  if ($ftype == 'polypeptide' and $downstream) {
+    form_set_error('downstream', 'When the sequence type is protein the downstream value must be unset.');
+  }
+  if ($ftype == 'polypeptide' and $use_parent) {
+    form_set_error('use_parent', 'When the sequence type is protein the "Use Parent" option must not be set.');
   }
 }
 
@@ -443,11 +477,9 @@ function tripal_feature_seq_extract_form_submit($form, &$form_state) {
   $fnames     = $form_state['values']['fnames'];
   $upstream   = $form_state['values']['upstream'];
   $downstream = $form_state['values']['downstream'];
-  $format     = $form_state['values']['format'];
   $use_parent = $form_state['values']['use_parent'];
   $aggregate  = $form_state['values']['aggregate'];
   $agg_types  = $form_state['values']['agg_types'];
-  $op         = $form_state['values']['op'];
 
   // we must use the parent sequence if the user has selected
   // the upstream, downstream or to aggregate
@@ -455,7 +487,7 @@ function tripal_feature_seq_extract_form_submit($form, &$form_state) {
     $use_parent = 1;
   }
 
-  if ($op == 'Retrieve') {
+  if ($form_state['clicked_button']['#name'] == 'retrieve') {
     $_SESSION['tripal_feature_seq_extract']['genus']      = $genus;
     $_SESSION['tripal_feature_seq_extract']['species']    = $species;
     $_SESSION['tripal_feature_seq_extract']['analysis']   = $analysis;
@@ -463,13 +495,12 @@ function tripal_feature_seq_extract_form_submit($form, &$form_state) {
     $_SESSION['tripal_feature_seq_extract']['fnames']     = $fnames;
     $_SESSION['tripal_feature_seq_extract']['upstream']   = $upstream;
     $_SESSION['tripal_feature_seq_extract']['downstream'] = $downstream;
-    $_SESSION['tripal_feature_seq_extract']['format']     = $format;
+    $_SESSION['tripal_feature_seq_extract']['format']     = 'fasta_txt';
     $_SESSION['tripal_feature_seq_extract']['use_parent'] = $use_parent;
     $_SESSION['tripal_feature_seq_extract']['aggregate']  = $aggregate;
     $_SESSION['tripal_feature_seq_extract']['agg_types']  = $agg_types;
     $_SESSION['tripal_feature_seq_extract']['download']   = 1;
-  }
-  if ($op == 'Reset') {
-    unset($_SESSION['tripal_feature_seq_extract']);
+
+    drupal_goto('find/sequences/download');
   }
 }

+ 18 - 20
tripal_feature/theme/templates/tripal_feature_help.tpl.php

@@ -6,16 +6,14 @@
   <ol>
     <li><p><b>Set Permissions</b>: By default only the site administrator account has access to create, edit, delete
    or administer features. Navigate to the <?php print l('permissions page', 'admin/user/permissions')?> and set the
-   permissions under the 'tripal_feature' section as appropriate for your site. For a simple setup, allow anonymous 
+   permissions under the 'tripal_feature' section as appropriate for your site. For a simple setup, allow anonymous
    users access to view content and create a special role for creating, editing and other administrative tasks.</p></li>
-   
-   <li><p><b>Loading of Ontologies</b>:  
+
+   <li><p><b>Loading of Ontologies</b>:
      Before loading genomic features you must also have several vocabularies loaded as well. Using the
      <?php print l('OGO loader','admin/tripal/tripal_cv/obo_loader')?> you should load the following
      ontologies:</p>
      <ul>
-        <li>Chado Feature Properties</li>
-        <li>Relationship Ontology</li>
         <li>Sequence Ontology</li>
         <li>Gene Ontology (if loading GO terms for features)</li>
      </ul>
@@ -40,7 +38,7 @@
      <li><p><b>Data Import</b>:  if you do not already have an existing Chado database with preloaded data
      then you will want
      to import data.  You can do so using the Chado perl scripts that come with the normal
-     <a href="http://gmod.org/wiki/Chado">distribution of Chado</a> or you can use 
+     <a href="http://gmod.org/wiki/Chado">distribution of Chado</a> or you can use
      the <a href="<?php print url('admin/tripal/tripal_feature/fasta_loader') ?>">FASTA loader</a> and
      <a href="<?php print url('admin/tripal/tripal_feature/gff3_load') ?>">GFF loader</a> provided here.  If you
      created the Chado database using Tripal then you'll most likely want to use the Tripal loaders.  If your data
@@ -70,27 +68,27 @@
   <p>Aside from data loading and feature page setup (as described in the Setup section above),
   The Tripal feature module also provides the following functionality</p>
   <ul>
-    <li><p><b>Retrieve Sequences</b>: A tool to <?php print l('retrieve sequences','find/sequences') ?> is provided 
+    <li><p><b>Retrieve Sequences</b>: A tool to <?php print l('retrieve sequences','find/sequences') ?> is provided
      which allows end-users to download sequences in FASTA format.  The site admin must first load sequence residues
-     as well as alignments.  The <?php  print l('organism_feature_count', 'admin/tripal/mviews') ?> and 
+     as well as alignments.  The <?php  print l('organism_feature_count', 'admin/tripal/mviews') ?> and
      <?php print l('analysis_organism', 'admin/tripal/mviews') ?> materialized
-     views must be populated before using this tool.  Those views should be re-populated 
+     views must be populated before using this tool.  Those views should be re-populated
      when new data is added.  If you use the <?php print l('jquery_update module', 'http://drupal.org/project/jquery_update') ?>
-     the tool may break.  You will need to update the jquery_update/replace/jquery.form.js file with <?php 
+     the tool may break.  You will need to update the jquery_update/replace/jquery.form.js file with <?php
      print l('a more recent version','https://raw.github.com/malsup/form/master/jquery.form.js') ?>. </p></li>
-    
-     <li><p><b>Generic Feature URL</b>:  As described in the setup instructions above, it is often convenient to have a 
-     simple URL for each feature page. For example, http://www.mygenomesite.org/[feature], where [feature] is a 
+
+     <li><p><b>Generic Feature URL</b>:  As described in the setup instructions above, it is often convenient to have a
+     simple URL for each feature page. For example, http://www.mygenomesite.org/[feature], where [feature] is a
      unique identifier for a feature page.  The
-     <?php print l('Feature Configuration page','admin/tripal/tripal_feature/configuration') ?> allows a 
+     <?php print l('Feature Configuration page','admin/tripal/tripal_feature/configuration') ?> allows a
      site admin to generate unique URLs for all feature.  The unique URL is necessary, however, sometimes
      it is easier to allow for links to the feature name without knowing the unique URL.  This is possible
-     using the URL: http://[site url]/feature/[feature name], where [site url] is the URL for the site and 
+     using the URL: http://[site url]/feature/[feature name], where [site url] is the URL for the site and
      [feature name] is the name of the feature.  If the feature name is not unique then a page will be
-     presented listing all of the features with the same name and allow the user to choose which one to 
-     view.  If the feature name is unique then the user will automatically be redirected to the 
+     presented listing all of the features with the same name and allow the user to choose which one to
+     view.  If the feature name is unique then the user will automatically be redirected to the
      unique URL for the feature.</p></li>
-     
+
     <li><p><b>Feature Browser:</b>  The feature browser is a tabular list of features with links to their
      feature pages which appears on the organism
      page.  It was created to provide a mechanism to allow site visitors to quickly
@@ -112,9 +110,9 @@
     published data (only works if Chado was installed using Tripal).  You can see a list of available pre-existing
     Views <a href="<?php print url('admin/build/views/') ?>">here</a>, as well as create your own. </p></li>
 
-    <li><p><b>Simple Search Tool</b>: A <?php print l('simple search tool','chado/features') ?> is provided for 
+    <li><p><b>Simple Search Tool</b>: A <?php print l('simple search tool','chado/features') ?> is provided for
     finding features. This tool relies on Drupal Views.  <a href="http://drupal.org/project/views">Drupal Views</a>
-    which must be installed to see the search tool.  Look for it in the navigation menu under the item 
+    which must be installed to see the search tool.  Look for it in the navigation menu under the item
     "Search Data". </p></li>
 
     <li><p><b>Delete Features</b>: You can  <a href="<?php print url('admin/tripal/tripal_feature/delete') ?>">bulk delete features</a>

+ 6 - 1
tripal_feature/theme/templates/tripal_organism_feature_browser.tpl.php

@@ -109,15 +109,20 @@ if (count($so_terms) > 0) {
     // here we add the paramter 'block' => 'feature_browser'. This is because
     // the pager is not on the default block that appears. When the user clicks a
     // page number we want the browser to re-appear with the page is loaded.
+    // We remove the 'pane' parameter from the original query parameters because
+    // Drupal won't reset the parameter if it already exists.
+    $get = $_GET;
+    unset($_GET['pane']);
     $pager = array(
       'tags' => array(),
       'element' => $element,
       'parameters' => array(
-        'block' => 'feature_browser'
+        'pane' => 'feature_browser'
       ),
       'quantity' => $num_per_page,
     );
     print theme_pager($pager);
+    $_GET = $get;
 
     print tripal_set_message("
       Administrators, please note that the feature browser will be retired in

+ 6 - 1
tripal_feature/theme/tripal_feature.theme.inc

@@ -31,7 +31,7 @@ function tripal_feature_preprocess_tripal_feature_sequence(&$variables) {
   // if this feature has associated protein sequences (or others via relationships
   // then we want to make sure the relationships are added so that we can
   // show the protein sequences
-  if (!$feature->all_relationships) {
+  if (!property_exists($feature, 'all_relationships')) {
     $feature->all_relationships = tripal_feature_get_feature_relationships($feature);
   }
 }
@@ -687,6 +687,11 @@ function tripal_feature_load_organism_feature_counts($organism) {
   $order = array();
   $names = array();
 
+  // We should not assume this table is present since it is a materialized view.
+  if (!chado_table_exists('organism_feature_count')) {
+    return NULL;
+  }
+
   // build the where clause for the SQL statement if we have a custom term list
   // we'll also keep track of the names the admin provided (if any) and the
   // order that the terms should appear.

+ 10 - 3
tripal_feature/tripal_feature.drush.inc

@@ -106,11 +106,18 @@ function drush_tripal_feature_tripal_get_sequence() {
     'sub_feature_types' => explode(',', $child),
     'relationship_type' => $relationship,
     'relationship_part' => $rel_part,
-    'print' => TRUE,
     'width' => $width
   );
-  
-  tripal_get_bulk_feature_sequences($options);
+
+  $seqs = tripal_get_bulk_feature_sequences($options);
+  if (count($seqs) == 0) {
+    print "No sequences found that match the criteria.";
+  }
+
+  foreach ($seqs as $seq) {
+    print ">" . $seq['defline'] . "\r\n";
+    print $seq['residues'] . "\r\n";
+  }
 }
 
 /**

+ 1 - 1
tripal_feature/tripal_feature.info

@@ -3,7 +3,7 @@ description = Supports the sequence (feature) tables of Chado by providing pages
 core = 7.x
 project = tripal
 package = Tripal
-version = 7.x-2.1-beta2
+version = 7.x-2.1
 
 stylesheets[all][] = theme/css/tripal_feature.css
 scripts[]          = theme/js/tripal_feature.js

+ 2 - 0
tripal_feature/tripal_feature.install

@@ -249,6 +249,7 @@ function tripal_feature_add_organism_count_mview() {
     'table' => $view_name,
     'fields' => array(
       'organism_id' => array(
+        'size' => 'big',
         'type' => 'int',
         'not null' => TRUE,
       ),
@@ -272,6 +273,7 @@ function tripal_feature_add_organism_count_mview() {
         'not null' => TRUE,
       ),
       'cvterm_id' => array(
+        'size' => 'big',
         'type' => 'int',
         'not null' => TRUE,
       ),

+ 41 - 31
tripal_feature/tripal_feature.module

@@ -114,14 +114,13 @@ function tripal_feature_menu() {
   $items['find/sequences'] = array(
     'title' => 'Sequence Retrieval',
     'description' => 'Download a file of sequences',
-    'page callback' => 'tripal_feature_seq_extract_page',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('tripal_feature_seq_extract_form'),
     'access arguments' => array('access chado_feature content'),
     'type' => MENU_CALLBACK,
   );
-
-  $items['find/sequences/ajax'] = array(
-    'title' => 'Sequence Retrieval',
-    'page callback' => 'tripal_feature_seq_extract_form_ahah_update',
+  $items['find/sequences/download'] = array(
+    'page callback' => 'tripal_feature_seq_extract_download',
     'access arguments' => array('access chado_feature content'),
     'type' => MENU_CALLBACK,
   );
@@ -343,7 +342,7 @@ function tripal_feature_theme($existing, $type, $theme, $path) {
 
   // Themed Forms
   $items['tripal_feature_seq_extract_form'] = array(
-     'arguments' => array('form'),
+    'render element' => 'form',
   );
 
   // D3 Charts.
@@ -366,32 +365,43 @@ function tripal_feature_job_describe_args($callback, $args) {
 
   $new_args = array();
   if ($callback == 'tripal_feature_load_fasta') {
+
     $new_args['FASTA file'] = $args[0];
-    $organism = chado_select_record('organism', array('genus', 'species'), array('organism_id' => $args[1]));
-    $new_args['Organism'] = $organism[0]->genus . " " . $organism[0]->species;
+
+    // Add in the organism.
+    if ($args[1] AND is_numeric($args[1])) {
+      $organism = chado_select_record('organism', array('genus', 'species'), array('organism_id' => $args[1]));
+      $new_args['Organism'] = $organism[0]->genus . " " . $organism[0]->species;
+    }
+
     $new_args['Sequence Type'] = $args[2];
-    $new_args['Name Match Type'] = $args[14];
-    $new_args['Name RE'] = $args[4];
-    $new_args['Unique Name RE'] = $args[5];
+
+    if (isset($args[14])) {
+      $new_args['Name Match Type'] = $args[14];
+      $new_args['Name RE'] = $args[4];
+      $new_args['Unique Name RE'] = $args[5];
+    }
 
     // add in the relationship arguments
-    $new_args['Relationship Type'] = $args[8];
-    $new_args['Relationship Parent RE'] = $args[9];
-    $new_args['Relationship Parent Type'] = $args[10];
+    if ($args[8]) {
+      $new_args['Relationship Type'] = $args[8];
+      $new_args['Relationship Parent RE'] = $args[9];
+      $new_args['Relationship Parent Type'] = $args[10];
+    }
 
     // add in the database reference arguments
-    if ($args[7]) {
+    if ($args[7] AND is_numeric($args[7])) {
       $db = chado_select_record('db', array('name'), array('db_id' => $args[7]));
+      $new_args['Database Reference'] = $db[0]->name;
+      $new_args['Accession RE'] = $args[6];
+      $new_args['Method'] = $args[11];
     }
-    $new_args['Database Reference'] = $db[0]->name;
-    $new_args['Accession RE'] = $args[6];
-    $new_args['Method'] = $args[11];
 
     // add in the analysis
-    if ($args[13]) {
-      $analysis = chado_select_record('analysis', array('name'), array('analysis_id' => $args[13]));
+    if ($args[12] AND is_numeric($args[12])) {
+      $analysis = chado_select_record('analysis', array('name'), array('analysis_id' => $args[12]));
+      $new_args['Analysis'] = $analysis[0]->name;
     }
-    $new_args['Analysis'] = $analysis[0]->name;
   }
   if ($callback == 'tripal_feature_delete_features') {
     if ($args[0]) {
@@ -531,13 +541,19 @@ function tripal_feature_match_features_page($id) {
   if ($num_matches == 1) {
     drupal_goto("node/" . $curr_match->nid);
   }
-  if ($num_matches == 0) {
-    return "<p>No features matched the given name '$id'</p>";
-  }
 
   $table_attrs = array('class' => 'tripal-data-table');
+  $params = array(
+    'header' => $header,
+    'rows' => $rows,
+    'attributes' => $table_attrs,
+    'caption' => '',
+    'empty' => "No features matched the given name '$id'",
+    'sticky' => FALSE,
+    'colgroups' => array(),
+  );
   $output = "<p>The following features match the name '$id'.</p>";
-  $output .= theme_table($header, $rows, $table_attrs, $caption);
+  $output .= theme_table($params);
   return $output;
 }
 
@@ -551,12 +567,6 @@ function tripal_feature_match_features_page($id) {
  * @ingroup tripal_feature
  */
 function tripal_feature_form_alter(&$form, &$form_state, $form_id) {
-  if ($form_id == "tripal_feature_seq_extract_form") {
-    // updating the form through the ahah callback sets the action of
-    // the form to the ahah callback URL. We need to set it back
-    // to the normal form URL
-    $form['#action'] = url("find/sequences");
-  }
   // turn off preview button for insert/updates
   if ($form_id == "chado_feature_node_form") {
     $form['actions']['preview']['#access'] = FALSE;

+ 2 - 2
tripal_featuremap/includes/tripal_featuremap.chado_node.inc

@@ -172,7 +172,7 @@ function chado_featuremap_validate($node, $form, &$form_state) {
   if ($node->unittype_id == 0) {
     form_set_error('unittype_id', 'Please provide a unit type for this map.');
   }
-  
+
   // trim white space from text fields
   $node->fmapname = property_exists($node, 'fmapname') ? trim($node->fmapname) : '';
 
@@ -221,7 +221,7 @@ function chado_featuremap_validate($node, $form, &$form_state) {
  *
  * @ingroup tripal_featuremap
  */
-function chado_featuremap_node_access($node, $op, $account) {
+function tripal_featuremap_node_access($node, $op, $account) {
   $node_type = $node;
   if (is_object($node)) {
     $node_type = $node->type;

+ 23 - 18
tripal_featuremap/theme/templates/tripal_feature_featurepos.tpl.php

@@ -2,18 +2,18 @@
 
 // expand the feature object to include the records from the featurepos table
 // specify the number of features to show by default and the unique pager ID
-$num_results_per_page = 25; 
+$num_results_per_page = 5;
 $featurepos_pager_id = 20;
 
 // get the maps associated with this feature
 $feature = $variables['node']->feature;
-$options = array(  
+$options = array(
   'return_array' => 1,
   'order_by' => array(
     'map_feature_id' => 'ASC'
   ),
   'pager' => array(
-    'limit' => $num_results_per_page, 
+    'limit' => $num_results_per_page,
     'element' => $featurepos_pager_id
   ),
   'include_fk' => array(
@@ -29,7 +29,7 @@ $options = array(
 
 $feature = chado_expand_var($feature, 'table', 'featurepos', $options);
 
-// because the featurepos table has  FK relationships with map_feature_id and feature_id with the feature table 
+// because the featurepos table has  FK relationships with map_feature_id and feature_id with the feature table
 // the function call above will try to expand both and will create an array of matches for each FK.
 // we only want to show the map that this feature belongs to
 $map_positions = $feature->featurepos->map_feature_id;
@@ -39,20 +39,20 @@ $total_records = chado_pager_get_count($featurepos_pager_id);
 
 
 if(count($map_positions) > 0){ ?>
-  <div class="tripal_feature-data-block-desc tripal-data-block-desc">This feature is contained in the following <?php print number_format($total_records) ?> map(s):</div><?php 
+  <div class="tripal_feature-data-block-desc tripal-data-block-desc">This feature is contained in the following <?php print number_format($total_records) ?> map(s):</div><?php
 
   // the $headers array is an array of fields to use as the colum headers.
   // additional documentation can be found here
   // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
   $headers = array('Map Name', 'Landmark', 'Type', 'Position');
-  
+
   // the $rows array contains an array of rows where each row is an array
   // of values for each column of the table in that row.  Additional documentation
   // can be found here:
   // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
   $rows = array();
 
-  // iterate through our map positions    
+  // iterate through our map positions
   foreach ($map_positions as $position){
     $map_feature = $position->map_feature_id;
 
@@ -61,7 +61,7 @@ if(count($map_positions) > 0){ ?>
     $options = array(
       'return_array' => 1,
       'include_fk' => array(
-        'type_id' => 1,            
+        'type_id' => 1,
       ),
     );
     $position = chado_expand_var($position, 'table', 'featureposprop', $options);
@@ -76,8 +76,8 @@ if(count($map_positions) > 0){ ?>
          if ($property->type_id->name == 'stop') {
            $stop = $property->value;
          }
-      }      
-    }  
+      }
+    }
     if ($start and $stop and $start != $stop) {
       $mappos = "$start-$stop";
     }
@@ -87,20 +87,20 @@ if(count($map_positions) > 0){ ?>
     if ($start and $stop and $start == $stop) {
       $mappos = $start;
     }
-    
+
     // get the map name feature
     $map_name =  $position->featuremap_id->name;
     if (property_exists($position->featuremap_id, 'nid')) {
       $map_name = l($map_name, 'node/' . $position->featuremap_id->nid, array('attributes' => array('target' => '_blank')));
     }
-    
-    
+
+
     // get the landmark
     $landmark = $map_feature->name;
     if (property_exists($map_feature, 'nid')) {
       $landmark =  l($landmark, 'node/' . $map_feature->nid, array('attributes' => array('target' => '_blank')));
     }
-    
+
     $rows[] = array(
       $map_name,
       $landmark,
@@ -127,22 +127,27 @@ if(count($map_positions) > 0){ ?>
 
   // once we have our table array structure defined, we call Drupal's theme_table()
   // function to generate the table.
-  print theme_table($table); 
-  
+  print theme_table($table);
+
   // the $pager array values that control the behavior of the pager.  For
   // documentation on the values allows in this array see:
   // https://api.drupal.org/api/drupal/includes!pager.inc/function/theme_pager/7
   // here we add the paramter 'block' => 'features'. This is because
   // the pager is not on the default block that appears. When the user clicks a
   // page number we want the browser to re-appear with the page is loaded.
+  // We remove the 'pane' parameter from the original query parameters because
+  // Drupal won't reset the parameter if it already exists.
+  $get = $_GET;
+  unset($_GET['pane']);
   $pager = array(
     'tags' => array(),
     'element' => $featurepos_pager_id,
     'parameters' => array(
-      'block' => 'featurepos'
+      'pane' => 'featurepos'
     ),
     'quantity' => $num_results_per_page,
   );
-  print theme_pager($pager); 
+  print theme_pager($pager);
+  $_GET = $get;
 }?>
 

+ 27 - 22
tripal_featuremap/theme/templates/tripal_featuremap_featurepos.tpl.php

@@ -4,15 +4,15 @@ $feature_positions = array();
 
 // expand the featuremap object to include the records from the featurepos table
 // specify the number of features to show by default and the unique pager ID
-$num_results_per_page = 25; 
+$num_results_per_page = 25;
 $featurepos_pager_id = 0;
 
 // get the features aligned on this map
-$options = array(  
+$options = array(
   'return_array' => 1,
   'order_by' => array('map_feature_id' => 'ASC'),
   'pager' => array(
-    'limit' => $num_results_per_page, 
+    'limit' => $num_results_per_page,
     'element' => $featurepos_pager_id
   ),
   'include_fk' => array(
@@ -38,30 +38,30 @@ $total_features = chado_pager_get_count($featurepos_pager_id);
 
 
 if(count($feature_positions) > 0){ ?>
-  <div class="tripal_featuremap-data-block-desc tripal-data-block-desc">This map contains <?php print number_format($total_features) ?> features:</div> <?php 
-  
+  <div class="tripal_featuremap-data-block-desc tripal-data-block-desc">This map contains <?php print number_format($total_features) ?> features:</div> <?php
+
   // the $headers array is an array of fields to use as the colum headers.
   // additional documentation can be found here
   // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
   $headers = array('Landmark', 'Type', 'Organism', 'Feature Name', 'Type', 'Position');
-  
+
   // the $rows array contains an array of rows where each row is an array
   // of values for each column of the table in that row.  Additional documentation
   // can be found here:
   // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
   $rows = array();
-  
+
   foreach ($feature_positions as $position){
     $map_feature = $position->map_feature_id;
-    $feature     = $position->feature_id;  
-    $organism    = $map_feature->organism_id; 
+    $feature     = $position->feature_id;
+    $organism    = $map_feature->organism_id;
 
     // check if there are any values in the featureposprop table for the start and stop
     $mappos = $position->mappos;
     $options = array(
       'return_array' => 1,
       'include_fk' => array(
-        'type_id' => 1,            
+        'type_id' => 1,
       ),
     );
     $position = chado_expand_var($position, 'table', 'featureposprop', $options);
@@ -76,18 +76,18 @@ if(count($feature_positions) > 0){ ?>
          if ($property->type_id->name == 'stop') {
            $stop = $property->value;
          }
-      }      
-    }  
+      }
+    }
     if ($start and $stop and $start != $stop) {
       $mappos = "$start-$stop";
     }
     if ($start and !$stop) {
       $mappos = $start;
-    } 
+    }
     if ($start and $stop and $start == $stop) {
       $mappos = $start;
     }
-    
+
     $mfname = $map_feature->name;
     if (property_exists($map_feature, 'nid')) {
       $mfname =  l($mfname, 'node/' . $map_feature->nid, array('attributes' => array('target' => '_blank')));
@@ -95,18 +95,18 @@ if(count($feature_positions) > 0){ ?>
     $orgname = $organism->genus ." " . $organism->species ." (" . $organism->common_name .")";
     if (property_exists($organism, 'nid')) {
       $orgname = l(
-        "<i>" . $organism->genus . " " . $organism->species . "</i> (" . $organism->common_name .")", 
-        "node/". $organism->nid, 
+        "<i>" . $organism->genus . " " . $organism->species . "</i> (" . $organism->common_name .")",
+        "node/". $organism->nid,
         array('html' => TRUE, 'attributes' => array('target' => '_blank'))
       );
     }
     $organism =  $organism->genus . ' ' . $organism->species;
-    
+
     $fname = $feature->name;
     if (property_exists($feature, 'nid')) {
       $fname = l($fname, 'node/' . $feature->nid, array('attributes' => array('target' => '_blank')));
     }
-      
+
     $rows[] = array(
       $mfname,
       $map_feature->type_id->name,
@@ -115,7 +115,7 @@ if(count($feature_positions) > 0){ ?>
       $feature->type_id->name,
       $mappos . ' ' . $position->featuremap_id->unittype_id->name
     );
-  } 
+  }
   // the $table array contains the headers and rows array as well as other
   // options for controlling the display of the table.  Additional
   // documentation can be found here:
@@ -132,7 +132,7 @@ if(count($feature_positions) > 0){ ?>
     'colgroups' => array(),
     'empty' => '',
   );
-  
+
   // once we have our table array structure defined, we call Drupal's theme_table()
   // function to generate the table.
   print theme_table($table);
@@ -143,14 +143,19 @@ if(count($feature_positions) > 0){ ?>
   // here we add the paramter 'block' => 'features'. This is because
   // the pager is not on the default block that appears. When the user clicks a
   // page number we want the browser to re-appear with the page is loaded.
+  // We remove the 'pane' parameter from the original query parameters because
+  // Drupal won't reset the parameter if it already exists.
+  $get = $_GET;
+  unset($_GET['pane']);
   $pager = array(
     'tags' => array(),
     'element' => $featurepos_pager_id,
     'parameters' => array(
-      'block' => 'featurepos'
+      'pane' => 'featurepos'
     ),
     'quantity' => $num_results_per_page,
   );
-  print theme_pager($pager); 
+  print theme_pager($pager);
+  $_GET = $get;
 }
 

+ 1 - 1
tripal_featuremap/tripal_featuremap.info

@@ -3,7 +3,7 @@ description = Supports the map tables of Chado by providing pages for viewing an
 core = 7.x
 project = tripal
 package = Tripal
-version = 7.x-2.1-beta2
+version = 7.x-2.1
 
 dependencies[] = tripal_core
 dependencies[] = tripal_views

+ 30 - 30
tripal_featuremap/tripal_featuremap.install

@@ -548,73 +548,73 @@ function tripal_featuremap_update_7201() {
     $fkey_exists = db_query('SELECT TRUE FROM pg_constraint WHERE conname = :constraint', array(':constraint' => 'featuremapprop_type_id_fkey'))->fetchField();
     if ($fkey_exists) {
       // featuremapprop table
-      db_query('
-        ALTER TABLE chado.featuremapprop
+      chado_query('
+        ALTER TABLE {featuremapprop}
         DROP CONSTRAINT featuremapprop_type_id_fkey CASCADE
       ');
-      db_query('
-        ALTER TABLE chado.featuremapprop
+      chado_query('
+        ALTER TABLE {featuremapprop}
         DROP CONSTRAINT featuremapprop_featuremap_id_fkey CASCADE
       ');
     }
-    db_query('
-      ALTER TABLE chado.featuremapprop
+    chado_query('
+      ALTER TABLE {featuremapprop}
       ADD CONSTRAINT featuremapprop_type_id_fkey
-      FOREIGN KEY (type_id) REFERENCES chado.cvterm (cvterm_id)
+      FOREIGN KEY (type_id) REFERENCES {cvterm} (cvterm_id)
       ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED
     ');
-    db_query('
-      ALTER TABLE chado.featuremapprop
+    chado_query('
+      ALTER TABLE {featuremapprop}
       ADD CONSTRAINT featuremapprop_featuremap_id_fkey
-      FOREIGN KEY (featuremap_id) REFERENCES chado.featuremap (featuremap_id)
+      FOREIGN KEY (featuremap_id) REFERENCES {featuremap} (featuremap_id)
       ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED
     ');
 
     // featuremap_dbref table
     if ($fkey_exists) {
-      db_query('
-        ALTER TABLE chado.featuremap_dbxref
+      chado_query('
+        ALTER TABLE {featuremap_dbxref}
         DROP CONSTRAINT featuremap_dbxref_dbxref_id_fkey CASCADE
       ');
-      db_query('
-        ALTER TABLE chado.featuremap_dbxref
+      chado_query('
+        ALTER TABLE {featuremap_dbxref}
         DROP CONSTRAINT featuremap_dbxref_featuremap_id_fkey CASCADE
       ');
     }
-    db_query('
-      ALTER TABLE chado.featuremap_dbxref
+    chado_query('
+      ALTER TABLE {featuremap_dbxref}
       ADD CONSTRAINT featuremap_dbxref_dbxref_id_fkey
-      FOREIGN KEY (dbxref_id) REFERENCES chado.dbxref (dbxref_id)
+      FOREIGN KEY (dbxref_id) REFERENCES {dbxref} (dbxref_id)
       ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED
     ');
-    db_query('
-      ALTER TABLE chado.featuremap_dbxref
+    chado_query('
+      ALTER TABLE {featuremap_dbxref}
       ADD CONSTRAINT featuremap_dbxref_featuremap_id_fkey
-      FOREIGN KEY (featuremap_id) REFERENCES chado.featuremap (featuremap_id)
+      FOREIGN KEY (featuremap_id) REFERENCES {featuremap} (featuremap_id)
       ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED
     ');
 
     // featureposprop
     if ($fkey_exists) {
-      db_query('
-        ALTER TABLE chado.featureposprop
+      chado_query('
+        ALTER TABLE {featureposprop}
         DROP CONSTRAINT featureposprop_type_id_fkey CASCADE
       ');
-      db_query('
-        ALTER TABLE chado.featureposprop
+      chado_query('
+        ALTER TABLE {featureposprop}
         DROP CONSTRAINT featureposprop_featurepos_id_fkey CASCADE
       ');
     }
-    db_query('
-      ALTER TABLE chado.featureposprop
+    chado_query('
+      ALTER TABLE {featureposprop}
       ADD CONSTRAINT featureposprop_type_id_fkey
-      FOREIGN KEY (type_id) REFERENCES chado.cvterm (cvterm_id)
+      FOREIGN KEY (type_id) REFERENCES {cvterm} (cvterm_id)
       ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED
     ');
-    db_query('
-      ALTER TABLE chado.featureposprop
+    chado_query('
+      ALTER TABLE {featureposprop}
       ADD CONSTRAINT featureposprop_featurepos_id_fkey
-      FOREIGN KEY (featurepos_id) REFERENCES chado.featurepos (featurepos_id)
+      FOREIGN KEY (featurepos_id) REFERENCES {featurepos} (featurepos_id)
       ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED
     ');
   }

+ 38 - 33
tripal_genetic/theme/templates/tripal_feature_genotypes.tpl.php

@@ -1,31 +1,31 @@
 <?php
 /*
  * Details about genotypes associated with features can be found in the following way:
- * 
+ *
  * feature => feature_genotype => genotype
- *   
- * There are two ways that features with genotypes can be associated with stocks.  The first, 
+ *
+ * There are two ways that features with genotypes can be associated with stocks.  The first,
  * more simple method, is by traversion the FK relationships in this manner:
- * 
+ *
  *   Simple Method: feature => feature_genotype => genotype => stock_genotype => stock
- *   
+ *
  * The second method involves use of the natural diversity tables which allows for association
- * or more ancilliary information. Within the Natural Diversity tables, if a feature has genotypes then 
- * you can find the corresponding stock by traversing the FK relationships 
- * in this manner: 
- * 
+ * or more ancilliary information. Within the Natural Diversity tables, if a feature has genotypes then
+ * you can find the corresponding stock by traversing the FK relationships
+ * in this manner:
+ *
  *   ND Method:     feature => feature_genotype => nd_experiment_genotype => nd_experiment => nd_experiment_stock => stock
- * 
- * The tripal_natural_diversity module handles association of stocks using the ND method.  
+ *
+ * The tripal_natural_diversity module handles association of stocks using the ND method.
  * This template handles association of stocks when stored using the simple method.
  * If the tripal_natural_diversity module is enabled then this template will not show.
  * You should instead see the tripal_feature.nd_genotypes.tpl.php template
- * 
+ *
  */
 $feature = $variables['node']->feature;
 
 // specify the number of genotypes to show by default and the unique pager ID
-$num_results_per_page = 25; 
+$num_results_per_page = 25;
 $feature_pager_id = 15;
 
 // get the genotypes from the feature_genotype table
@@ -36,7 +36,7 @@ $options = array(
     'element' => $feature_pager_id
   ),
 );
-$feature = chado_expand_var($feature, 'table', 'feature_genotype', $options); 
+$feature = chado_expand_var($feature, 'table', 'feature_genotype', $options);
 $feature_genotypes = $feature->feature_genotype->feature_id;
 
 // get the total number of records
@@ -44,8 +44,8 @@ $total_records = chado_pager_get_count($feature_pager_id);
 
 // now iterate through the feature genotypes and print a paged table.
 if (count($feature_genotypes) > 0) {?>
-  <div class="tripal_feature-data-block-desc tripal-data-block-desc">This following <?php print number_format($total_records) ?> genotype(s) have been recorded for this feature.</div><?php 
-  
+  <div class="tripal_feature-data-block-desc tripal-data-block-desc">This following <?php print number_format($total_records) ?> genotype(s) have been recorded for this feature.</div><?php
+
   // the $headers array is an array of fields to use as the colum headers.
   // additional documentation can be found here
   // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
@@ -56,26 +56,26 @@ if (count($feature_genotypes) > 0) {?>
   // can be found here:
   // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
   $rows = array();
-  
+
   foreach($feature_genotypes as $feature_genotype) {
     $genotype = $feature_genotype->genotype_id;
-    
+
     // show the uniquename for the genotype unless a name exists
     $name = $genotype->uniquename;
     if ($genotype->name){
       $name = $genotype->name;
     }
-    
+
     // get the genotype type
     $type = 'N/A';
     if ($genotype->type_id) {
       $type = ucwords(preg_replace('/_/', ' ', $genotype->type_id->name));
     }
-    
+
     // get the genotype properties
     $options = array('return_array' => 1);
     $genotype = chado_expand_var($genotype, 'table', 'genotypeprop', $options);
-    $properties = $genotype->genotypeprop; 
+    $properties = $genotype->genotypeprop;
     $details = '';
     if(count($properties) > 0) {
       foreach ($properties as $property){
@@ -83,7 +83,7 @@ if (count($feature_genotypes) > 0) {?>
       }
       $details = substr($details, 0, -4); // remove trailing <br>
     }
-    
+
     // add in stocks associated with this genotype if any
     $options = array(
       'return_array' => 1,
@@ -94,21 +94,21 @@ if (count($feature_genotypes) > 0) {?>
       ),
     );
     $genotype = chado_expand_var($genotype, 'table', 'stock_genotype', $options);
-    $stock_genotypes = $genotype->stock_genotype; 
+    $stock_genotypes = $genotype->stock_genotype;
 
     // build the list of germplasm.
     $stock_names = '';
-    if(count($stock_genotypes) > 0) { 
-      foreach ($stock_genotypes as $stock_genotype){ 
-        $stock = $stock_genotype->stock_id; 
-        $stock_name = $stock->name . ' (' . $stock->uniquename . ')'; 
+    if(count($stock_genotypes) > 0) {
+      foreach ($stock_genotypes as $stock_genotype){
+        $stock = $stock_genotype->stock_id;
+        $stock_name = $stock->name . ' (' . $stock->uniquename . ')';
         if(property_exists($stock, 'nid')) {
           $stock_name = l($stock_name, 'node/' . $stock->nid, array('attributes' => array('target' => '_blank')));
         }
         $stock_names .= $stock_name . '<br>';
       }
       $stock_names = substr($stock_names, 0, -4); // remove trailing <br>
-    } 
+    }
     // add the fields to the table row
     $rows[] = array(
       $name,
@@ -118,7 +118,7 @@ if (count($feature_genotypes) > 0) {?>
       $stock_names
     );
   }
-   
+
   // the $table array contains the headers and rows array as well as other
   // options for controlling the display of the table.  Additional
   // documentation can be found here:
@@ -135,24 +135,29 @@ if (count($feature_genotypes) > 0) {?>
     'colgroups' => array(),
     'empty' => '',
   );
-  
+
   // once we have our table array structure defined, we call Drupal's theme_table()
   // function to generate the table.
-  print theme_table($table); 
-  
+  print theme_table($table);
+
   // the $pager array values that control the behavior of the pager.  For
   // documentation on the values allows in this array see:
   // https://api.drupal.org/api/drupal/includes!pager.inc/function/theme_pager/7
   // here we add the paramter 'block' => 'features'. This is because
   // the pager is not on the default block that appears. When the user clicks a
   // page number we want the browser to re-appear with the page is loaded.
+  // We remove the 'pane' parameter from the original query parameters because
+  // Drupal won't reset the parameter if it already exists.
+  $get = $_GET;
+  unset($_GET['pane']);
   $pager = array(
     'tags' => array(),
     'element' => $feature_pager_id,
     'parameters' => array(
-      'block' => 'genotypes'
+      'pane' => 'genotypes'
     ),
     'quantity' => $num_results_per_page,
   );
   print theme_pager($pager);
+  $_GET = $get;
 }

+ 32 - 27
tripal_genetic/theme/templates/tripal_stock_genotypes.tpl.php

@@ -1,35 +1,35 @@
 <?php
 /*
- * Details about genotypes associated with stocks can be found in two ways by 
+ * Details about genotypes associated with stocks can be found in two ways by
  * traversing the the foreign key (FK) relationships in these ways:
- * 
+ *
  *   Simple Method: stock => stock_genotype => genotype
  *   ND Method:     stock => nd_experiment_stock => nd_experiment => nd_experiment_genotype => genotype
- *   
- * The tripal_natural_diversity module handles display of genotypes when stored using the 
+ *
+ * The tripal_natural_diversity module handles display of genotypes when stored using the
  * ND method.  This template handles display of genotype when stored using
  * the Simple Method.  If the tripal_natural_diversity module is enabled then this template
  * will not show.  You should instead see the tripal_stock.nd_genotypes.tpl.php template
- *  
+ *
  */
 $stock = $variables['node']->stock;
 
 // specify the number of genotypes to show by default and the unique pager ID
-$num_results_per_page = 25; 
+$num_results_per_page = 25;
 $stock_pager_id = 15;
 
 // get the genotypes from the stock_genotype table
 $options = array(
-  'return_array' => 1, 
+  'return_array' => 1,
   'pager' => array(
-    'limit' => $num_results_per_page, 
+    'limit' => $num_results_per_page,
     'element' => $stock_pager_id
   ),
   'fk_include' => array(
     'genotype_id' => 1
   ),
 );
-$stock = chado_expand_var($stock, 'table', 'stock_genotype', $options); 
+$stock = chado_expand_var($stock, 'table', 'stock_genotype', $options);
 $stock_genotypes = $stock->stock_genotype;
 
 // get the total number of records
@@ -38,26 +38,26 @@ $total_records = chado_pager_get_count($stock_pager_id);
 // now iterate through the stock genotypes and print a paged table.
 if (count($stock_genotypes) > 0) {?>
   <div class="tripal_stock-data-block-desc tripal-data-block-desc">The following <?php print number_format($total_records) ?> genotype(s) have been recorded for this stock.</div> <?php
-  
+
   // the $headers array is an array of fields to use as the colum headers.
   // additional documentation can be found here
   // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
   $headers = array('Name', 'Type', 'Genotype', 'Details', 'Markers');
-  
+
   // the $rows array contains an array of rows where each row is an array
   // of values for each column of the table in that row.  Additional documentation
   // can be found here:
   // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
   $rows = array();
-  
-  foreach($stock_genotypes as $stock_genotype) {       
+
+  foreach($stock_genotypes as $stock_genotype) {
     $genotype = $stock_genotype->genotype_id;
-    
+
     // get the genotype properties
     $options = array('return_array' => 1);
     $genotype = chado_expand_var($genotype, 'table', 'genotypeprop', $options);
-    $properties = $genotype->genotypeprop; 
-    
+    $properties = $genotype->genotypeprop;
+
     // add in markers associated with this genotype if any
     $options = array(
       'return_array' => 1,
@@ -68,8 +68,8 @@ if (count($stock_genotypes) > 0) {?>
       ),
     );
     $genotype = chado_expand_var($genotype, 'table', 'feature_genotype', $options);
-    $feature_genotypes = $genotype->feature_genotype; 
-    
+    $feature_genotypes = $genotype->feature_genotype;
+
     // show the uniquename for the genotype unless a name exists
     $name = $genotype->uniquename;
     if ($genotype->name){
@@ -80,7 +80,7 @@ if (count($stock_genotypes) > 0) {?>
     if ($genotype->type_id) {
       $type = ucwords(preg_replace('/_/', ' ', $genotype->type_id->name));
     }
-    
+
     // get the genotype properties
     $details = '';
     if(count($properties) > 0) {
@@ -89,7 +89,7 @@ if (count($stock_genotypes) > 0) {?>
       }
       $details = substr($details, 0, -4); // remove trailing <br>
     }
-    
+
     // build the list of marker features.
     $feature_names = 'N/A';
     if(count($feature_genotypes) > 0) {
@@ -104,7 +104,7 @@ if (count($stock_genotypes) > 0) {?>
       }
       $feature_names = substr($feature_names, 0, -4); // remove trailing <br>
     }
-      
+
     // add the fields to the table row
     $rows[] = array(
       $name,
@@ -113,8 +113,8 @@ if (count($stock_genotypes) > 0) {?>
       $details,
       $feature_names
     );
-  } 
-  
+  }
+
   // the $table array contains the headers and rows array as well as other
   // options for controlling the display of the table.  Additional
   // documentation can be found here:
@@ -134,20 +134,25 @@ if (count($stock_genotypes) > 0) {?>
   // once we have our table array structure defined, we call Drupal's theme_table()
   // function to generate the table.
   print theme_table($table);
-  
+
   // the $pager array values that control the behavior of the pager.  For
   // documentation on the values allows in this array see:
   // https://api.drupal.org/api/drupal/includes!pager.inc/function/theme_pager/7
   // here we add the paramter 'block' => 'features'. This is because
   // the pager is not on the default block that appears. When the user clicks a
   // page number we want the browser to re-appear with the page is loaded.
+  // We remove the 'pane' parameter from the original query parameters because
+  // Drupal won't reset the parameter if it already exists.
+  $get = $_GET;
+  unset($_GET['pane']);
   $pager = array(
     'tags' => array(),
     'element' => $stock_pager_id,
     'parameters' => array(
-      'block' => 'genotypes'
+      'pane' => 'genotypes'
     ),
     'quantity' => $num_results_per_page,
   );
-  print theme_pager($pager); 
-} 
+  print theme_pager($pager);
+  $_GET = $get;
+}

+ 1 - 1
tripal_genetic/tripal_genetic.info

@@ -3,7 +3,7 @@ description = Supports the genetic tables of Chado by providing pages for viewin
 core = 7.x
 project = tripal
 package = Tripal
-version = 7.x-2.1-beta2
+version = 7.x-2.1
 
 dependencies[] = tripal_core
 dependencies[] = tripal_views

+ 42 - 30
tripal_library/includes/tripal_library.chado_node.inc

@@ -37,7 +37,7 @@ function tripal_library_node_info() {
 }
 
 /**
- *  Implements hook_form().
+ * Implements hook_form().
  *
  * When editing or creating a new node of type 'chado_library' we need
  *  a form.  This function creates the form that will be used for this.
@@ -49,13 +49,14 @@ function chado_library_form($node, &$form_state) {
 
   // Default values can come in the following ways:
   //
-  // 1) as elements of the $node object.  This occurs when editing an existing library
-  // 2) in the $form_state['values'] array which occurs on a failed validation or
-  //    ajax callbacks from non submit form elements
-  // 3) in the $form_state['input'] array which occurs on ajax callbacks from submit
-  //    form elements and the form is being rebuilt
-  //
-  // set form field defaults
+  // 1) As elements of the $node object: this occurs when editing an existing
+  //    library.
+  // 2) In the $form_state['values'] array which occurs on a failed validation
+  //    or ajax callbacks from non submit form elements.
+  // 3) In the $form_state['input'] array which occurs on ajax callbacks from
+  //    submit form elements and the form is being rebuilt.
+
+  // Set form field defaults.
   $library_id = NULL;
   $libraryname = '';
   $uniquename = '';
@@ -63,7 +64,8 @@ function chado_library_form($node, &$form_state) {
   $organism_id = '';
   $description = '';
 
-  // if we are editing an existing node then the library is already part of the node
+  // If we are editing an existing node then the library is already part of
+  // the node
   if (property_exists($node, 'library')) {
     $library = $node->library;
     $library_id = $library->library_id;
@@ -79,15 +81,15 @@ function chado_library_form($node, &$form_state) {
     );
     $description = $libprop->value;
 
-    // keep track of the library id if we have.  If we do have one then
+    // Keep track of the library id if we have.  If we do have one then
     // this is an update as opposed to an insert.
     $form['library_id'] = array(
       '#type' => 'value',
       '#value' => $library_id,
     );
   }
-  // if we are re constructing the form from a failed validation or ajax callback
-  // then use the $form_state['values'] values
+  // If we are re constructing the form from a failed validation or ajax callback
+  // then use the $form_state['values'] values.
   if (array_key_exists('values', $form_state)) {
     $libraryname  = $form_state['values']['libraryname'];
     $uniquename   = $form_state['values']['uniquename'];
@@ -95,8 +97,8 @@ function chado_library_form($node, &$form_state) {
     $organism_id  = $form_state['values']['organism_id'];
     $description  = $form_state['values']['description'];
   }
-  // if we are re building the form from after submission (from ajax call) then
-  // the values are in the $form_state['input'] array
+  // If we are re building the form from after submission (from ajax call) then
+  // the values are in the $form_state['input'] array.
   if (array_key_exists('input', $form_state) and !empty($form_state['input'])) {
     $libraryname  = $form_state['input']['libraryname'];
     $uniquename   = $form_state['input']['uniquename'];
@@ -121,7 +123,7 @@ function chado_library_form($node, &$form_state) {
     '#default_value' => $uniquename,
   );
 
-  // get the list of library types
+  // Get the list of library types.
   $lt_cv = tripal_get_default_cv("library", "type_id");
   $types = tripal_get_cvterm_default_select_options('library', 'type_id', 'library types');
   $types[0] = 'Select a Type';
@@ -144,7 +146,7 @@ function chado_library_form($node, &$form_state) {
     '#suffix'        => $lt_message,
   );
 
-  // get the list of organisms
+  // Get the list of organisms.
   $sql = "SELECT * FROM {organism}";
   $org_rset = chado_query($sql);
 
@@ -172,36 +174,46 @@ function chado_library_form($node, &$form_state) {
     '#default_value' => $description,
   );
 
-  // PROPERTIES FORM
+  // PROPERTIES FORM.
   //---------------------------------------------
-  $select_options = array();
   $prop_cv = tripal_get_default_cv('libraryprop', 'type_id');
   $cv_id = $prop_cv ? $prop_cv->cv_id : NULL;
-  // if the default is the 'library_property' vocabulary then we want
-  // to exclude the 'Library Description' term since it has it's own form element above
+
+  $details = array(
+    // The name of the prop table.
+    'property_table' => 'libraryprop',
+    // The value of library_id for this record.
+    'chado_id' => $library_id,
+    // The cv.cv_id of the cv governing libraryprop.type_id.
+    'cv_id' => $cv_id,
+  );
+
+  // If the default is the 'library_property' vocabulary then we want
+  // to exclude the 'Library Description' term since it has it's own form
+  // element above
   if ($prop_cv->name == 'library_property') {
     // Generate our own select list so we can exclude the description element
+    $select_options = array();
     $cv_result = chado_select_record('cv', array('cv_id'), array('name' => 'library_property'));
     $cv_id = $cv_result[0]->cv_id;
     $select_options = tripal_get_cvterm_select_options($cv_id);
     $descrip_id = array_search('Library Description', $select_options);
     unset($select_options[$descrip_id]);
+    $details['select_options'] = $select_options;
   }
-  $details = array(
-    'property_table' => 'libraryprop',      // the name of the prop table
-    'chado_id' => $library_id,              // the value of library_id for this record
-    'cv_id' => $cv_id,                      // the cv.cv_id of the cv governing libraryprop.type_id
-    'select_options' => $select_options
-  );
+
   // Adds the form elements to your current form
   chado_add_node_form_properties($form, $form_state, $details);
 
   // ADDITIONAL DBXREFS FORM
   //---------------------------------------------
   $details = array(
-    'linking_table' => 'library_dbxref',  // the name of the _dbxref table
-    'base_foreign_key' => 'library_id',   // the name of the key in your base chado table
-    'base_key_value' => $library_id       // the value of library_id for this record
+    // The name of the _dbxref table.
+    'linking_table' => 'library_dbxref',
+    // The name of the key in your base chado table.
+    'base_foreign_key' => 'library_id',
+    // The value of library_id for this record.
+    'base_key_value' => $library_id
   );
   // Adds the form elements to your current form
   chado_add_node_form_dbxrefs($form, $form_state, $details);
@@ -478,7 +490,7 @@ function chado_library_delete(&$node) {
  *
  * @ingroup tripal_library
  */
-function chado_library_node_access($node, $op, $account) {
+function tripal_library_node_access($node, $op, $account) {
   $node_type = $node;
   if (is_object($node)) {
     $node_type = $node->type;

+ 6 - 1
tripal_library/theme/templates/tripal_library_features.tpl.php

@@ -86,15 +86,20 @@ if (count($features) > 0) { ?>
   // here we add the paramter 'block' => 'feature_browser'. This is because
   // the pager is not on the default block that appears. When the user clicks a
   // page number we want the browser to re-appear with the page is loaded.
+  // We remove the 'pane' parameter from the original query parameters because
+  // Drupal won't reset the parameter if it already exists.
+  $get = $_GET;
+  unset($_GET['pane']);
   $pager = array(
     'tags' => array(),
     'element' => $element,
     'parameters' => array(
-      'block' => 'features'
+      'pane' => 'features'
     ),
     'quantity' => $num_per_page,
   );
   print theme_pager($pager);
+  $_GET = $get;
 }
 
 

+ 1 - 1
tripal_library/theme/templates/tripal_organism_libraries.tpl.php

@@ -26,7 +26,7 @@ if (count($libraries) > 0) {?>
   foreach ($libraries as $library){ 
     
     $libname = $library->name;
-    if ($library->nid) {
+    if (isset($library->nid)) {
       $libname = l($libname, "node/".$library->nid, array('attributes' => array('target' => '_blank')));
     }
     

+ 1 - 1
tripal_library/tripal_library.info

@@ -3,7 +3,7 @@ description = Supports the library tables of Chado by providing pages for viewin
 core = 7.x
 project = tripal
 package = Tripal
-version = 7.x-2.1-beta2
+version = 7.x-2.1
 
 dependencies[] = tripal_core
 dependencies[] = tripal_views

+ 43 - 81
tripal_library/tripal_library.install

@@ -121,6 +121,7 @@ function tripal_library_add_mview_library_feature_count(){
     'description' => $comment,
     'fields' => array(
       'library_id' => array(
+        'size' => 'big',
         'type' => 'int',
         'not null' => TRUE,
       ),
@@ -268,15 +269,15 @@ function tripal_library_update_7200() {
   // site upgrade when the tripal_core module is disabled.
   module_load_include('module', 'tripal_core', 'tripal_core');
   tripal_core_import_api();
+  module_load_include('inc', 'tripal_cv', 'api/tripal_cv.api');
 
   // the library types were formerly in a vocabulary named 'tripal_library_types'.
-  // rename that to just be 'library_type'. We cannot use the Tripal API calls
-  // because during upgrade the tripal_core should also be disabled
+  // rename that to just be 'library_type'.
   try {
-    $check = db_query("SELECT cv_id FROM chado.cv WHERE name = 'library_type'")->fetchObject();
+    $check = chado_query("SELECT cv_id FROM {cv} WHERE name = 'library_type'")->fetchObject();
     if (!$check->cv_id) {
-      $sql = "UPDATE chado.cv SET name = 'library_type' WHERE name = 'tripal_library_types'";
-      db_query($sql);
+      $sql = "UPDATE {cv} SET name = 'library_type' WHERE name = 'tripal_library_types'";
+      chado_query($sql);
     }
   }
   catch (\PDOException $e) {
@@ -286,13 +287,18 @@ function tripal_library_update_7200() {
 
   // add the library_property CV
   try {
-    $check = db_query("SELECT cv_id FROM chado.cv WHERE name = 'library_property'")->fetchObject();
-    if (!$check->cv_id) {
-      $sql = "INSERT INTO chado.cv (name, definition) VALUES (
-        'library_property',
-        'Contains properties for libraries.')
-      ";
-      db_query($sql);
+    $cv = tripal_insert_cv(
+      'library_property',
+      'Contains properties for libraries.'
+    );
+    if ($cv) {
+      $cv_id = $cv->cv_id;
+
+      // Set as Default CV for library properties.
+      $is_set = tripal_get_default_cv('libraryprop', 'type_id');
+      if (!$is_set) {
+        tripal_set_default_cv('libraryprop','type_id', 'library_property', $cv_id);
+      }
     }
   }
   catch (\PDOException $e) {
@@ -302,13 +308,20 @@ function tripal_library_update_7200() {
 
   // add the library_type CV
   try {
-    $check = db_query("SELECT cv_id FROM chado.cv WHERE name = 'library_type'")->fetchObject();
-    if (!$check->cv_id) {
-      $sql = "INSERT INTO chado.cv (name, definition) VALUES (
-        'library_type',
-        'Contains terms for types of libraries (e.g. BAC, cDNA, FOSMID, etc).')
-      ";
-      db_query($sql);
+    // Note: tripal_insert_cv will only insert it if doesn't already exist
+    // so this doesn't conflict with the update above.
+    $cv = tripal_insert_cv(
+      'library_type',
+      'Contains terms for types of libraries (e.g. BAC, cDNA, FOSMID, etc).'
+    );
+    if ($cv) {
+      $cv_id = $cv->cv_id;
+
+      // Set as Default CV for library types.
+      $is_set = tripal_get_default_cv('library', 'type_id');
+      if (!$is_set) {
+        tripal_set_default_cv('library','type_id', 'library_type', $cv_id);
+      }
     }
   }
   catch (\PDOException $e) {
@@ -320,19 +333,17 @@ function tripal_library_update_7200() {
   // 'tripal' CV.  It should be stored in the new library_property CV that
   // is added by this module for Tripal 2.0 and Drupal 7.  So, we need to
   // reset the CV ID for that term and rename the term to 'Library Description'
-  // We cannot use the Tripal API calls in the 7000 update
-  // because during upgrade the tripal_core should also be disabled
-  $sql = "
-    UPDATE chado.cvterm
-    SET
-      name = 'Library Description',
-      cv_id = (SELECT cv_id FROM chado.cv WHERE name = 'library_property')
-    WHERE
-      name = 'library_description' AND
-      cv_id = (SELECT cv_id FROM chado.cv WHERE name = 'tripal')
-  ";
   try {
-    db_query($sql);
+    $sql = "
+      UPDATE {cvterm}
+      SET
+        name = 'Library Description',
+        cv_id = (SELECT cv_id FROM {cv} WHERE name = 'library_property')
+      WHERE
+        name = 'library_description' AND
+        cv_id = (SELECT cv_id FROM {cv} WHERE name = 'tripal')
+    ";
+    chado_query($sql);
   }
   catch (\PDOException $e) {
     $error = $e->getMessage();
@@ -376,55 +387,6 @@ function tripal_library_update_7200() {
       throw new DrupalUpdateException('Could not move library taxonomy terms: '. $error);
     }
   }
-
-  // set the default vocabularies
-  // library_type
-  try {
-    $cv_id = db_query("SELECT cv_id FROM chado.cv WHERE name = 'library_type'")->fetchField();
-    $cdi = db_select('tripal_cv_defaults', 't')
-      ->fields('t', array('cv_default_id'))
-      ->condition('table_name', 'library')
-      ->condition('field_name', 'type_id')
-      ->execute()
-      ->fetchField();
-    if (!$cdi) {
-      db_insert('tripal_cv_defaults')
-        ->fields(array(
-          'table_name' => 'library',
-          'field_name' => 'type_id',
-          'cv_id' => $cv_id
-        ))
-        ->execute();
-    }
-  }
-  catch (\PDOException $e) {
-    $error = $e->getMessage();
-    throw new DrupalUpdateException('Failed to set library_type vocabulary as default: '. $error);
-  }
-  // library_property
-  try {
-    $cv_id = db_query("SELECT cv_id FROM chado.cv WHERE name = 'library_property'")->fetchField();
-    $cdi = db_select('tripal_cv_defaults', 't')
-      ->fields('t', array('cv_default_id'))
-      ->condition('table_name', 'libraryprop')
-      ->condition('field_name', 'type_id')
-      ->execute()
-      ->fetchField();
-    if (!$cdi) {
-      db_insert('tripal_cv_defaults')
-        ->fields(array(
-          'table_name' => 'libraryprop',
-          'field_name' => 'type_id',
-          'cv_id' => $cv_id
-        ))
-        ->execute();
-    }
-  }
-  catch (\PDOException $e) {
-    $error = $e->getMessage();
-    throw new DrupalUpdateException('Failed to set the library_property vocabulary as default: '. $error);
-  }
-
 }
 
 /**
@@ -482,4 +444,4 @@ function tripal_library_update_7201() {
       ->condition('name', $view_name)
       ->execute();
   }
-}
+}

+ 35 - 30
tripal_natural_diversity/theme/templates/tripal_feature_nd_genotypes.tpl.php

@@ -2,25 +2,25 @@
 /*
  * Deatils about genotypes associated features can be found by traversing the foreign key (FK)
  * relationships in this way
- * 
+ *
  * feature => feature_genotype => genotype
  *
- * There are two ways that features with genotypes can be associated with stocks.  The first, 
+ * There are two ways that features with genotypes can be associated with stocks.  The first,
  * more simple method, is by traversion the FK relationships in this manner:
- * 
+ *
  *   Simple Method: feature => feature_genotype => genotype => stock_genotype => stock
- *   
+ *
  * The second method involves use of the natural diversity (ND) tables which allows for association
- * or more ancilliary information. Within the ND tables, If a feature has genotypes then 
- * you can find the corresponding stock by traversing the FK relationships 
- * in this manner: 
- * 
+ * or more ancilliary information. Within the ND tables, If a feature has genotypes then
+ * you can find the corresponding stock by traversing the FK relationships
+ * in this manner:
+ *
  *   ND MEthod: feature => feature_genotype => nd_experiment_genotype => nd_experiment => nd_experiment_stock => stock
- * 
+ *
  * You can find ancilliary information about data associated with a genotype in the ND tables such as
- * a contact, pub, protocol, project, genotype, dbxref by using the 
+ * a contact, pub, protocol, project, genotype, dbxref by using the
  * nd_experiment.nd_experiment_id value and traversing the other FK relationships
- * 
+ *
  * feature => feature_genotype => nd_experiment_genotype => nd_experiment => nd_experiment_stock => stock
  *                                                                        => nd_experiment_project => project
  *                                                                        => nd_experiment_pub => pub
@@ -29,16 +29,16 @@
  *                                                                        => nd_experiment_protocol => protocol
  *                                                                        => nd_experiment_stockprop
  *                                                                        => nd_experiment_stock_dbxref
- * 
- * In the FK relationships shown above, the nd_experiment_id value represents a single 
- * experimental value that may have all of the ancilliary data associated with it.  
+ *
+ * In the FK relationships shown above, the nd_experiment_id value represents a single
+ * experimental value that may have all of the ancilliary data associated with it.
  * If the genotype record shares an nd_experiment_id with a genotype, pub, contact,
  * protocol, etc then all of that data is associated with the genotype and vice-versa.
- * 
- * Techincally, we can skip including the 'nd_experiment' table when traversing the FK's 
- * because we have the nd_experiment_id value when we get the nd_experiment_genotype record. 
- * 
- * NOTE: if the tripal_natural_diversity module is enabled this template will supercede 
+ *
+ * Techincally, we can skip including the 'nd_experiment' table when traversing the FK's
+ * because we have the nd_experiment_id value when we get the nd_experiment_genotype record.
+ *
+ * NOTE: if the tripal_natural_diversity module is enabled this template will supercede
  * the tripal_feature_genotypes.tpl.php template (provided by the tripal_genetic module).
  * Therefore, this template must handle both cases for linking to stocks as described above
  */
@@ -67,7 +67,7 @@ $total_records = chado_pager_get_count($feature_pager_id);
 
 // now iterate through the feature genotypes and print a paged table.
 if (count($feature_genotypes) > 0) { ?>
-  <div class="tripal_feature-data-block-desc tripal-data-block-desc">This following <?php print number_format($total_records) ?> genotype(s) have been recorded for this feature.</div> <?php 
+  <div class="tripal_feature-data-block-desc tripal-data-block-desc">This following <?php print number_format($total_records) ?> genotype(s) have been recorded for this feature.</div> <?php
 
   // the $headers array is an array of fields to use as the colum headers.
   // additional documentation can be found here
@@ -79,11 +79,11 @@ if (count($feature_genotypes) > 0) { ?>
   // can be found here:
   // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
   $rows = array();
-  
+
   foreach ($feature_genotypes as $feature_genotype) {
     $project_names = 'N/A';
     $stock_names   = 'N/A';
-    
+
     // get the genotype from the feature_genotype record
     $genotype = $feature_genotype->genotype_id;
 
@@ -93,7 +93,7 @@ if (count($feature_genotypes) > 0) { ?>
     if ($genotype->name){
       $name = $genotype->name;
     }
-    
+
     // build the genotype type for display
     $type = 'N/A';
     if ($genotype->type_id) {
@@ -143,7 +143,7 @@ if (count($feature_genotypes) > 0) { ?>
         }
         $stock_names = substr($stock_names, 0, -4); // remove trailing <br>
       }
-      
+
       // expand the nd_experiment object to incldue the nd_experiment_project table
       $values = array('nd_experiment_id' => $nd_experiment_id);
       $options = array('return_array' => 1);
@@ -171,8 +171,8 @@ if (count($feature_genotypes) > 0) { ?>
       $stock_names,
       $project_names,
     );
-  } 
-  
+  }
+
   // the $table array contains the headers and rows array as well as other
   // options for controlling the display of the table.  Additional
   // documentation can be found here:
@@ -191,21 +191,26 @@ if (count($feature_genotypes) > 0) { ?>
   );
   // once we have our table array structure defined, we call Drupal's theme_table()
   // function to generate the table.
-  print theme_table($table); 
-  
+  print theme_table($table);
+
   // the $pager array values that control the behavior of the pager.  For
   // documentation on the values allows in this array see:
   // https://api.drupal.org/api/drupal/includes!pager.inc/function/theme_pager/7
   // here we add the paramter 'block' => 'features'. This is because
   // the pager is not on the default block that appears. When the user clicks a
   // page number we want the browser to re-appear with the page is loaded.
+  // We remove the 'pane' parameter from the original query parameters because
+  // Drupal won't reset the parameter if it already exists.
+  $get = $_GET;
+  unset($_GET['pane']);
   $pager = array(
     'tags' => array(),
     'element' => $feature_pager_id,
     'parameters' => array(
-      'block' => 'genotypes'
+      'pane' => 'genotypes'
     ),
     'quantity' => $num_results_per_page,
   );
-  print theme_pager($pager); 
+  print theme_pager($pager);
+  $_GET = $get;
 }

+ 44 - 39
tripal_natural_diversity/theme/templates/tripal_stock_nd_genotypes.tpl.php

@@ -1,26 +1,26 @@
 <?php
 /*
- * Details about genotypes associated with stocks can be found in two ways by 
+ * Details about genotypes associated with stocks can be found in two ways by
  * traversing the the foreign key (FK) relationships in these ways:
- * 
+ *
  *   Simple Method: stock => stock_genotype => genotype
  *   ND Method:     stock => nd_experiment_stock => nd_experiment => nd_experiment_genotype => genotype
  *
- * The tripal_genetic module handles display of genotypes when stored using the 
+ * The tripal_genetic module handles display of genotypes when stored using the
  * simple method.  This template handles display of genotype when stored using
- * the ND Method.  The ND method uses the natural diversity tables and allows for 
- * association or more ancilliary information. 
- * 
- * 
- * Within the ND tables, If a stock has genotypes then you can find the corresponding 
- * features by traversing the FK relationships in this manner: 
- * 
+ * the ND Method.  The ND method uses the natural diversity tables and allows for
+ * association or more ancilliary information.
+ *
+ *
+ * Within the ND tables, If a stock has genotypes then you can find the corresponding
+ * features by traversing the FK relationships in this manner:
+ *
  * stock => nd_experiment_stock => nd_experiment => nd_experiment_genotype => genotype => feature_genotype => feature
- * 
+ *
  * You can find ancilliary information about data associated with a genotype in the ND tables such as
- * a contact, pub, protocol, project, genotype, dbxref by using the 
+ * a contact, pub, protocol, project, genotype, dbxref by using the
  * nd_experiment.nd_experiment_id value and traversing the other FK relationships
- * 
+ *
  * stock => nd_experiment_stock => nd_experiment => nd_experiment_project => project
  *                                               => nd_experiment_pub => pub
  *                                               => nd_experiment_contact => contact
@@ -28,21 +28,21 @@
  *                                               => nd_experiment_protocol => protocol
  *                                               => nd_experiment_stockprop
  *                                               => nd_experiment_stock_dbxref
- * 
- * In the FK relationships shown above, the nd_experiment_id value represents a single 
- * experimental unit that may have all of the ancilliary data associated with it or none.  
+ *
+ * In the FK relationships shown above, the nd_experiment_id value represents a single
+ * experimental unit that may have all of the ancilliary data associated with it or none.
  * If the genotype record shares an nd_experiment_id with a genotype, pub, contact,
  * protocol, etc then all of that data is associated with the genotype and vice-versa.
- * 
- * Techincally, we can skip including the 'nd_experiment' table when traversing the FK's 
+ *
+ * Techincally, we can skip including the 'nd_experiment' table when traversing the FK's
  * because we have the nd_experiment_id value when we get the nd_experiment_stock record.
- * 
+ *
  * When lots of genotypes are associated with a stock (e.g. thousands) then traversing
  * the FK relationships as described above can be very slow. Ideally, we only need to
- * show a small subset with a pager. Therefore, a list of nd_experiment_genotype_id's 
+ * show a small subset with a pager. Therefore, a list of nd_experiment_genotype_id's
  * are provided to this template automatically within the stock object.
- * 
- * NOTE: if the tripal_natural_diversity module is enabled this template will supercede 
+ *
+ * NOTE: if the tripal_natural_diversity module is enabled this template will supercede
  * the tripal_stock_genotypes.tpl.php template (provided by the tripal_genetic module).
  * Therefore, this template must handle both cases for linking to features as described above
  */
@@ -57,7 +57,7 @@ $stock_pager_id = 15;
 
 // the nd_experiment_genotype IDs get passed into this template, so we use
 // those to iterate and show a subset via a pager.  This is faster than trying
-// to traverse all of the FK relationship, especially when thousands of 
+// to traverse all of the FK relationship, especially when thousands of
 // associations may be present.  Because the nd_experiment_id in Chado
 // can be associated with other data types it becomes slow to use the
 // chado_expand_var functions that we would normal use.
@@ -70,13 +70,13 @@ $offset = $num_results_per_page * $current_page_num;
 
 $genotypes = array();
 if ($total_records > 0) {
-  
+
   // iterate through the nd_experiment_genotype_ids and get the genotype record
   for ($i = $offset ; $i < $offset + $num_results_per_page; $i++) {
     $nd_experiment_genotype_id = $nd_experiment_genotype_ids[$i];
-      
+
     // expand the nd_experiment record to include the nd_experiment_genotype table
-    // there many be many genotypes for a stock so we want to use a pager to limit 
+    // there many be many genotypes for a stock so we want to use a pager to limit
     // the results returned
     $options = array(
       'return_array' => 1,
@@ -98,7 +98,7 @@ if ($total_records > 0) {
 if (count($genotypes) > 0) { ?>
   <div class="tripal_feature-data-block-desc tripal-data-block-desc">
     The following <?php print number_format($total_records) ?> genotype(s) have been recorded.
-  </div> <?php 
+  </div> <?php
 
   // the $headers array is an array of fields to use as the colum headers.
   // additional documentation can be found here
@@ -110,26 +110,26 @@ if (count($genotypes) > 0) { ?>
   // can be found here:
   // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
   $rows = array();
-  
+
   // iterate through the genotypes and build each row of the resulting table
   foreach ($genotypes as $info) {
     $genotype         = $info['genotype'];
     $nd_experiment_id = $info['nd_experiment_id'];
-    
+
     // get the nd_experiment record
     $nd_experiment = chado_generate_var('nd_experiment', array('nd_experiment_id' => $nd_experiment_id));
-    
+
     // set some defaults for project and feature names
     $project_names = 'N/A';
     $feature_names = 'N/A';
-    
+
     // build the name for displaying the genotype. Use the uniquename by default
     // unless a name exists
     $name = $genotype->uniquename;
     if ($genotype->name){
       $name = $genotype->name;
     }
-    
+
     // build the genotype type for display
     $type = 'N/A';
     if ($genotype->type_id) {
@@ -147,7 +147,7 @@ if (count($genotypes) > 0) { ?>
       }
       $details = substr($details, 0, -4); // remove trailing <br>
     }
-    
+
     // get the features as found in the feature_genotype table and if any, add them to the $features array
     // we will later add in the features list for display
     $features = array();
@@ -173,7 +173,7 @@ if (count($genotypes) > 0) { ?>
       }
       $feature_names = substr($feature_names, 0, -4); // remove trailing <br>
     }
-      
+
     // expand the nd_experiment object to incldue the nd_experiment_project table
     $values = array('nd_experiment_id' => $nd_experiment_id);
     $options = array('return_array' => 1);
@@ -200,8 +200,8 @@ if (count($genotypes) > 0) { ?>
       $feature_names,
       $project_names,
     );
-  } 
-  
+  }
+
   // the $table array contains the headers and rows array as well as other
   // options for controlling the display of the table.  Additional
   // documentation can be found here:
@@ -220,21 +220,26 @@ if (count($genotypes) > 0) { ?>
   );
   // once we have our table array structure defined, we call Drupal's theme_table()
   // function to generate the table.
-  print theme_table($table); 
-  
+  print theme_table($table);
+
   // the $pager array values that control the behavior of the pager.  For
   // documentation on the values allows in this array see:
   // https://api.drupal.org/api/drupal/includes!pager.inc/function/theme_pager/7
   // here we add the paramter 'block' => 'features'. This is because
   // the pager is not on the default block that appears. When the user clicks a
   // page number we want the browser to re-appear with the page is loaded.
+  // We remove the 'pane' parameter from the original query parameters because
+  // Drupal won't reset the parameter if it already exists.
+  $get = $_GET;
+  unset($_GET['pane']);
   $pager = array(
     'tags' => array(),
     'element' => $stock_pager_id,
     'parameters' => array(
-      'block' => 'genotypes'
+      'pane' => 'genotypes'
     ),
     'quantity' => $num_results_per_page,
   );
   print theme_pager($pager);
+  $_GET = $get;
 }

+ 41 - 36
tripal_natural_diversity/theme/templates/tripal_stock_nd_phenotypes.tpl.php

@@ -2,14 +2,14 @@
 /*
  * Phenotype relationships with stocks are stored in the natural diversity tables.
  * If a stock has phenotypes associated then you can find the data by traversing
- * the foreign key (FK) relationships in this manner: 
- * 
+ * the foreign key (FK) relationships in this manner:
+ *
  * stock => nd_experiment_stock => nd_experiment => nd_experiment_phenotype => phenotype.
- * 
+ *
  * You can find ancillary information about data associated with a phenotype such as
- * a contact, pub, protocol, project, phenotype, dbxref by using the 
+ * a contact, pub, protocol, project, phenotype, dbxref by using the
  * nd_experiment.nd_experiment_id value and traversing the other FK relationships
- * 
+ *
  * stock => nd_experiment_stock => nd_experiment => nd_experiment_phenotype => phenotype
  *                                               => nd_experiment_phenotype => phenotype
  *                                               => nd_experiment_project => project
@@ -19,20 +19,20 @@
  *                                               => nd_experiment_protocol => protocol
  *                                               => nd_experiment_stockprop
  *                                               => nd_experiment_stock_dbxref
- * 
- * In the FK relationships shown above, the nd_experiment_id value represents a single 
- * experimental value that may have all of the ancilliary data associated with it.  
+ *
+ * In the FK relationships shown above, the nd_experiment_id value represents a single
+ * experimental value that may have all of the ancilliary data associated with it.
  * If the phenotype record shares an nd_experiment_id with a phenotype, pub, contact,
  * protocol, etc then all of that data is associated with the phenotype and vice-versa.
- * 
- * Techincally, we can skip including the 'nd_experiment' table when traversing the FK's 
+ *
+ * Techincally, we can skip including the 'nd_experiment' table when traversing the FK's
  * because we have the nd_experiment_id value when we get the nd_experiment_stock record.
- * 
+ *
  * When lots of phenotypes are associated with a stock (e.g. thousands) then traversing
  * the FK relationships as described above can be very slow. Ideally, we only need to
- * show a small subset with a pager. Therefore, a list of nd_experiment_phenotype_id's 
+ * show a small subset with a pager. Therefore, a list of nd_experiment_phenotype_id's
  * are provided to this template automatically within the stock object.
- * 
+ *
  */
 
 // get the current stock
@@ -45,7 +45,7 @@ $stock_pager_id = 10;
 
 // the nd_experiment_phenotype IDs get passed into this template, so we use
 // those to iterate and show a subset via a pager.  This is faster than trying
-// to traverse all of the FK relationship, especially when thousands of 
+// to traverse all of the FK relationship, especially when thousands of
 // associations may be present.  Because the nd_experiment_id in Chado
 // can be associated with other data types it becomes slow to use the
 // chado_expand_var functions that we would normal use.
@@ -59,11 +59,11 @@ $offset = $num_results_per_page * $current_page_num;
 
 $phenotypes = array();
 if ($total_records > 0) {
-  
+
   // iterate through the nd_experiment_phenotype_ids and get the phenotype record
   for ($i = $offset ; $i < $offset + $num_results_per_page; $i++) {
     // expand the nd_experiment record to include the nd_experiment_phenotype table
-    // there many be many phenotypes for a stock so we want to use a pager to limit 
+    // there many be many phenotypes for a stock so we want to use a pager to limit
     // the results returned
     $options = array(
       'return_array' => 1,
@@ -84,7 +84,7 @@ if ($total_records > 0) {
 if (count($phenotypes) > 0) {?>
   <div class="tripal_stock-data-block-desc tripal-data-block-desc">
     The following <?php print number_format($total_records) ?> phenotypes(s) have been recorded.
-  </div><?php 
+  </div><?php
 
   // the $headers array is an array of fields to use as the colum headers.
   // additional documentation can be found here
@@ -96,43 +96,43 @@ if (count($phenotypes) > 0) {?>
   // can be found here:
   // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
   $rows = array();
-  
-  // iterate through the nd_experiment_stock records and get 
+
+  // iterate through the nd_experiment_stock records and get
   // each experiment and the associated phenotypes
   foreach ($phenotypes as $info){
     $phenotype         = $info['phenotype'];
     $nd_experiment_id  = $info['nd_experiment_id'];
-    
+
     // get the nd_experiment record
     $nd_experiment = chado_generate_var('nd_experiment', array('nd_experiment_id' => $nd_experiment_id));
-    
+
     $details = '';
 
-    if ($phenotype->name) { 
+    if ($phenotype->name) {
       $details .= "Name: $phenotype->name<br>";
     }
-    
-    // add in the attribute type pheonotypes values are stored qualitatively or quantitatively. 
+
+    // add in the attribute type pheonotypes values are stored qualitatively or quantitatively.
     // If qualitatively the cvalue_id will link to a type. If quantitative we
     // use the value column
     $details .= ucwords(preg_replace('/_/', ' ', $phenotype->attr_id->name)) . ': ';
-    if ($phenotype->cvalue_id) { 
+    if ($phenotype->cvalue_id) {
       $details .= ucwords(preg_replace('/_/', ' ', $phenotype->cvalue_id->name)) . '<br>';
     }
-    else { 
+    else {
       $details .= $phenotype->value . '<br>';
-    }  
-    
+    }
+
     // get the observable unit and add it to the details
-    if ($phenotype->observable_id) { 
+    if ($phenotype->observable_id) {
       $details .= "Observable Unit: " . ucwords(preg_replace('/_/', ' ', $phenotype->observable_id->name)) . '<br>';
     }
-    
+
     // get the evidence unit and add it to the details
-    if ($phenotype->assay_id) { 
+    if ($phenotype->assay_id) {
       $details .= "Evidence: " .  ucwords(preg_replace('/_/', ' ', $phenotype->assay_id->name)) . '<br>';
     }
-    
+
     // Get the project for this experiment. For each nd_experiment_id there should only be one project
     // but the database does not constrain that there only be one project so just in case we get them all
     $projects = array();
@@ -153,7 +153,7 @@ if (count($phenotypes) > 0) {?>
       $pnames .= $name . '<br>';
     }
     $pnames = substr($pnames, 0, -4); // remove trailing <br>
-    
+
     $rows[] = array(
        $details,
        $pnames,
@@ -177,21 +177,26 @@ if (count($phenotypes) > 0) {?>
   );
   // once we have our table array structure defined, we call Drupal's theme_table()
   // function to generate the table.
-  print theme_table($table); 
-  
+  print theme_table($table);
+
   // the $pager array values that control the behavior of the pager.  For
   // documentation on the values allows in this array see:
   // https://api.drupal.org/api/drupal/includes!pager.inc/function/theme_pager/7
   // here we add the paramter 'block' => 'features'. This is because
   // the pager is not on the default block that appears. When the user clicks a
   // page number we want the browser to re-appear with the page is loaded.
+  // We remove the 'pane' parameter from the original query parameters because
+  // Drupal won't reset the parameter if it already exists.
+  $get = $_GET;
+  unset($_GET['pane']);
   $pager = array(
     'tags' => array(),
     'element' => $stock_pager_id,
     'parameters' => array(
-      'block' => 'genotypes'
+      'pane' => 'genotypes'
     ),
     'quantity' => $num_results_per_page,
   );
   print theme_pager($pager);
+  $_GET = $get;
 }

+ 1 - 1
tripal_natural_diversity/tripal_natural_diversity.info

@@ -3,7 +3,7 @@ description = Supports the natural diversity (ND) tables of Chado by providing p
 core = 7.x
 project = tripal
 package = Tripal
-version = 7.x-2.1-beta2
+version = 7.x-2.1
 
 dependencies[] = tripal_core
 dependencies[] = tripal_views

+ 173 - 36
tripal_organism/includes/tripal_organism.chado_node.inc

@@ -61,7 +61,7 @@ function tripal_organism_node_info() {
  *
  * @ingroup tripal_organism
  */
-function chado_organism_node_access($node, $op, $account) {
+function tripal_organism_node_access($node, $op, $account) {
   $node_type = $node;
   if (is_object($node)) {
     $node_type = $node->type;
@@ -103,66 +103,150 @@ function chado_organism_node_access($node, $op, $account) {
  */
 function chado_organism_form($node, $form_state) {
   $form = array();
-
-  // we have a file upload element on the form soe we need the multipart encoding type
+  $chado_version = chado_get_version(TRUE);
+
+  // Default values can come in the following ways:
+  //
+  // 1) As elements of the $node object.  This occurs when editing an existing
+  //    organism.
+  // 2) In the $form_state['values'] array which occurs on a failed validation
+  //    or ajax callbacks from non submit form elements
+  // 3) In the $form_state['input'[ array which occurs on ajax callbacks from
+  //    submit form elements and the form is being rebuilt
+  //
+  // Set form field defaults.
+  $organism = NULL;
+  $organism_id = NULL;
+  $abbreviation   = '';
+  $genus          = '';
+  $species        = '';
+  $common_name    = '';
+  $description    = '';
+  $infraspecific_name = '';
+  $type_id = '';
+
+  // We have a file upload element on the form soe we need the multipart
+  // encoding type
   $form['#attributes']['enctype'] = 'multipart/form-data';
 
-  // if the organism is part of the node object then we are editing. If not we are inserting
+  // If the organism is part of the node object then we are editing. If not
+  // we are inserting
   if (property_exists($node, 'organism')) {
     $organism = $node->organism;
 
-    // add in the comment since it is a text field and may not be included if too big
+    // Add in the comment since it is a text field and may not be included if
+    // too big
     $organism = chado_expand_var($organism, 'field', 'organism.comment');
 
-    // get form defaults
-    $abbreviation   = property_exists($node, 'abbreviation')   ? property_exists($node, 'abbreviation')   : $organism->abbreviation;
-    $genus          = property_exists($node, 'genus')          ? property_exists($node, 'genus')          : $organism->genus;
-    $species        = property_exists($node, 'species')        ? property_exists($node, 'species')        : $organism->species;
-    $common_name    = property_exists($node, 'common_name')    ? property_exists($node, 'common_name')    : $organism->common_name;
-    $description    = property_exists($node, 'description')    ? property_exists($node, 'description')    : $organism->comment;
-    $organism_image = property_exists($node, 'organism_image') ? property_exists($node, 'organism_image') : '';
+    // Get form defaults.
+    $abbreviation   = $organism->abbreviation;
+    $genus          = $organism->genus;
+    $species        = $organism->species;
+    $common_name    = $organism->common_name;
+    $description    = $organism->comment;
+    // The infraspecific and type_id fields are new to Chado v1.3
+    if ($chado_version > 1.2) {
+      $infraspecific_name = $organism->infraspecific_name;
+      $type_id  = $organism->type_id->cvterm_id;
+    }
 
-    // set the organism_id in the form
+    // Set the organism_id in the form.
     $form['organism_id'] = array(
       '#type' => 'value',
       '#value' => $organism->organism_id,
     );
     $organism_id = $organism->organism_id;
   }
-  else {
-    // get form defaults
-    $abbreviation   = property_exists($node, 'abbreviation')   ? property_exists($node, 'abbreviation')   : '';
-    $genus          = property_exists($node, 'genus')          ? property_exists($node, 'genus')          : '';
-    $species        = property_exists($node, 'species')        ? property_exists($node, 'species')        : '';
-    $common_name    = property_exists($node, 'common_name')    ? property_exists($node, 'common_name')    : '';
-    $description    = property_exists($node, 'description')    ? property_exists($node, 'description')    : '';
-    $organism_image = property_exists($node, 'organism_image') ? property_exists($node, 'organism_image') : '';
-
-    $organism_id = NULL;
+
+  // If we are re constructing the form from a failed validation or ajax
+  // callback then use the $form_state['values'] values.
+  if (array_key_exists('values', $form_state) and isset($form_state['values']['genus'])) {
+    $abbreviation   = $form_state['values']['abbreviation'];
+    $genus        = $form_state['values']['genus'];
+    $species = $form_state['values']['species'];
+    $common_name  = $form_state['values']['common_name'];
+    $description     = $form_state['values']['comment'];
+    if ($chado_version > 1.2) {
+      $infraspecific_name = $form_state['values']['infraspecific_name'];
+      $type_id  = $form_state['values']['type_id'];
+    }
+  }
+  // If we are re building the form from after submission (from ajax call) then
+  // the values are in the $form_state['input'] array.
+  if (array_key_exists('input', $form_state) and !empty($form_state['input'])) {
+    $abbreviation   = $form_state['input']['abbreviation'];
+    $genus        = $form_state['input']['genus'];
+    $species = $form_state['input']['species'];
+    $common_name  = $form_state['input']['common_name'];
+    $description     = $form_state['input']['comment'];
+    if ($chado_version > 1.2) {
+      $infraspecific_name = $form_state['input']['infraspecific_name'];
+      $type_id  = $form_state['input']['type_id'];
+    }
   }
 
-  $form['genus']= array(
+  $form['genus'] = array(
     '#type' => 'textfield',
     '#title' => t('Genus'),
     '#required' => TRUE,
     '#default_value' => $genus,
   );
-  $form['species']= array(
+  $form['species'] = array(
     '#type' => 'textfield',
     '#title' => t('Species'),
     '#required' => TRUE,
     '#default_value' => $species,
   );
+  // The infraspecific and type_id fields are new to Chado v1.3.
+  if ($chado_version > 1.2) {
+
+    $options = array('0' => 'Select a rank');
+    $cv = tripal_get_cv(array('name' => 'taxonomic_rank'));
+    if (!$cv) {
+      drupal_set_message('The taxonomic_rank vocabulary cannot be found, thus selects for "rank" are not available.', 'warning');
+    }
+    else {
+      $terms = tripal_get_cvterm_select_options($cv->cv_id);
+
+      // Unfortunately the taxonomic_rank vocabulary is not properly organized
+      // such that we an only include terms below 'species'. Therefore we will
+      // just list them here and hope we haven't missed one.
+      $valid_terms = array('subspecies', 'varietas', 'subvariety', 'forma', 'subforma');
+      foreach  ($terms as $cvterm_id => $name) {
+        if (in_array($name, $valid_terms)) {
+          $options[$cvterm_id] = $name;
+        }
+      }
+    }
+
+    $form['type_id']= array(
+      '#type' => 'select',
+      '#title' => t('Infraspecific Rank'),
+      '#options' => $options,
+      '#default_value' => $type_id,
+      '#description' => t('The scientific name for any taxon
+        below the rank of species. This field is used for constructing the
+        full infraspecific name for the organism.')
+    );
+
+    $form['infraspecific_name']= array(
+      '#type' => 'textfield',
+      '#title' => t('Infraspecific Name'),
+      '#default_value' => $infraspecific_name,
+      '#description'   => t("The infraspecific name for this organism. When
+          diplaying the full taxonomic name, this field is appended to the
+          genus, species and rank."),
+    );
+  }
   $form['abbreviation']= array(
     '#type' => 'textfield',
     '#title' => t('Abbreviation'),
-    '#required' => TRUE,
     '#default_value' => $abbreviation,
+    '#descriptoin' => t('A short abbreviation for this species (e.g. O.sativa)'),
   );
   $form['common_name']= array(
     '#type' => 'textfield',
     '#title' => t('Common Name'),
-    '#required' => TRUE,
     '#default_value' => $common_name,
   );
   $form['description']= array(
@@ -185,9 +269,9 @@ function chado_organism_form($node, $form_state) {
   $prop_cv = tripal_get_default_cv('organismprop', 'type_id');
   $cv_id = $prop_cv ? $prop_cv->cv_id : NULL;
   $details = array(
-    'property_table' => 'organismprop',      // the name of the prop table
-    'chado_id' => $organism_id,              // the value of organism_id for this record
-    'cv_id' => $cv_id                        // the cv.cv_id of the cv governing organismprop.type_id
+    'property_table' => 'organismprop',
+    'chado_id' => $organism_id,
+    'cv_id' => $cv_id
   );
   // Adds the form elements to your current form
   chado_add_node_form_properties($form, $form_state, $details);
@@ -195,11 +279,11 @@ function chado_organism_form($node, $form_state) {
   // ADDITIONAL DBXREFS FORM
   //---------------------------------------------
   $details = array(
-    'linking_table' => 'organism_dbxref',  // the name of the _dbxref table
-    'base_foreign_key' => 'organism_id',   // the name of the key in your base chado table
-    'base_key_value' => $organism_id       // the value of organism_id for this record
+    'linking_table' => 'organism_dbxref',
+    'base_foreign_key' => 'organism_id',
+    'base_key_value' => $organism_id
   );
-  // Adds the form elements to your current form
+  // Adds the form elements to your current form.
   chado_add_node_form_dbxrefs($form, $form_state, $details);
 
   return $form;
@@ -235,6 +319,15 @@ function chado_organism_validate($node, $form, &$form_state) {
   $node->species      = property_exists($node, 'species') ? trim($node->species) : '';
   $node->abbreviation = property_exists($node, 'abbreviation') ? trim($node->abbreviation) : '';
   $node->common_name  = property_exists($node, 'common_name') ? trim($node->common_name) : '';
+  $node->type_id  = property_exists($node, 'type_id') ? trim($node->type_id) : '';
+  $node->infraspecific_name  = property_exists($node, 'infraspecific_name') ? trim($node->infraspecific_name) : '';
+
+  if ($node->type_id and !$node->infraspecific_name) {
+    form_set_error('infraspecific_name', "If a rank is provided an infraspecific name must also be provided.");
+  }
+  if (!$node->type_id and $node->infraspecific_name) {
+    form_set_error('type_id', "Please provide a rank for the infraspecific name.");
+  }
 
   // Validating for an update
   if (property_exists($node, 'organism_id')) {
@@ -284,6 +377,7 @@ function chado_organism_validate($node, $form, &$form_state) {
  */
 function chado_organism_insert($node) {
 
+  $chado_version = chado_get_version(TRUE);
   $organism_id = '';
 
   // if there is an organism_id in the $node object then this must be a sync so
@@ -296,14 +390,27 @@ function chado_organism_insert($node) {
     $node->abbreviation = trim($node->abbreviation);
     $node->common_name  = trim($node->common_name);
     $node->description  = trim($node->description['value']);
+    if ($chado_version > 1.2) {
+      $node->type_id  = trim($node->type_id);
+      $node->infraspecific_name  = trim($node->infraspecific_name);
+    }
 
     $values = array(
       'genus'        => $node->genus,
       'species'      => $node->species,
       'abbreviation' => $node->abbreviation,
       'common_name'  => $node->common_name,
-      'comment'      => $node->description
+      'comment'      => $node->description,
     );
+    if ($chado_version > 1.2) {
+      if ($node->type_id) {
+        $values['type_id'] = $node->type_id;
+      }
+      if ($node->infraspecific_name) {
+        $values['infraspecific_name'] = $node->infraspecific_name;
+      }
+    }
+
     $organism = chado_insert_record('organism', $values);
     if (!$organism) {
       drupal_set_message(t('Unable to add organism.', 'warning'));
@@ -361,12 +468,18 @@ function chado_organism_insert($node) {
  */
 function chado_organism_update($node) {
 
+  $chado_version = chado_get_version(TRUE);
+
   // remove any white space around values
   $node->genus        = trim($node->genus);
   $node->species      = trim($node->species);
   $node->abbreviation = trim($node->abbreviation);
   $node->common_name  = trim($node->common_name);
   $node->description  = trim($node->description['value']);
+  if ($chado_version > 1.2) {
+    $node->type_id = trim($node->type_id);
+    $node->infraspecific_name = trim($node->infraspecific_name);
+  }
 
   $organism_id = chado_get_id_from_nid('organism', $node->nid);
 
@@ -384,6 +497,21 @@ function chado_organism_update($node) {
     'common_name' => $node->common_name,
     'comment' => $node->description
   );
+    if ($chado_version > 1.2) {
+      if ($node->type_id) {
+        $values['type_id'] = $node->type_id;
+      }
+      else {
+        $values['type_id'] = '__NULL__';
+      }
+      if ($node->infraspecific_name) {
+        $values['infraspecific_name'] = $node->infraspecific_name;
+      }
+      else {
+        $values['infraspecific_name'] = '__NULL__';
+      }
+    }
+
   $org_status = chado_update_record('organism', $match, $values);
   if ( $node->organism_image != '' ) {
     chado_organism_add_image($node);
@@ -538,9 +666,18 @@ function tripal_organism_node_presave($node) {
       // is being called for syncing, so we must set the title accordingly
       if (property_exists($node, 'genus')) {
         $node->title = $node->genus  . " " . $node->species;
+        if (property_exists($node, 'type_id')) {
+          $cvterm = tripal_get_cvterm(array('cvterm_id' => $node->type_id));
+          if ($cvterm) {
+            $node->title .= $cvterm->name . " " . $node->infraspecific_name;
+          }
+        }
       }
-      else if (property_exists($node, 'organism')) {
+      elseif (property_exists($node, 'organism')) {
         $node->title = $node->organism->genus . " " . $node->organism->species;
+        if (property_exists($node, 'type_id')) {
+          $node->title .= $node->organism->type_id->name . " " . $node->organism->infraspecific_name;
+        }
       }
       break;
   }

+ 53 - 17
tripal_organism/theme/templates/tripal_organism_base.tpl.php

@@ -1,4 +1,5 @@
 <?php
+$chado_version = chado_get_version(TRUE);
 
 $organism  = $variables['node']->organism;
 $organism = chado_expand_var($organism,'field','organism.comment'); ?>
@@ -7,13 +8,13 @@ $organism = chado_expand_var($organism,'field','organism.comment'); ?>
 
 // generate the image tag
 $image = '';
-$image_url = tripal_get_organism_image_url($organism); 
+$image_url = tripal_get_organism_image_url($organism);
 if ($image_url) {
   $image = "<img class=\"tripal-organism-img\" src=\"$image_url\">";
 }
 
-// the $headers array is an array of fields to use as the colum headers. 
-// additional documentation can be found here 
+// the $headers array is an array of fields to use as the colum headers.
+// additional documentation can be found here
 // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
 // This table for the organism has a vertical header (down the first column)
 // so we do not provide headers here, but specify them in the $rows array below.
@@ -22,15 +23,30 @@ $headers = array();
 // the $rows array contains an array of rows where each row is an array
 // of values for each column of the table in that row.  Additional documentation
 // can be found here:
-// https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7 
+// https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
 $rows = array();
 
+$infra = '';
+if ($chado_version > 1.2 and $organism->type_id) {
+  $infra = $organism->type_id->name . ' <i>' .  $organism->infraspecific_name . '</i>';
+}
+
+// full name row
+$rows[] = array(
+  array(
+    'data' => 'Full Name',
+    'header' => TRUE,
+    'width' => '30%',
+  ),
+  '<i>' . $organism->genus . ' ' . $organism->species . '</i> ' . $infra
+);
+
 // genus row
 $rows[] = array(
   array(
-    'data' => 'Genus', 
+    'data' => 'Genus',
     'header' => TRUE,
-    'width' => '20%',
+    'width' => '30%',
   ),
   '<i>' . $organism->genus . '</i>'
 );
@@ -38,12 +54,32 @@ $rows[] = array(
 // species row
 $rows[] = array(
   array(
-    'data' => 'Species', 
+    'data' => 'Species',
     'header' => TRUE
-  ), 
+  ),
   '<i>' . $organism->species . '</i>'
 );
 
+if ($chado_version > 1.2) {
+  $type_id = $organism->type_id ? $organism->type_id->name : '';
+  // type_id row
+  $rows[] = array(
+    array(
+      'data' => 'Infraspecific Rank',
+      'header' => TRUE
+    ),
+    $type_id
+  );
+  // infraspecific name row
+  $rows[] = array(
+    array(
+      'data' => 'Infraspecific Name',
+      'header' => TRUE
+    ),
+    '<i>' . $organism->infraspecific_name . '</i>'
+  );
+}
+
 // common name row
 $rows[] = array(
   array(
@@ -56,7 +92,7 @@ $rows[] = array(
 // abbreviation row
 $rows[] = array(
   array(
-    'data' => 'Abbreviation', 
+    'data' => 'Abbreviation',
     'header' => TRUE
   ),
   $organism->abbreviation
@@ -79,23 +115,23 @@ if (user_access('view ids')) {
 }
 
 // the $table array contains the headers and rows array as well as other
-// options for controlling the display of the table.  Additional 
+// options for controlling the display of the table.  Additional
 // documentation can be found here:
 // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
 $table = array(
-  'header' => $headers, 
-  'rows' => $rows, 
+  'header' => $headers,
+  'rows' => $rows,
   'attributes' => array(
     'id' => 'tripal_organism-table-base',
     'class' => 'tripal-organism-data-table tripal-data-table',
-  ), 
+  ),
   'sticky' => FALSE,
   'caption' => '',
-  'colgroups' => array(), 
-  'empty' => '', 
-); 
+  'colgroups' => array(),
+  'empty' => '',
+);
 
 // once we have our table array structure defined, we call Drupal's theme_table()
 // function to generate the table.
 print theme_table($table); ?>
-<div style="text-align: justify"><?php print $image . $organism->comment?></div>  
+<div style="text-align: justify"><?php print $image . $organism->comment?></div>

+ 1 - 1
tripal_organism/tripal_organism.info

@@ -3,7 +3,7 @@ description = Supports the organism tables of Chado by providing pages for viewi
 core = 7.x
 project = tripal
 package = Tripal
-version = 7.x-2.1-beta2
+version = 7.x-2.1
 configure = admin/tripal/chado/tripal_organism
 
 stylesheets[all][] = theme/css/tripal_organism.css

+ 26 - 2
tripal_organism/tripal_organism.install

@@ -27,13 +27,16 @@ function tripal_organism_disable() {
  * @ingroup tripal_organism
  */
 function tripal_organism_install() {
-  // cvs & cvterms
+  // cvs & cvterms.
   tripal_organism_add_cvs();
   tripal_organism_add_cvterms();
 
-  // set the default vocabularies
+  // set the default vocabularies.
   tripal_set_default_cv('organismprop', 'type_id', 'organism_property');
 
+  // Add taxonomic terms.
+  $obo_id = tripal_insert_obo('Taxonomic Rank', 'http://purl.obolibrary.org/obo/taxrank.obo');
+  tripal_submit_obo_job(array('obo_id' => $obo_id));
 }
 
 /**
@@ -191,6 +194,27 @@ function tripal_organism_update_7200() {
   }
 }
 
+/**
+ * Adds the taxonomic rank vocabulary.
+ */
+function tripal_organism_update_7201() {
+  try {
+    // Make sure we have the full API loaded this will help during a
+    // site upgrade when the tripal_core module is disabled.
+    module_load_include('module', 'tripal_core', 'tripal_core');
+    tripal_core_import_api();
+    module_load_include('inc', 'tripal_cv', 'api/tripal_cv.api');
+
+    // Add taxonomic terms.
+    $obo_id = tripal_insert_obo('Taxonomic Rank', 'http://purl.obolibrary.org/obo/taxrank.obo');
+    tripal_submit_obo_job(array('obo_id' => $obo_id));
+  }
+  catch (\PDOException $e) {
+    $error = $e->getMessage();
+    throw new DrupalUpdateException('Could not add taxrank ontology: '. $error);
+  }
+}
+
 /**
  * Implementation of hook_update_dependencies().
  *

+ 1 - 1
tripal_organism/tripal_organism.module

@@ -264,4 +264,4 @@ function tripal_organism_form_alter(&$form, &$form_state, $form_id) {
     //remove the body field
     unset($form['body']);
   }
-}
+}

+ 1 - 1
tripal_phenotype/tripal_phenotype.info

@@ -3,7 +3,7 @@ description = Supports the phenotype tables of Chado by providing pages for view
 core = 7.x
 project = tripal
 package = Tripal
-version = 7.x-2.1-beta2
+version = 7.x-2.1
 
 dependencies[] = tripal_core
 dependencies[] = tripal_views

+ 528 - 0
tripal_phylogeny/api/tripal_phylogeny.api.inc

@@ -0,0 +1,528 @@
+<?php
+
+/**
+ * Validates an $options array for insert or update of a phylotree record.
+ *
+ * If validation passes then any values that needed validation lookups
+ * (such as the dbxref, analysis, leaf_type, etc) will have their approriate
+ * primary_keys added to the $options array, and missing default values
+ * will also be added.
+ *
+ * @param $val_type
+ *   The type of validation. Can be either 'insert' or 'update'.
+ * @param $options
+ *   An array of key/value pairs containing any of the valid keys for
+ *   either the tripal_insert_phylotree() or tripal_update_phylotree()
+ *   functions.
+ * @param $errors
+ *   An empty array where validation error messages will be set. The keys
+ *   of the array will be name of the field from the options array and the
+ *   value is the error message.
+ * @param $warnings
+ *   An empty array where validation warning messagges will be set. The
+ *   warnings should not stop an insert or an update but should be provided
+ *   to the user as information by a drupal_set_message() if appropriate. The
+ *   keys of the array will be name of the field from the options array and the
+ *   value is the error message.
+ * @return
+ *   If validation failes then FALSE is returned.  Any options that do not pass
+ *   validation checks will be added in the $errors array with the key being
+ *   the option and the value being the error message.  If validation
+ *   is successful then TRUE is returned.
+ *
+ */
+function tripal_validate_phylotree($val_type, &$options, &$errors, &$warnings) {
+
+  if ($val_type != 'insert' and $val_type != 'update') {
+    tripal_report_error('tripal_phylogeny', TRIPAL_ERROR, "The $val_type argument must be either 'update or 'insert'.");
+  }
+
+  // Set Defaults.
+  if ($val_type == 'insert') {
+    // Match by feature name.
+    if (!array_key_exists('match', $options)) {
+      $options['match'] = 'name';
+    }
+    // The regular expression is to match the entire node name.
+    if (!array_key_exists('name_re', $options)) {
+      $options['name_re'] = '^(.*)$';
+    }
+    // A dbxref is not required by Tripal but is required by the database
+    // field in the phylotree table.  Therefore, if the dbxref is not provided
+    // we can set this to be the null database and null dbxref which
+    // is represented as 'null:local:null'
+    if (!array_key_exists('dbxref', $options)) {
+      $options['dbxref'] = "null:local:null";
+    }
+  }
+
+  // Make sure required values are set.
+  if ($val_type == 'insert') {
+    if (!array_key_exists('name', $options)) {
+      $errors['name'] = t('Please provide the name of the tree.');
+      return FALSE;
+    }
+    if (!array_key_exists('description', $options)) {
+      $errors['description'] = t('Please provide a description for this tree.');
+      return FALSE;
+    }
+    if (!array_key_exists('analysis', $options) and !array_key_exists('analysis_id', $options)) {
+      $errors['analysis'] = t('Please provide an analysis or analysis_id for this tree.');
+      return FALSE;
+    }
+    if (!array_key_exists('tree_file', $options)) {
+      $errors['tree_file'] = t('Please provide either the full path to the tree_file or a Drupal managed file ID number.');
+      return FALSE;
+    }
+    if (!array_key_exists('format', $options) or !$options['format']) {
+      $errors['format'] = t('Please provide a file format for the tree file.');
+      return FALSE;
+    }
+    // Make sure the file format is correct
+    if ($options['format'] != 'newick' and $options['format'] != 'taxonomy') {
+      $errors['format'] = t('The file format is not supported. Currently only the "newick" file format is supported.');
+      return FALSE;
+    }
+  }
+  else {
+    // Does the phylotree ID exist and is it valid
+    if (!array_key_exists('phylotree_id', $options)) {
+      $errors['phylotree_id'] = t('Please provide the ID for the tree.');
+      return FALSE;
+    }
+    $exists = chado_select_record('phylotree', array('phylotree_id'),
+        array('phylotree_id' => $options['phylotree_id']), array('has_record' => 1));
+    if (!$exists) {
+      $errors['phylotree_id'] = t('The phylotree_id does not exist.');
+      return FALSE;
+    }
+
+  }
+
+  // Make sure the file exists if one is specified
+  if (array_key_exists('tree_file', $options) and $options['tree_file']) {
+    // If this is a numeric Drupal file then all is good, no need to check.
+    if (!is_numeric($options['tree_file'])) {
+      if (!file_exists($options['tree_file'])) {
+        $errors['tree_file'] = t('The file provided does not exists.');
+        return FALSE;
+      }
+    }
+    // Make sure the file format is correct
+    if (!array_key_exists('format', $options) or
+        ($options['format'] != 'newick' and $options['format'] != 'taxonomy')) {
+      $errors['format'] = t('Please provide a supported file format. Currently only the "newick" file format is supported.');
+      return FALSE;
+    }
+
+    // If no leaf type is provided then use the polypeptide term.
+    if (!array_key_exists('leaf_type', $options) or !$options['leaf_type']) {
+      $options['leaf_type'] = 'polypeptide';
+    }
+  }
+
+  // Make sure the analysis exists.
+  $analysis = NULL;
+  if (array_key_exists('analysis_id', $options) and $options['analysis_id']) {
+    $analysis = chado_select_record('analysis', array('analysis_id'), array('analysis_id' => $options['analysis_id']));
+    if (!$analysis) {
+      $errors['analysis_id'] = t('The analysis name provided does not exist.');
+      return FALSE;
+    }
+    $options['analysis_id'] = $analysis[0]->analysis_id;
+  }
+  if (array_key_exists('analysis', $options) and $options['analysis']) {
+    $analysis = chado_select_record('analysis', array('analysis_id'), array('name' => $options['analysis']));
+    if (!$analysis) {
+      $errors['analysis'] = t('The analysis ID provided does not exist.');
+      return FALSE;
+    }
+    $options['analysis_id'] = $analysis[0]->analysis_id;
+  }
+
+  // Make sure the leaf type exists.
+  $type = NULL;
+  if (array_key_exists('leaf_type', $options) and $options['leaf_type']) {
+    if ($options['leaf_type'] == 'taxonomy') {
+      $values = array(
+        'cv_id' => array(
+           'name' => 'tripal_phylogeny'
+        ),
+        'name' => 'taxonomy'
+      );
+      $type = chado_select_record('cvterm', array('cvterm_id'), $values);
+    }
+    else {
+      $values = array(
+        'cv_id' => array(
+           'name' => 'sequence'
+        ),
+        'name' => $options['leaf_type']
+      );
+      $type = chado_select_record('cvterm', array('cvterm_id'), $values);
+      if (!$type) {
+        $errors['leaf_type'] = t('The leaf_type provided is not a valid Sequence Ontology term: %term.');
+        return FALSE;
+      }
+    }
+    $options['type_id'] = $type[0]->cvterm_id;
+  }
+
+  // A Dbxref is required by the phylotree module, but if the
+  // tree was generated in-house and the site admin doens't want to
+  // assign a local dbxref then we will set it to the null db
+  // and the local:null dbxref.
+  if (array_key_exists('dbxref', $options)) {
+    if (!$options['dbxref']) {
+        $options['dbxref'] = 'null:local:null';
+    }
+    $matches = array();
+    preg_match('/^(.*?):(.*)$/', $options['dbxref'], $matches);
+    $db_name = $matches[1];
+    $accession = $matches[2];
+    $values = array(
+      'accession' => $accession,
+      'db_id' => array(
+        'name' => $db_name
+      ),
+    );
+    $dbxref = chado_generate_var('dbxref', $values);
+    if (!$dbxref) {
+      $errors['dbxref'] = t('The dbxref provided does not exist in the database: %dbxref.', array('%dbxref' => $dbxref));
+      return FALSE;
+    }
+    $options['dbxref_id'] = $dbxref->dbxref_id;
+  }
+
+  // Make sure the tree name is unique
+  if (array_key_exists('name', $options) and $options['name']) {
+    $sql = "
+      SELECT *
+      FROM {phylotree} P
+      WHERE
+        P.name = :name
+    ";
+    $args = array(':name' => $options['name']);
+    if ($val_type == 'update') {
+      $sql .= " AND NOT P.phylotree_id = :phylotree_id";
+      $args[':phylotree_id'] = $options['phylotree_id'];
+    }
+    $result = chado_query($sql, $args)->fetchObject();
+    if ($result) {
+      $errors['name'] = t("The tree name is in use by another tree. Please provide a different unique name for this tree.");
+    }
+  }
+
+  return TRUE;
+}
+/**
+ * Inserts a phylotree record into Chado.
+ *
+ * This function validates the options passed prior to insertion of the record,
+ * and if validation passes then any values in the options array that needed
+ * validation lookups (such as the dbxref, analysis, leaf_type, etc) will have
+ * their approriate primary key values added to the options array.
+ *
+ * @param $options
+ *  An array of key value pairs with the following keys required:
+ *     'name':       The name of the tree. This will be displayed to users.
+ *     'description: A description about the tree
+ *     'anlaysis_id: The ID of the analysis to which this phylotree should be
+ *                   associated.
+ *     'analysis':   If the analysis_id key is not used then the analysis name
+ *                   may be provided to identify the analysis to which the tree
+ *                   should be associated.
+ *     'leaf_type':  A sequence ontology term or the word 'organism'. If the
+ *                   type is 'organism' then this tree represents a
+ *                   taxonomic tree.  The default, if not specified, is the
+ *                   term 'polypeptide'.
+ *     'tree_file':  The path of the file containing the phylogenetic tree to
+ *                   import or a Drupal managed_file numeric ID.
+ *     'format':     The file format. Currently only 'newick is supported'
+ *  Optional keys:
+ *     'dbxref':     A database cross-reference of the form DB:ACCESSION.
+ *                   Where DB is the database name, which is already present
+ *                   in Chado, and ACCESSION is the unique identifier for
+ *                   this tree in the remote database.
+ *     'name_re':    If the leaf type is NOT 'taxonomy', then the value of
+ *                   this field can be a regular expression to pull out
+ *                   the name of the feature from the node label in the
+ *                   intput tree. If no value is provided the entire label is
+ *                   used.
+ *     'match':      Set to 'uniquename' if the leaf nodes should be matched
+ *                   with the feature uniquename.
+ *     'load_now':   If set, the tree will be loaded immediately if a tree_file
+ *                   is provided. Otherwise, the tree will be loaded via
+ *                   a Tripal jobs call.
+ *     'no_load':    If set the tree file will not be loaded.
+ * @param $errors
+ *   An empty array where validation error messages will be set. The keys
+ *   of the array will be name of the field from the options array and the
+ *   value is the error message.
+ * @param $warnings
+ *   An empty array where validation warning messagges will be set. The
+ *   warnings should not stop an insert or an update but should be provided
+ *   to the user as information by a drupal_set_message() if appropriate. The
+ *   keys of the array will be name of the field from the options array and the
+ *   value is the error message.
+ * @return
+ *   TRUE for success and FALSE for failure.
+ */
+function tripal_insert_phylotree(&$options, &$errors, &$warnings) {
+  global $user;
+
+  $options['name_re'] = trim($options['name_re']);
+  $options['leaf_type'] = trim($options['leaf_type']);
+  $options['name'] = trim($options['name']);
+  $options['format'] = trim($options['format']);
+  $options['tree_file'] = trim($options['tree_file']);
+
+  // Validate the incoming options.
+  $success = tripal_validate_phylotree('insert', $options, $errors, $warnings);
+  if (!$success) {
+    foreach ($errors as $field => $message) {
+      tripal_report_error('tripal_phylogeny', TRIPAL_ERROR, $message);
+    }
+    return FALSE;
+  }
+
+  // If we're here then all is good, so add the phylotree record.
+  $values = array(
+    'analysis_id' => $options['analysis_id'],
+    'name' => $options['name'],
+    'dbxref_id' => $options['dbxref_id'],
+    'comment' => $options['description'],
+    'type_id' => $options['type_id'],
+  );
+  $phylotree = chado_insert_record('phylotree', $values);
+  if (!$phylotree) {
+    drupal_set_message(t('Unable to add phylotree.'), 'warning');
+    tripal_report_error('tripal_phylogeny', TRIPAL_WARNING, 'Insert phylotree: Unable to create phylotree where values: %values',
+        array('%values' => print_r($values, TRUE)));
+    return FALSE;
+  }
+  $phylotree_id = $phylotree['phylotree_id'];
+  $options['phylotree_id'] = $phylotree_id;
+
+  // If the tree_file is numeric then it is a Drupal managed file and
+  // we want to make the file permanent and associated with the tree.
+  if (is_numeric($options['tree_file'])) {
+    $file = NULL;
+    $file = file_load($options['tree_file']);
+    $file->status = FILE_STATUS_PERMANENT;
+    $file = file_save($file);
+    file_usage_add($file, 'tripal_phylogeny', $options['format'], $phylotree_id);
+    $real_file_path = drupal_realpath($file->uri);
+  }
+  else {
+    $real_file_path = $options['tree_file'];
+  }
+
+  // If caller has requested to load the file now then do so, otherwise
+  // submit using a Tripal job.
+  if (!array_key_exists('no_load', $options) or !$options['no_load']) {
+    if (array_key_exists('load_now', $options) and $options['load_now']) {
+      $args = array(
+        'phylotree_id' => $phylotree_id,
+        'leaf_type' => $options['leaf_type'],
+        'match' => $options['match'] ? 'uniquename' : 'name',
+        'name_re' => $options['name_re'],
+      );
+      tripal_phylogeny_import_tree_file($real_file_path, $options['format'], $args);
+    }
+    else {
+      $args = array(
+          $real_file_path,
+          'newick',
+          array(
+            'phylotree_id' => $phylotree_id,
+            'leaf_type' => $options['leaf_type'],
+            'match' => $options['match'] ? 'uniquename' : 'name',
+            'name_re' => $options['name_re'],
+          ),
+      );
+      if (tripal_add_job("Import Tree File: " . $file->filename, 'tripal_phylogeny',
+          'tripal_phylogeny_import_tree_file', $args, $user->uid)) {
+          drupal_set_message(t('The tree visualizations will appear once the tree is fully imported.'));
+      }
+    }
+  }
+
+  return TRUE;
+}
+
+/**
+ * Updates a phylotree record into Chado.
+ *
+ * This function validates the options passed prior to update of the record
+ * and if validation passes then any values in the options array that needed
+ * validation lookups (such as the dbxref, analysis, leaf_type, etc) will have
+ * their approriate primary key values added to the options array. A Drupal
+ * File object will be added to the options array for the tree file if one
+ * is provided.
+ *
+ *
+ * @param $phylotree_id
+ *   The ID of the phylotree to update.
+ * @param $options
+ *  An array of key value pairs with the following optional keys:
+ *     'name':       The name of the tree. This will be displayed to users.
+ *     'description: A description about the tree
+ *     'anlaysis_id: The ID of the analysis to which this phylotree should be
+ *                   associated.
+ *     'analysis':   If the analysis_id key is not used then the analysis name
+ *                   may be provided to identify the analysis to which the tree
+ *                   should be associated.
+ *     'leaf_type':  A sequence ontology term or the word 'organism'. If the
+ *                   type is 'organism' then this tree represents a
+ *                   taxonomic tree.  The default, if not specified, is the
+ *                   term 'polypeptide'.
+ *     'tree_file':  The path of the file containing the phylogenetic tree to
+ *                   import or a Drupal managed_file numeric ID.
+ *     'format':     The file format. Currently only 'newick is supported'
+ *     'dbxref':     A database cross-reference of the form DB:ACCESSION.
+ *                   Where DB is the database name, which is already present
+ *                   in Chado, and ACCESSION is the unique identifier for
+ *                   this tree in the remote database.
+ *     'name_re':    If the leaf type is NOT 'taxonomy', then the value of
+ *                   this field can be a regular expression to pull out
+ *                   the name of the feature from the node label in the
+ *                   intput tree. If no value is provided the entire label is
+ *                   used.
+ *     'match':      Set to 'uniquename' if the leaf nodes should be matched
+ *                   with the feature uniquename.
+ *     'load_now':   If set, the tree will be loaded immediately if a tree_file
+ *                   is provided. Otherwise, the tree will be loaded via
+ *                   a Tripal jobs call.
+ */
+function tripal_update_phylotree($phylotree_id, &$options) {
+  global $user;
+
+  // Validate the incoming options.
+  $errors = array();
+  $warnings = array();
+  $success = tripal_validate_phylotree('update', $options, $errors, $warnings);
+  if (!$success) {
+    foreach ($errors as $field => $message) {
+      tripal_report_error('tripal_phylogeny', TRIPAL_ERROR, $message);
+    }
+    return FALSE;
+  }
+
+  // If we're here then all is good, so update the phylotree record.
+  $match = array(
+      'phylotree_id' => $phylotree_id,
+  );
+  if (array_key_exists('name', $options) and $options['name']) {
+    $values['name'] = $options['name'];
+  }
+  if (array_key_exists('analysis_id', $options) and $options['analysis_id']) {
+    $values['analysis_id'] = $options['analysis_id'];
+  }
+  if (array_key_exists('dbxref_id', $options) and $options['dbxref_id']) {
+    $values['dbxref_id'] = $options['dbxref_id'];
+  }
+  if (array_key_exists('description', $options) and $options['description']) {
+    $values['comment'] = $options['description'];
+  }
+  if (array_key_exists('type_id', $options) and $options['type_id']) {
+    $values['type_id'] = $options['type_id'];
+  }
+
+  $phylotree = chado_update_record('phylotree', $match, $values, array('return_record' => TRUE));
+  if (!$phylotree) {
+    drupal_set_message(t('Unable to update phylotree.'), 'warning');
+    tripal_report_error('tripal_phylogeny', TRIPAL_WARNING,
+        'Update phylotree: Unable to update phylotree where values: %values',
+        array('%values' => print_r($values, TRUE))
+    );
+  }
+
+  // If we have a tree file, then import the tree
+  if (array_key_exists('tree_file', $options) and $options['tree_file']) {
+
+    // Remove any existing nodes
+    chado_delete_record('phylonode', array('phylotree_id' => $options['phylotree_id']));
+
+    // Make sure if we already have a file that we remove the old one.
+    $sql = "
+      SELECT FM.fid
+      FROM {file_managed} FM
+        INNER JOIN {file_usage} FU on FM.fid = FU.fid
+      WHERE FU.id = :id and FU.module = 'tripal_phylogeny'
+    ";
+    $fid = db_query($sql, array(':id' => $options['phylotree_id']))->fetchField();
+    if ($fid) {
+      $file = file_load($fid);
+      file_delete($file, TRUE);
+    }
+
+    // If the tree_file is numeric then it is a Drupal managed file and
+    // we want to make the file permanent and associated with the tree.
+    if (is_numeric($options['tree_file'])) {
+      $file = file_load($options['tree_file']);
+      $file->status = FILE_STATUS_PERMANENT;
+      $file = file_save($file);
+      file_usage_add($file, 'tripal_phylogeny', 'newick', $options['phylotree_id']);
+
+      // Add a job to parse the new node tree.
+      $real_file_path = drupal_realpath($file->uri);
+    }
+    else {
+      $real_file_path = $options['tree_file'];
+    }
+
+    // If caller has requested to load the file now then do so, otherwise
+    // submit using a Tripal job.
+    if (array_key_exists('load_now', $options) and $options['load_now']) {
+      $args = array(
+        'phylotree_id' => $options['phylotree_id'],
+        'leaf_type' => $options['leaf_type'],
+        'match' => $options['match'] ? 'uniquename' : 'name',
+        'name_re' => $options['name_re'],
+      );
+      tripal_phylogeny_import_tree_file($real_file_path, $options['format'], $args);
+    }
+    else {
+      $args = array(
+        $real_file_path,
+        'newick',
+        array(
+          'phylotree_id' => $options['phylotree_id'],
+          'leaf_type' => $options['leaf_type'],
+          'match' => $options['match'] ? 'uniquename' : 'name',
+          'name_re' => $options['name_re'],
+        ),
+      );
+      if (tripal_add_job("Import Tree File: " . $file->filename, 'tripal_phylogeny',
+          'tripal_phylogeny_import_tree_file', $args, $user->uid)) {
+        drupal_set_message(t('The tree visualizations will appear once the tree is fully imported.'));
+      }
+    }
+  }
+
+  return TRUE;
+}
+
+/**
+ * Deletes a phylotree record from Chado.
+ *
+ * @param $phylotree_id
+ *
+ * @return
+ *   TRUE on success, FALSE on failure.
+ */
+function tripal_delete_phylotree($phylotree_id) {
+
+  // if we don't have a phylotree id for this node then this isn't a node of
+  // type chado_phylotree or the entry in the chado_phylotree table was lost.
+  if (!$phylotree_id) {
+    tripal_report_error('tripal_phylogeny', TRIPAL_ERROR,
+        'Please provide a phylotree_id to delete a tree.');
+    return FALSE;
+  }
+
+  // Remove the tree
+  $values = array('phylotree_id' => $phylotree_id);
+  return chado_delete_record('phylotree', $values);
+}

+ 331 - 0
tripal_phylogeny/includes/parsers/tripal_phylogeny.newick_parser.inc

@@ -0,0 +1,331 @@
+<?php
+
+/**
+ * This code parses the grammer for the Newick format as per the following
+ * grammar:
+ * 
+ *  Tree --> Subtree ";" | Branch ";"
+ *  Subtree --> Leaf | Internal
+ *  Leaf --> Name
+ *  Internal --> "(" BranchSet ")" Name
+ *  BranchSet --> Branch | BranchSet "," Branch
+ *  Branch --> Subtree Length
+ *  Name --> empty | string
+ *  Length --> empty | ":" number
+ * 
+ */
+
+/**
+ * 
+ * @param unknown $file_name
+ */
+function tripal_phylogeny_parse_newick_file($file_name) {
+  
+  // Initialize the bootstrap value and index
+  global $tripal_phylogeny_bootstrap;
+  
+  $tripal_phylogeny_bootstrap = 1;
+  $tripal_phylogeny_index = 1;
+  
+  $tree = array();
+  
+  $fp = fopen($file_name, 'r');
+  if ($fp) {
+    $tree = tripal_phylogeny_parse_newick_tree($fp);
+  }
+  else {
+    // ERROR
+  }
+  return $tree;
+}
+/**
+ * 
+ * @param unknown $fp
+ * @param number $depth
+ * @return boolean
+ */
+function tripal_phylogeny_parse_newick_tree($fp, $depth = 0) {
+  
+  $subtree = tripal_phylogeny_parse_newick_subtree($fp, $depth);
+  $subtree['is_root'] = 1;
+
+  // this subtree may also be a branch. A branch is a subtree with a length,
+  // so see if there is a length
+  $token = tripal_phylogeny_parse_newick_get_token($fp);
+  if ($token == ";") {
+    // we're done!
+    return $subtree;
+  }
+  tripal_phylogeny_parse_newick_replace_token($fp);
+  
+  // Get the length.
+  $length = tripal_phylogeny_parse_newick_length($fp, $depth);
+  $subtree['length'] = $length;
+  
+  // Now if we're missing the semicolon we have a syntax error.
+  $token = tripal_phylogeny_parse_newick_get_token($fp);
+  if ($token != ';') {
+    print "Syntax Error: missing trailing semicolon.\n";
+    exit;
+  }
+ 
+  return $subtree;
+}
+
+/**
+ * 
+ * @param unknown $fp
+ * @param unknown $depth
+ * @return Ambigous|unknown
+ */
+function tripal_phylogeny_parse_newick_subtree($fp, $depth) {
+  
+  $internal = tripal_phylogeny_parse_newick_internal($fp, $depth + 1);
+  if (!is_array($internal)) {
+    $leaf_node = tripal_phylogeny_parse_newick_leaf($fp, $depth);
+    return array(
+      'name' => $leaf_node,
+      'depth' => $depth,
+      'is_leaf' => TRUE,
+      'descendents' => 0,
+    );
+  }
+  else {
+    $internal['depth'] = $depth;
+  }
+  return $internal;
+}
+
+/**
+ * 
+ * @param unknown $fp
+ * @param unknown $depth
+ * @return boolean|multitype:unknown Ambigous <Ambigous, unknown>
+ */
+function tripal_phylogeny_parse_newick_branch($fp, $depth) {
+
+  $subtree = tripal_phylogeny_parse_newick_subtree($fp, $depth);
+  $length = tripal_phylogeny_parse_newick_length($fp, $depth);
+
+  $subtree['length'] = $length;
+  return $subtree;
+}
+/**
+ * 
+ * @param unknown $fp
+ * @param unknown $parent
+ * @param unknown $depth
+ */
+function tripal_phylogeny_parse_newick_internal($fp, $depth) {
+
+  // If the next character is not an open paren then this is an internal node
+  if (tripal_phylogeny_parse_newick_get_token($fp) != '(') {
+    tripal_phylogeny_parse_newick_replace_token($fp);
+    return FALSE;
+  }
+  
+  $branches = tripal_phylogeny_parse_newick_branchset($fp, $depth);
+  if (!is_array($branches)) {
+    return FALSE;
+  }
+  // If we don't have a closing parent then this is a syntax error.
+  if (tripal_phylogeny_parse_newick_get_token($fp) != ')') {
+    tripal_phylogeny_parse_newick_replace_token($fp);
+    return FALSE;
+  }
+  $internal_node = tripal_phylogeny_parse_newick_name($fp, $depth);
+  $descendent_count = 0;
+  for ($i = 0; $i < count($branches); $i++) {
+    $branches[$i]['parent'] = $internal_node;
+    $descendent_count += 1 + $branches[$i]['descendents'];
+  }
+
+  return array(
+    'name' => $internal_node,
+    'depth' => $depth,
+    'branch_set' => $branches,
+    'is_internal' => TRUE,
+    'descendents' => $descendent_count,
+  );
+}
+
+/**
+ * 
+ * @param unknown $fp
+ * @param unknown $parent
+ * @param unknown $depth
+ */
+function tripal_phylogeny_parse_newick_branchset($fp, $depth) {
+  $branches = array();
+  
+  $num_read = 0;
+  $branch = tripal_phylogeny_parse_newick_branch($fp, $depth);
+  $branches[] = $branch;
+
+  // If it's not a branch then return false, a branchset will
+  // always appear as a branch.
+  if (!is_array($branch)) {
+    return FALSE;
+  }
+
+  // If we have a comma as the next token then this is
+  // a branchset and we should recurse. 
+  $token = tripal_phylogeny_parse_newick_get_token($fp);
+  if ($token == ',') {
+    $rbranches = tripal_phylogeny_parse_newick_branchset($fp, $depth);
+    foreach ($rbranches as $branch) {
+      $branches[] = $branch;
+    }
+  }
+  else {
+    tripal_phylogeny_parse_newick_replace_token($fp);
+  }
+
+  return $branches;
+}
+/**
+ * 
+ * @param unknown $fp
+ * @param unknown $depth
+ * @return Ambigous <string, boolean, unknown>
+ */
+function tripal_phylogeny_parse_newick_leaf($fp, $depth) {
+  return tripal_phylogeny_parse_newick_name($fp, $depth);
+}
+/**
+ * 
+ * @param unknown $fp
+ * @param unknown $depth
+ * @return string|boolean|Ambigous <string, unknown>
+ */
+function tripal_phylogeny_parse_newick_name($fp, $depth) {
+  global $tripal_phylogeny_bootstrap;
+
+  $token = tripal_phylogeny_parse_newick_get_token($fp);
+  
+  // If the next token is a colon, semicolon, close paren, or comma 
+  // then the name is empty.
+  if ($token == ':' or $token == ',' or $token == ';' or $token == ')') {
+    tripal_phylogeny_parse_newick_replace_token($fp);
+    // create a bootstrap value
+    return $tripal_phylogeny_bootstrap++;
+  }
+  
+  // If the next token is an open paren then this is a syntax error:
+  if ($token == '(') {
+    tripal_phylogeny_parse_newick_replace_token($fp);
+    return FALSE;
+  }
+  return $token;
+}
+/**
+ * 
+ * @param unknown $fp
+ * @param unknown $depth
+ * @return string|boolean|unknown
+ */
+function tripal_phylogeny_parse_newick_length($fp, $depth) {
+  $length  = '';
+
+  $token = tripal_phylogeny_parse_newick_get_token($fp);
+  
+  // If the next token is a semicolon, close paren, or comma
+  // then the length is empty.
+  if ($token == ',' or $token == ';' or $token == ')') {
+    tripal_phylogeny_parse_newick_replace_token($fp);
+    return '';
+  }
+
+  // If the next token is a colon then we are parsing the length. 
+  // Otherwise we are not.
+  if ($token != ':') {
+    tripal_phylogeny_parse_newick_replace_token($fp);
+    return FALSE;
+  }
+  
+  // Now get the length.
+  $token = tripal_phylogeny_parse_newick_get_token($fp);
+
+  // If the next token is an open paren then this is a syntax error:
+  if ($token == '(') {
+    exit();
+  }
+
+  return $token;
+}
+
+/**
+ * 
+ * @param unknown $fp
+ * @return string
+ */
+function tripal_phylogeny_parse_newick_get_token($fp) {
+  
+  // Keep track of the file position that we start with
+  global $tripal_phylogeny_fp_pos;
+  $tripal_phylogeny_fp_pos = ftell($fp);
+  
+  $token = '';
+  $in_quote = FALSE;
+  $num_read = 0;
+  
+  $c = fgetc($fp);
+  while (!feof($fp)) {
+    $num_read++;
+
+    switch ($c) {
+      // If the first character is a reserved character and we
+      // we have not encountered any other charcters then return
+      // it as the token. Otherwise, return the collected token.
+      case ';':
+      case '(':
+      case ')':
+      case ',':
+      case ':':
+        if (!$token) {
+          return $c;
+        }
+        else {
+          // put the character back and return the token
+          fseek($fp, $tripal_phylogeny_fp_pos + $num_read - 1);
+          return $token;
+        }
+        
+        break;
+      // Quotes are allowed around names and if a name is in
+      // quotes then allow spaces. Otherwise, spaces are ignored.
+      case '\'':
+      case '"':
+        if (!$in_quote) {
+          $in_quote = TRUE;
+        }
+        else {
+          $in_quote = FALSE;
+        }
+        break;
+      case " ":
+      case "\t":
+      case "\r":
+      case "\n":
+        if ($in_quote) {
+          $token .= $c;
+        }
+        break;
+      // All other characters get saved as the token
+      default:
+        $token .= $c;
+    }
+    $c = fgetc($fp);
+  }
+  return $token;
+}
+/**
+ * 
+ * @param unknown $fp
+ */
+function tripal_phylogeny_parse_newick_replace_token($fp) {
+  global $tripal_phylogeny_fp_pos;
+  
+  fseek($fp, $tripal_phylogeny_fp_pos);
+  $tripal_phylogeny_fp_pos = ftell($fp);
+}

+ 320 - 0
tripal_phylogeny/includes/tripal_phylogeny.admin.inc

@@ -0,0 +1,320 @@
+<?php
+/**
+ * @file
+ * This file contains the functions used for administration of the module
+ *
+ */
+
+function tripal_phylogeny_admin_phylotrees_listing() {
+  $output = '';
+
+  // set the breadcrumb
+  $breadcrumb = array();
+  $breadcrumb[] = l('Home', '<front>');
+  $breadcrumb[] = l('Administration', 'admin');
+  $breadcrumb[] = l('Tripal', 'admin/tripal');
+  $breadcrumb[] = l('Chado', 'admin/tripal/chado');
+  $breadcrumb[] = l('Phylotrees', 'admin/tripal/extension/tripal_phylogeny');
+  drupal_set_breadcrumb($breadcrumb);
+
+  // Add the view
+  $view = views_embed_view('tripal_phylogeny_admin_phylotree','default');
+  if (isset($view)) {
+    $output .= $view;
+  }
+  else {
+    $output .= '<p>The Phylotree module uses primarily views to provide an '
+      . 'administrative interface. Currently one or more views needed for this '
+      . 'administrative interface are disabled. <strong>Click each of the following links to '
+      . 'enable the pertinent views</strong>:</p>';
+    $output .= '<ul>';
+      $output .= '<li>'.l('Phylotree View', 'admin/tripal/extension/tripal_phylogeny/views/phylotree/enable').'</li>';
+    $output .= '</ul>';
+  }
+  return $output;
+}
+
+/**
+ * Administrative settings form
+ *
+ * @ingroup tripal_phylogeny
+ */
+function tripal_phylogeny_admin() {
+  $form = array();
+
+
+  // PHYLOTREE NODE TITLES
+  // If your module is using the Chado Node: Title & Path API to allow
+  // custom titles for your node type then you need to add the
+  // configuration form for this functionality.
+  $details = array(
+    'module' => 'tripal_phylogeny',
+    'content_type' => 'chado_phylotree',
+    // An array of options to use under "Page Titles"
+    // the key should be the token and the value should be the human-readable option
+    'options' => array(
+      '[phylotree.name]' => 'Tree Name Only',
+      // there should always be one options matching the unique constraint.
+      '[phylotree.phylotree_id]' => 'The Chado ID for Phylotrees'
+    ),
+    // the token indicating the unique constraint in the options array
+    'unique_option' => '[phylotree.phylotree_id]'
+  );
+
+  // This call adds the configuration form to your current form
+  // This sub-form handles it's own validation & submit
+  chado_add_admin_form_set_title($form, $form_state, $details);
+
+
+  // PHYLOTREE NODE URL
+  // Using the Chado Node: Title & Path API
+  $details = array(
+    'module' => 'tripal_phylogeny',
+    'content_type' => 'chado_phylotree',
+    // An array of options to use under "Page URL"
+    // the key should be the token and the value should be the human-readable option
+    'options' => array(
+      '/tree/[phylotree.name]' => 'Tree Name Only',
+      // there should always be one options matching the unique constraint.
+      '/tree/[phylotree.phylotree_id]' => 'The Chado ID for Phylotrees',
+    )
+  );
+  // This call adds the configuration form to your current form
+  // This sub-form handles it's own validation & submit
+  chado_add_admin_form_set_url($form, $form_state, $details);
+
+  return system_settings_form($form);
+
+}
+
+/**
+ *
+ * @param unknown $form
+ * @param unknown $form_state
+ */
+function tripal_phylogeny_default_plots_form($form, &$form_state) {
+  $form = array();
+
+  $form['plot_settings'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Plot Settings'),
+    '#description' => t('You can customize settings for each plot'),
+    '#collapsible' => TRUE,
+    '#collapsed' => FALSE
+  );
+
+  $form['plot_settings']['phylogram_width'] = array(
+    '#type' => 'textfield',
+    '#title' => 'Tree Width',
+    '#description' => 'Please specify the width in pixels for the phylogram',
+    '#default_value' => variable_get('tripal_phylogeny_default_phylogram_width', 350),
+    '#element_validate' => array(
+      'element_validate_integer_positive'
+    ),
+    '#size' => 5,
+  );
+
+  $form['node_settings'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Node Settings'),
+    '#description' => t('You can customize settings for the nodes on the trees.'),
+    '#collapsible' => TRUE,
+    '#collapsed' => FALSE
+  );
+  $form['node_settings']['root_node_size'] = array(
+    '#type' => 'textfield',
+    '#title' => 'Root Node Size',
+    '#description' => 'Please specify a size for the root node size. If set to zero, the node will not appear.',
+    '#default_value' => variable_get('tripal_phylogeny_default_root_node_size', 3),
+    '#element_validate' => array(
+      'element_validate_integer'
+    ),
+    '#size' => 3,
+  );
+  $form['node_settings']['interior_node_size'] = array(
+    '#type' => 'textfield',
+    '#title' => 'Interor Node Size',
+    '#description' => 'Please specify a size for the interior node size. If set to zero, the node will not appear.',
+    '#default_value' => variable_get('tripal_phylogeny_default_interior_node_size', 0),
+    '#element_validate' => array(
+      'element_validate_integer'
+    ),
+    '#size' => 3,
+  );
+  $form['node_settings']['leaf_node_size'] = array(
+    '#type' => 'textfield',
+    '#title' => 'Leaf Node Size',
+    '#description' => 'Please specify a size for the leaf node size. If set to zero, the node will not appear.',
+    '#default_value' => variable_get('tripal_phylogeny_default_leaf_node_size', 6),
+    '#element_validate' => array(
+      'element_validate_integer'
+    ),
+    '#size' => 3,
+  );
+
+  // Get the number of organism colors that already exist. If the site admin
+  // has set colors then those settings will be in a Drupal variable which we
+  // will retrieve.  Otherwise the num_orgs defaults to 1 and a single
+  // set of fields is provided.
+  $num_orgs = variable_get("tripal_phylogeny_num_orgs", 1);
+  if (array_key_exists('values', $form_state) and array_key_exists('num_orgs', $form_state['values'])) {
+    $num_orgs = $form_state['values']['num_orgs'];
+  }
+  // The default values for each organism color are provided in a d
+  // Drupal variable that gets set when the form is set.
+  $color_defaults = variable_get("tripal_phylogeny_org_colors", array('1' => array('organism' => '', 'color' => '')));
+
+  $form['node_settings']['desc'] = array(
+    '#type' => 'item',
+    '#title' => t('Node Colors by Organism'),
+    '#markup' => t('If the trees are associated with features (e.g. proteins)
+      then the nodes can be color-coded by their organism.  This helps the user
+      visualize which nodes belong to each organism.  Please enter the
+      name of the organism and it\'s corresponding color in HEX code (e.g. #FF0000 == red).
+      Organisms that are not given a color will be gray.'),
+  );
+  $form['node_settings']['org_table']['num_orgs'] = array(
+    '#type' => 'value',
+    '#value' => $num_orgs,
+  );
+
+  // Iterate through the number of organism colors and add a field for each one.
+  for ($i = 0; $i < $num_orgs; $i++) {
+    $form['node_settings']['org_table']['organism_' . $i] = array(
+      '#type' => 'textfield',
+      '#default_value' => array_key_exists($i, $color_defaults) ? $color_defaults[$i]['organism'] : '',
+      '#autocomplete_path' => "admin/tripal/chado/tripal_organism/organism/auto_name",
+      '#description' => t('Please enter the name of the organism.'),
+      '#size' => 30,
+    );
+    $form['node_settings']['org_table']['color_' . $i] = array(
+      '#type' => 'textfield',
+      '#description' => t('Please provide a color in Hex format (e.g. #FF0000).'),
+      '#default_value' => array_key_exists($i, $color_defaults) ? $color_defaults[$i]['color'] : '',
+      '#suffix' => "<div id=\"color-box-$i\" style=\"width: 30px;\"></div>",
+      '#size' => 10,
+    );
+  }
+  $form['node_settings']['org_table']['add'] = array(
+    '#type' => 'submit',
+    '#name' => 'add',
+    '#value' => 'Add',
+    '#ajax' => array(
+      'callback' => "tripal_phylogeny_default_plots_form_ajax_callback",
+      'wrapper'  => 'tripal_phylogeny_default_plots_form',
+      'effect'   => 'fade',
+      'method'   => 'replace',
+    ),
+  );
+  $form['node_settings']['org_table']['remove'] = array(
+    '#type' => 'submit',
+    '#name' => 'remove',
+    '#value' => 'Remove',
+    '#ajax' => array(
+      'callback' => "tripal_phylogeny_default_plots_form_ajax_callback",
+      'wrapper'  => 'tripal_phylogeny_default_plots_form',
+      'effect'   => 'fade',
+      'method'   => 'replace',
+    ),
+  );
+  $form['node_settings']['org_table']['#theme'] = 'tripal_phylogeny_admin_org_color_tables';
+  $form['node_settings']['org_table']['#prefix'] = '<div id="tripal_phylogeny_default_plots_form">';
+  $form['node_settings']['org_table']['#suffix'] = '</div>';
+
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#name' => 'submit',
+    '#value' => 'Save Configuration',
+  );
+
+  $form['#submit'][] = 'tripal_phylogeny_default_plots_form_submit';
+
+  return $form;
+}
+
+/**
+ * Validate the phylotree settings forms
+ *
+ * @ingroup tripal_phylogeny
+ */
+function tripal_phylogeny_default_plots_form_validate($form, &$form_state) {
+
+}
+/**
+ *
+ * @param unknown $form
+ * @param unknown $form_state
+ */
+function tripal_phylogeny_default_plots_form_submit($form, &$form_state) {
+  // Rebuild this form after submission so that any changes are reflected in
+  // the flat tables.
+  $form_state['rebuild'] = TRUE;
+
+  if ($form_state['clicked_button']['#name'] == 'submit') {
+    variable_set('tripal_phylogeny_default_phylogram_width', $form_state['values']['phylogram_width']);
+
+    variable_set('tripal_phylogeny_default_root_node_size', $form_state['values']['root_node_size']);
+    variable_set('tripal_phylogeny_default_interior_node_size', $form_state['values']['interior_node_size']);
+    variable_set('tripal_phylogeny_default_leaf_node_size', $form_state['values']['leaf_node_size']);
+
+    $num_orgs = $form_state['values']['num_orgs'];
+    variable_set("tripal_phylogeny_num_orgs", $num_orgs);
+    $colors = array();
+    for ($i = 0; $i < $num_orgs ;$i++) {
+      $colors[$i] = array(
+        'organism' => $form_state['values']['organism_' . $i],
+        'color' => $form_state['values']['color_' . $i]
+      );
+    }
+    variable_set("tripal_phylogeny_org_colors", $colors);
+  }
+  if ($form_state['clicked_button']['#name'] == 'add') {
+    $form_state['values']['num_orgs']++;
+  }
+  if ($form_state['clicked_button']['#name'] == 'remove') {
+    $form_state['values']['num_orgs']--;
+  }
+}
+
+/**
+ *
+ * @param unknown $variables
+ */
+function theme_tripal_phylogeny_admin_org_color_tables($variables){
+   $fields = $variables['element'];
+   $num_orgs = $fields['num_orgs']['#value'];
+   $headers = array('Organism', 'Color', '');
+   $rows = array();
+   for ($i = 0; $i < $num_orgs; $i++) {
+     $add_button = ($i == $num_orgs - 1) ? drupal_render($fields['add']) : '';
+     $del_button = ($i == $num_orgs - 1 and $i != 0) ? drupal_render($fields['remove']) : '';
+     $rows[] = array(
+       drupal_render($fields['organism_' . $i]),
+       drupal_render($fields['color_' . $i]),
+       $add_button . $del_button,
+     );
+   }
+   $table_vars = array(
+     'header' => $headers,
+     'rows' => $rows,
+     'attributes' => array(),
+     'sticky' => FALSE,
+     'colgroups' => array(),
+     'empty' => '',
+   );
+   $form['orgs']['num_orgs'] = $fields['num_orgs'];
+   return theme('table', $table_vars);
+}
+
+
+/**
+ * Ajax callback function for the gensas_job_view_panel_form.
+ *
+ * @param $form
+ * @param $form_state
+ */
+function tripal_phylogeny_default_plots_form_ajax_callback($form, $form_state) {
+ // drupal_debug($form['tree_settings']['org_table']['num_orgs']);
+
+  return $form['node_settings']['org_table'];
+}

+ 782 - 0
tripal_phylogeny/includes/tripal_phylogeny.chado_node.inc

@@ -0,0 +1,782 @@
+<?php
+
+/**
+ * @file
+ * Implements the phylotree node content type
+ */
+
+/**
+ * Implements hook_node_info().
+ *
+ * Provide information to drupal about the node types that we're creating
+ * in this module.
+ *
+ * @ingroup tripal_phylogeny
+ */
+function tripal_phylogeny_node_info() {
+  $nodes = array();
+  $nodes['chado_phylotree'] = array(
+    'name'        => t('Phylotree'),
+    'base'        => 'chado_phylotree',
+    'description' => t('A phylotree from the chado database'),
+    'has_title'   => TRUE,
+    'locked'      => TRUE,
+    'chado_node_api' => array(
+      'base_table' => 'phylotree',
+      'hook_prefix' => 'chado_phylotree',
+      'record_type_title' => array(
+        'singular' => t('Phylotree'),
+        'plural' => t('Phylotrees')
+      ),
+
+      /* sync_filters: tripal is hardcoded to look for this
+       sync_filter settings: type_id and organism_id. (phylotree does
+       not have organism_id but need to set it false anyways. */
+      'sync_filters' => array(
+        'type_id' => FALSE,
+        'organism_id' => FALSE
+      ),
+    )
+  );
+  return $nodes;
+}
+
+
+/**
+ * Implements hook_node_view(). Acts on all content types
+ *
+ * @ingroup tripal_phylogeny
+ */
+function tripal_phylogeny_node_view($node, $view_mode, $langcode) {
+
+  if($node->type != 'chado_phylotree') { return; }
+
+  switch($view_mode) {
+  case 'full':
+    $node->content['tripal_phylogeny_base'] = array(
+      '#theme' => 'tripal_phylogeny_base',
+      '#node' => $node,
+      '#tripal_toc_id'    => 'base',
+      '#tripal_toc_title' => 'Overview',
+      '#weight' => -100,
+    );
+    $node->content['tripal_phylogeny_phylogram'] = array(
+      '#theme' => 'tripal_phylogeny_phylogram',
+      '#node' => $node,
+      '#tripal_toc_id'    => 'phylotree_phylogram',
+      '#tripal_toc_title' => 'Phylogram',
+      '#weight' => -90,
+    );
+    $node->content['tripal_phylogeny_taxonomic_tree'] = array(
+      '#theme' => 'tripal_phylogeny_taxonomic_tree',
+      '#node' => $node,
+      '#tripal_toc_id'    => 'tripal_phylogeny_taxonomic_tree',
+      '#tripal_toc_title' => 'Taxonomic Tree',
+      '#weight' => -80,
+    );
+    $node->content['tripal_phylogeny_organisms'] = array(
+      '#theme' => 'tripal_phylogeny_organisms',
+      '#node' => $node,
+      '#tripal_toc_id'    => 'phylotree_organisms',
+      '#tripal_toc_title' => 'Organisms',
+      '#weight' => -70,
+    );
+    $node->content['tripal_phylogeny_references'] = array(
+      '#theme' => 'tripal_phylogeny_references',
+      '#node' => $node,
+      '#tripal_toc_id'    => 'phylotree_references',
+      '#tripal_toc_title' => 'Cross References',
+    );
+     $node->content['tripal_phylogeny_analysis'] = array(
+      '#theme' => 'tripal_phylogeny_analysis',
+      '#node' => $node,
+      '#tripal_toc_id'    => 'phylotree_analysis',
+      '#tripal_toc_title' => 'Analysis',
+    );
+    break;
+
+  case 'teaser':
+    $node->content['tripal_phylogeny_teaser'] = array(
+      '#theme' => 'tripal_phylogeny_teaser',
+      '#node' => $node,
+    );
+    break;
+    }
+}
+
+/**
+ * Implementation of hook_form().
+ *
+ * @ingroup tripal_phylogeny
+ */
+function chado_phylotree_form($node, &$form_state) {
+
+  $form = array();
+
+  // Default values can come in the following ways:
+  //
+  // 1) as elements of the $node object.  This occurs when editing an existing phylotree
+  // 2) in the $form_state['values'] array which occurs on a failed validation or
+  //    ajax callbacks from non submit form elements
+  // 3) in the $form_state['input'[ array which occurs on ajax callbacks from submit
+  //    form elements and the form is being rebuilt
+  //
+  // set form field defaults
+  $phylotree     = null;
+  $phylotree_id  = null;
+  $tree_name     = '';
+  $leaf_type     = '';
+  $analysis_id   = '';
+  $dbxref        = '';
+  $comment       = '';
+  $tree_required = TRUE;
+  $tree_file     = '';
+  $name_re      = '';
+  $match = '';
+
+  // If we are editing an existing node then the phylotree is already part of the node.
+  if (property_exists($node, 'phylotree')) {
+    $phylotree      = $node->phylotree;
+    $phylotree      = chado_expand_var($phylotree, 'field', 'phylotree.comment');
+    $phylotree_id   = $phylotree->phylotree_id;
+    $tree_name      = $phylotree->name;
+    $leaf_type      = $phylotree->type_id ? $phylotree->type_id->name : '';
+    $comment        = $phylotree->comment;
+    $analysis_id    = $phylotree->analysis_id ? $phylotree->analysis_id->analysis_id : '';
+    $dbxref         = $phylotree->dbxref_id->db_id->name . ":" . $phylotree->dbxref_id->accession;
+    $name_re        = $phylotree->tripal_variables->phylotree_name_re;
+    $match          = $phylotree->tripal_variables->phylotree_use_uniquename;
+
+    // If the dbxref is the null db then hide it.
+    if ($phylotree->dbxref_id->db_id->name == 'null') {
+      $dbxref = '';
+    }
+
+    // Get the tree file name. If the file was added via the Drupal interface
+    // then a numeric file_id will be present in the phylotree_tree_file
+    // variable. If not then the tree was loaded on the command-line and
+    // the actual filename is in this variable.
+    $file_id = $phylotree->tripal_variables->phylotree_tree_file;
+    if (is_numeric($file_id)) {
+      $file = file_load($file_id);
+      if ($file) {
+        $tree_file = $file->filename;
+      }
+    }
+    else {
+      $tree_file = $file_id;
+    }
+
+    // The tree file is not a required input field when editing the node.
+    $tree_required  = FALSE;
+
+    // Keep track of the phylotree id.
+    $form['phylotree_id'] = array(
+      '#type' => 'value',
+      '#value' => $phylotree_id,
+    );
+  }
+  // If we are re constructing the form from a failed validation or ajax callback
+  // then use the $form_state['values'] values.
+  if (array_key_exists('values', $form_state) and isset($form_state['values']['tree_name'])) {
+    $tree_name    = $form_state['values']['tree_name'];
+    $leaf_type    = $form_state['values']['leaf_type'];
+    $analysis_id  = $form_state['values']['analysis_id'];
+    $dbxref       = $form_state['values']['dbxref'];
+    $comment      = $form_state['values']['description'];
+  }
+  // If we are re building the form from after submission (from ajax call) then
+  // the values are in the $form_state['input'] array.
+  if (array_key_exists('input', $form_state) and !empty($form_state['input'])) {
+    $tree_name    = $form_state['input']['tree_name'];
+    $leaf_type    = $form_state['input']['leaf_type'];
+    $analysis_id  = $form_state['input']['analysis_id'];
+    $comment      = $form_state['input']['description'];
+    $dbxref       = $form_state['input']['dbxref'];
+  }
+
+  $form['tree_name']= array(
+    '#type' => 'textfield',
+    '#title' => t('Tree Name'),
+    '#required' => TRUE,
+    '#default_value' => $tree_name,
+    '#description' => t('Enter the name used to refer to this phylogenetic tree.'),
+    '#maxlength' => 255
+  );
+
+  $type_cv = tripal_get_default_cv('phylotree', 'type_id');
+  $so_cv  = tripal_get_cv(array('name' => 'sequence'));
+  $cv_id = $so_cv->cv_id;
+  if (!$so_cv) {
+    drupal_set_message('The Sequence Ontolgoy does not appear to be imported.
+        Please import the Sequence Ontology before adding a tree.', 'error');
+  }
+
+  $form['leaf_type'] = array(
+    '#title'       => t('Tree Type'),
+    '#type'        => 'textfield',
+    '#description' => t("Choose the tree type. The type is
+        a valid Sequence Ontology (SO) term. For example, trees derived
+        from protein sequences should use the SO term 'polypeptide'.
+        Alternatively, a phylotree can be used for representing a taxonomic
+        tree. In this case, the word 'taxonomy' should be used."),
+    '#required'    => TRUE,
+    '#default_value' => $leaf_type,
+    '#autocomplete_path' => "admin/tripal/chado/tripal_cv/cvterm/auto_name/$cv_id",
+  );
+
+  // Get the list of analyses.
+  $sql = "SELECT * FROM {analysis} ORDER BY name";
+  $arset = chado_query($sql);
+  $analyses = array();
+  $analyses[''] = '';
+  while ($analysis = $arset->fetchObject()) {
+    $analyses[$analysis->analysis_id] = $analysis->name;
+  }
+  $form['analysis_id'] = array(
+    '#title'         => t('Analysis'),
+    '#type'          => 'select',
+    '#description'   => t("Choose the analysis from which this phylogenetic tree was derived"),
+    '#required'      => TRUE,
+    '#default_value' => $analysis_id,
+    '#options'       => $analyses,
+  );
+
+  $form['dbxref'] = array(
+    '#title'       => t('Database Cross-Reference'),
+    '#type'        => 'textfield',
+    '#description' => t("Enter a database cross-reference of the form
+        [DB name]:[accession]. The database name must already exist in the
+        database. If the accession does not exist it is automatically added."),
+    '#required'    => FALSE,
+    '#default_value' => $dbxref,
+  );
+
+  $form['description']= array(
+    '#type' => 'textarea',
+    '#title' => t('Description'),
+    '#required' => TRUE,
+    '#default_value' => $comment,
+    '#description' => t('Enter a description for this tree.'),
+  );
+
+  $upload_location = tripal_get_files_stream('tripal_phylogeny');
+  $form['tree_file'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Tree File Import'),
+    '#collapsible' => FALSE,
+  );
+
+  $description = t('Please provide a file in the Newick format that contains
+      the nodes of this tree.');
+  if ($tree_file) {
+    $form['tree_file']['curr_file'] = array(
+      '#type' => 'item',
+      '#title' => 'Current Tree File',
+      '#markup' => $tree_file,
+    );
+    $description = t('Please provide a file in the Newick format that
+        contains the nodes of this tree.  Please note that uploading a new
+        file will overwrite the current tree.');
+  }
+  $form['tree_file']['tree_file'] = array(
+    '#type' => 'managed_file',
+    '#title' => t('New Tree File'),
+    '#description' => $description,
+    '#upload_location' => $upload_location,
+    '#upload_validators' => array(
+        // We don't want to require a specific file extension so leave the array empty.
+       'file_validate_extensions' => array(),
+        // The following is for checking the Newick file format.
+       'chado_phylotree_validate_newick_format' => array(),
+    ),
+    '#required' => $tree_required,
+  );
+
+  $form['tree_file']['name_re'] = array(
+      '#title' => t('Feature Name Regular Expression'),
+      '#type' => 'textfield',
+      '#description' => t('If this is a phylogenetic (non taxonomic) tree, then
+          the tree nodes will be automatically associated with features. However,
+          if the nodes in the tree file are not exactly as the names of features
+          but have enough information to uniquely identify the feature then you
+          may provide a regular expression that the importer will use to extract
+          the feature names from the node names.'),
+      '#default_value' => $name_re,
+  );
+  $form['tree_file']['match'] = array(
+      '#title' => t('Use Unique Feature Name'),
+      '#type' => 'checkbox',
+      '#description' => t('If this is a phylogenetic (non taonomic tree) and the nodes ' .
+          'should match the unique name of the feature rather than the name of the feautre ' .
+          'then select this box. If unselected the loader will try to match the feature ' .
+          'using the feature name.'),
+      '#default_value' => $match,
+  );
+
+  return $form;
+}
+
+/**
+ * A validation function for checking the newick file format.
+ *
+ * @param stdClass $file
+ *   A Drupal file object.
+ */
+function chado_phylotree_validate_newick_format(stdClass $file) {
+  // An array of strings where each string represents a unique error
+  // when examining the file.
+  $errors = array();
+
+  // TODO: check the newick file format for errors.
+
+  return $errors;
+}
+
+/**
+ * Implementation of hook_validate().
+ *
+ * This validation is being used for three activities:
+ *   CASE A: Update a node that exists in both drupal and chado
+ *   CASE B: Synchronizing a node from chado to drupal
+ *   CASE C: Inserting a new node that exists in niether drupal nor chado
+ *
+ * @ingroup tripal_phylogeny
+ */
+function chado_phylotree_validate($node, $form, &$form_state) {
+
+  // We are syncing if we do not have a node ID but we do have a phylotree_id. We don't
+  // need to validate during syncing so just skip it.
+  if (is_null($node->nid) and property_exists($node, 'phylotree_id') and $node->phylotree_id != 0) {
+    return;
+  }
+
+  // Remove surrounding white-space on submitted values.
+  $node->tree_name  = trim($node->tree_name);
+  $node->description   = trim($node->description);
+  $node->dbxref = trim($node->dbxref);
+
+  // if this is a delete then don't validate
+  if ($node->op == 'Delete') {
+    return;
+  }
+
+  $errors = array();
+  $warnings = array();
+  $options = array(
+    'name'         => $node->tree_name,
+    'description'  => $node->description,
+    'analysis_id'  => $node->analysis_id,
+    'leaf_type'    => $node->leaf_type,
+    'tree_file'    => $node->tree_file,
+    'format'       => 'newick',
+    'dbxref'       => $node->dbxref,
+    'match'        => $node->match,
+    'name_re'      => $node->name_re,
+  );
+  // If we have a node id already then this is an update:
+  if ($node->nid) {
+    $options['phylotree_id'] = $node->phylotree_id;
+    tripal_validate_phylotree('update', $options, $errors, $warnings);
+  }
+  else {
+    tripal_validate_phylotree('insert', $options, $errors, $warnings);
+  }
+
+  // Now set form errors if any errors were detected.
+  if (count($errors) > 0) {
+    foreach($errors as $field => $message) {
+      if ($field == 'name') {
+        $field = 'tree_name';
+      }
+      form_set_error($field, $message);
+    }
+  }
+  // Add any warnings if any were detected
+  if (count($warnings) > 0) {
+    foreach($warnings as $field => $message) {
+      drupal_set_message($message, 'warning');
+    }
+  }
+}
+/**
+ * Implements hook_node_presave(). Acts on all node content types.
+ *
+ * @ingroup tripal_phylogeny
+ */
+function tripal_phylogeny_node_presave($node) {
+
+  switch ($node->type) {
+    // This step is for setting the title for the Drupal node.  This title
+    // is permanent and thus is created to be unique.  Title changes provided
+    // by tokens are generated on the fly dynamically, but the node title
+    // seen in the content listing needs to be set here. Do not call
+    // the chado_get_node_title() function here to set the title as the node
+    // object isn't properly filled out and the function will fail.
+    case 'chado_phylotree':
+      // for a form submission the 'phylotreename' field will be set,
+      // for a sync, we must pull from the phylotree object
+      if (property_exists($node, 'phylotreename')) {
+        // set the title
+        $node->title = $node->tree_name;
+      }
+      else if (property_exists($node, 'phylotree')) {
+        $node->title = $node->phylotree->name;
+      }
+      break;
+  }
+}
+
+/**
+ * Implements hook_node_insert().
+ * Acts on all content types.
+ *
+ * @ingroup tripal_phylogeny
+ */
+function tripal_phylogeny_node_insert($node) {
+
+  switch ($node->type) {
+    case 'chado_phylotree':
+
+      $phylotree_id = chado_get_id_from_nid('phylotree', $node->nid);
+      $values = array('phylotree_id' => $phylotree_id);
+      $phylotree = chado_generate_var('phylotree', $values);
+      $phylotree = chado_expand_var($phylotree, 'field', 'phylotree.comment');
+      $node->phylotree = $phylotree;
+
+      // Now use the API to set the path.
+      chado_set_node_url($node);
+
+      // Now get the title.
+      $node->title = chado_get_node_title($node);
+
+      break;
+  }
+}
+
+/**
+ * Implements hook_node_update().
+ * Acts on all content types.
+ *
+ * @ingroup tripal_phylogeny
+ */
+function tripal_phylogeny_node_update($node) {
+
+  switch ($node->type) {
+    case 'chado_phylotree':
+
+      $phylotree_id = chado_get_id_from_nid('phylotree', $node->nid);
+      $values = array('phylotree_id' => $phylotree_id);
+      $phylotree = chado_generate_var('phylotree', $values);
+      $phylotree = chado_expand_var($phylotree, 'field', 'phylotree.comment');
+      $node->phylotree = $phylotree;
+
+      // Now get the title
+      $node->title = chado_get_node_title($node);
+
+      break;
+  }
+}
+
+/**
+ * Implements [content_type]_chado_node_default_title_format().
+ *
+ * Defines a default title format for the Chado Node API to set the titles on
+ * Chado phylotree nodes based on chado fields.
+ *
+ * @ingroup tripal_phylogeny
+ */
+function chado_phylotree_chado_node_default_title_format() {
+  return '[phylotree.name]';
+}
+
+/**
+ * Implements hook_chado_node_default_url_format().
+ *
+ * Designates a default URL format for phylotree nodes.
+ */
+function chado_phylotree_chado_node_default_url_format() {
+  return '/phylotree/[phylotree.name]';
+}
+
+/**
+ *  Implements hook_insert().
+ *
+ *  When a new chado_phylotree node is created we also need to add
+ *  information to our chado_phylotree table.  This function is called
+ *  on insert of a new node of type 'chado_phylotree' and inserts the
+ *  necessary information.
+ *
+ * @ingroup tripal_phylogeny
+ */
+function chado_phylotree_insert($node) {
+  global $user;
+
+  $node->tree_name   = trim($node->tree_name);
+  $node->description = trim($node->description);
+  $node->dbxref      = trim($node->dbxref);
+
+  // if there is a phylotree_id in the $node object then this must
+  // be a sync (not an insert) so we can skip adding the phylotree as it is
+  // already there, although we do need to proceed with the rest of the
+  // insert.
+  $phylotree_id = NULL;
+  if (!property_exists($node, 'phylotree_id')) {
+    $options = array(
+      'name'         => $node->tree_name,
+      'description'  => $node->description,
+      'analysis_id'  => $node->analysis_id,
+      'leaf_type'    => $node->leaf_type,
+      'tree_file'    => $node->tree_file,
+      'format'       => 'newick',
+      'dbxref'       => $node->dbxref,
+      'match'        => $node->match,
+      'name_re'      => $node->name_re,
+    );
+    $errors = array();
+    $warnings = array();
+    if (tripal_insert_phylotree($options, $errors, $warnings)) {
+      $phylotree_id = $options['phylotree_id'];
+
+      // Add the Tripal variables to this node.
+      tripal_add_node_variable($node->nid, 'phylotree_name_re', $node->name_re);
+      tripal_add_node_variable($node->nid, 'phylotree_use_uniquename', $node->match);
+      tripal_add_node_variable($node->nid, 'phylotree_tree_file', $node->tree_file);
+    }
+    else {
+      drupal_set_message(t('Unable to insert phylotree.'), 'error');
+      tripal_report_error('tripal_phylogeny', TRIPAL_WARNING,
+          'Insert phylotree: Unable to insert phylotree where values: %values',
+          array('%values' => print_r($options, TRUE))
+      );
+    }
+  }
+  else {
+    $phylotree_id = $node->phylotree_id;
+  }
+
+  // Make sure the entry for this phylotree doesn't already exist in the
+  // chado_phylotree table if it doesn't exist then we want to add it.
+  $check_org_id = chado_get_id_from_nid('phylotree', $node->nid);
+  if (!$check_org_id) {
+    $record = new stdClass();
+    $record->nid = $node->nid;
+    $record->vid = $node->vid;
+    $record->phylotree_id = $phylotree_id;
+    drupal_write_record('chado_phylotree', $record);
+  }
+}
+
+/**
+ * Implements hook_update().
+ *
+ * @ingroup tripal_phylogeny
+ */
+function chado_phylotree_update($node) {
+
+  global $user;
+
+  $node->tree_name  = trim($node->tree_name);
+  $node->description   = trim($node->description);
+  $node->dbxref = trim($node->dbxref);
+
+  // Get the phylotree_id for this node.
+  $phylotree_id = chado_get_id_from_nid('phylotree', $node->nid) ;
+
+
+  $options = array(
+    'phylotree_id' => $node->phylotree_id,
+    'name'         => $node->tree_name,
+    'description'  => $node->description,
+    'analysis_id'  => $node->analysis_id,
+    'leaf_type'    => $node->leaf_type,
+    'tree_file'    => $node->tree_file,
+    'format'       => 'newick',
+    'dbxref'       => $node->dbxref,
+    'match'        => $node->match,
+    'name_re'      => $node->name_re,
+  );
+
+  $success = tripal_update_phylotree($phylotree_id, $options);
+
+  if (!$success) {
+    drupal_set_message("Unable to update phylotree.", "error");
+    tripal_report_error('tripal_phylogeny', TRIPAL_WARNING,
+      'Update phylotree: Unable to update phylotree where values: %values',
+      array('%values' => print_r($options, TRUE))
+    );
+    return;
+  }
+
+  // Remove any variables and then add back the variables from the form.
+  tripal_delete_node_variables($node->nid);
+  tripal_add_node_variable($node->nid, 'phylotree_name_re', $node->name_re);
+  tripal_add_node_variable($node->nid, 'phylotree_use_uniquename', $node->match);
+  tripal_add_node_variable($node->nid, 'phylotree_tree_file', $node->tree_file);
+}
+/**
+ *  Implements hook_load().
+ *
+ *  When a node is requested by the user this function is called to allow us
+ *  to add auxiliary data to the node object.
+ *
+ * @ingroup tripal_phylogeny
+ */
+function chado_phylotree_load($nodes) {
+
+  foreach ($nodes as $nid => $node) {
+
+    $phylotree_id = chado_get_id_from_nid('phylotree', $nid);
+
+    // If the nid does not have a matching record then skip this node.
+    // this can happen with orphaned nodes.
+    if (!$phylotree_id) {
+      continue;
+    }
+
+    // Build the Chado variable for the phylotree.
+    $values = array('phylotree_id' => $phylotree_id);
+    $phylotree = chado_generate_var('phylotree', $values);
+    $nodes[$nid]->phylotree = $phylotree;
+
+    // Expand the comment field, chado_generate_var() omits it by default
+    // because it is a large text field.
+    $phylotree = chado_expand_var($phylotree, 'field', 'phylotree.comment');
+
+    // Add non Chado information to the object. These variables are needed
+    // for the edit/update forms.
+    $phylotree->tripal_variables = new stdClass;
+    $variables = tripal_get_node_variables($nid, 'phylotree_name_re');
+    $phylotree->tripal_variables->phylotree_name_re = count($variables) > 0 ? $variables[0]->value : '';
+
+    $variables = tripal_get_node_variables($nid, 'phylotree_use_uniquename');
+    $phylotree->tripal_variables->phylotree_use_uniquename = count($variables) > 0 ? $variables[0]->value : '';
+
+    $variables = tripal_get_node_variables($nid, 'phylotree_tree_file');
+    $phylotree->tripal_variables->phylotree_tree_file = count($variables) > 0 ? $variables[0]->value : '';
+
+    // Set the title for this node.
+    $node->title = chado_get_node_title($node);
+  }
+}
+
+/**
+ * Implements hook_delete().
+ *
+ * Delete data from drupal and chado databases when a node is deleted
+ *
+ * @ingroup tripal_phylogeny
+ */
+function chado_phylotree_delete(&$node) {
+
+  $phylotree_id = chado_get_id_from_nid('phylotree', $node->nid);
+
+  // if we don't have a phylotree id for this node then this isn't a node of
+  // type chado_phylotree or the entry in the chado_phylotree table was lost.
+  if (!$phylotree_id) {
+    return;
+  }
+
+  // Remove data from {chado_phylotree}, {node} and {node_revisions} tables of
+  // drupal database
+  $sql_del = "DELETE FROM {chado_phylotree} WHERE nid = :nid AND vid = :vid";
+  db_query($sql_del, array(':nid' => $node->nid, ':vid' => $node->vid));
+  $sql_del = "DELETE FROM {node_revision} WHERE nid = :nid AND vid = :vid";
+  db_query($sql_del, array(':nid' => $node->nid, ':vid' => $node->vid));
+  $sql_del = "DELETE FROM {node} WHERE nid = :nid AND vid = :vid";
+  db_query($sql_del, array(':nid' => $node->nid, ':vid' => $node->vid));
+
+  // Remove data from phylotree and phylotreeprop tables of chado
+  // database as well
+
+  chado_query("DELETE FROM {phylotree} WHERE phylotree_id = :phylotree_id", array(':phylotree_id' => $phylotree_id));
+
+}
+
+/**
+ * Implement hook_node_access().
+ *
+ * This hook allows node modules to limit access to the node types they define.
+ *
+ *  @param $node
+ *  The node on which the operation is to be performed, or, if it does not yet exist, the
+ *  type of node to be created
+ *
+ *  @param $op
+ *  The operation to be performed
+ *
+ *  @param $account
+ *  A user object representing the user for whom the operation is to be performed
+ *
+ *  @return
+ *  If the permission for the specified operation is not set then return FALSE. If the
+ *  permission is set then return NULL as this allows other modules to disable
+ *  access.  The only exception is when the $op == 'create'.  We will always
+ *  return TRUE if the permission is set.
+ *
+ * @ingroup tripal_phylogeny
+ */
+function chado_phylotree_node_access($node, $op, $account) {
+
+  $node_type = $node;
+  if (is_object($node)) {
+    $node_type = $node->type;
+  }
+
+  if($node_type == 'chado_phylotree') {
+    if ($op == 'create') {
+      if (!user_access('create chado_phylotree content', $account)) {
+        return NODE_ACCESS_DENY;
+      }
+      return NODE_ACCESS_ALLOW;
+    }
+    if ($op == 'update') {
+      if (!user_access('edit chado_phylotree content', $account)) {
+        return NODE_ACCESS_DENY;
+      }
+    }
+    if ($op == 'delete') {
+      if (!user_access('delete chado_phylotree content', $account)) {
+        return NODE_ACCESS_DENY;
+      }
+    }
+    if ($op == 'view') {
+      if (!user_access('access chado_phylotree content', $account)) {
+        return NODE_ACCESS_DENY;
+      }
+    }
+    return NODE_ACCESS_IGNORE;
+  }
+}
+
+/**
+ *  Phylotree feature summary.
+ *
+ *  Get an array of feature counts by organism. key = organism
+ *  abbreviation. value = number of features for this phylotree having
+ *  this organism.
+ *
+ * @param int phylotree_id
+ * @return array
+ * @ingroup tripal_phylogeny
+ */
+function phylotree_feature_summary($phylotree_id) {
+
+  $sql = "
+    SELECT o.abbreviation, COUNT(o.organism_id) AS count
+    FROM {phylonode} n
+      LEFT OUTER JOIN {feature} f  ON n.feature_id = f.feature_id
+      LEFT OUTER JOIN {organism} o ON f.organism_id = o.organism_id
+    WHERE n.phylotree_id = :phylotree_id
+      AND n.feature_id IS NOT NULL
+    GROUP BY o.organism_id
+  ";
+
+  $args = array(':phylotree_id' => $phylotree_id);
+  $result = chado_query($sql, $args);
+  $summary = array();
+  foreach($result as $r) {
+    $summary[$r->abbreviation] = $r->count;
+  }
+  return $summary;
+}

+ 326 - 0
tripal_phylogeny/includes/tripal_phylogeny.import_tree.inc

@@ -0,0 +1,326 @@
+<?php
+
+
+/**
+ * Imports a tree file.
+ *
+ * This function is used as a wrapper for loading a phylogenetic tree using
+ * any number of file loaders.
+ *
+ * @param $file_name
+ *   The name of the file containing the phylogenetic tree to import.
+ * @param $format
+ *   The format of the file. Currently only the 'newick' file format is
+ *   supported.
+ * @param $options
+ *   Options if the phylotree record already exists:
+ *     'phylotree_id': The imported nodes will be associated with this tree.
+ *     'leaf_type':  A sequence ontology term or the word 'organism'. If the
+ *                   type is 'organism' then this tree represents a
+ *                   taxonomic tree.  The default, if not specified, is the
+ *                   term 'polypeptide'.
+ *     'name_re':    If the leaf type is NOT 'taxonomy', then the value of
+ *                   this field can be a regular expression to pull out
+ *                   the name of the feature from the node label in the
+ *                   intput tree. If no value is provided the entire label is
+ *                   used.
+ *     'match':      Set to 'uniquename' if the leaf nodes should be matched
+ *                   with the feature uniquename.
+ *
+ */
+function tripal_phylogeny_import_tree_file($file_name, $format, $options = array(), $job_id = NULL) {
+
+    // Set some option details.
+  if (!array_key_exists('leaf_type', $options)) {
+    $options['leaf_type'] = 'polypeptide';
+  }
+  if (!array_key_exists('match', $options)) {
+    $options['match'] = 'name';
+  }
+  if (!array_key_exists('name_re', $options)) {
+    $options['name_re'] = '^(.*)$';
+  }
+  $options['name_re'] = trim($options['name_re']);
+
+  // If a phylotree ID is not passed in then make sure we have the other
+  // required fields for creating a tree.
+  if (!array_key_exists('phylotree_id', $options)) {
+    if (!array_key_exists('name', $options)) {
+       tripal_report_error('tripal_phylogeny', TRIPAL_ERROR,
+         'The phylotree_id is required for importing the tree.');
+       return FALSE;
+    }
+  }
+
+  // get the phylotree record.
+  $values = array('phylotree_id' => $options['phylotree_id']);
+  $phylotree = chado_generate_var('phylotree', $values);
+
+  if (!$phylotree) {
+    tripal_report_error('tripal_phylogeny', TRIPAL_ERROR,
+        'Could not find the phylotree using the ID provided: %phylotree_id.',
+        array('%phylotree_id' => $options['phylotree_id']));
+    return FALSE;
+  }
+
+  $transaction = db_transaction();
+  print "\nNOTE: Loading of this tree file is performed using a database transaction. \n" .
+      "If the load fails or is terminated prematurely then the entire set of \n" .
+      "insertions/updates is rolled back and will not be found in the database\n\n";
+  try {
+
+    // Parse the file according to the format indicated.
+    if ($format == 'newick') {
+      // Parse the tree into the expected nested node format.
+      module_load_include('inc', 'tripal_phylogeny', 'includes/parsers/tripal_phylogeny.newick_parser');
+      $tree = tripal_phylogeny_parse_newick_file($file_name);
+
+      // Assign the right and left indecies to the tree ndoes
+      tripal_phylogeny_assign_tree_indices($tree);
+    }
+    // Iterate through the tree nodes and add them to Chado in accordance
+    // with the details in the $options array.
+    tripal_phylogeny_import_tree($tree, $phylotree, $options);
+  }
+  catch (Exception $e) {
+    $transaction->rollback();
+    watchdog_exception('tripal_phylogeny', $e);
+    print "\nFAILED: Rolling back database changes...\n";
+  }
+  print "\nDone Importing Tree.\n";
+}
+
+/**
+ *
+ * @return boolean|multitype:Either
+ */
+function tripal_phylogeny_get_node_types_vocab() {
+  // Get the vocabulary terms used to describe nodes in the tree
+  $values = array(
+    'name' => 'phylo_leaf',
+    'cv_id' => array(
+      'name' => 'tripal_phylogeny',
+    ),
+  );
+  $leaf = chado_generate_var('cvterm', $values);
+  if (!$leaf) {
+    tripal_report_error('tripal_phylogeny', TRIPAL_ERROR,
+      "Could not find the leaf vocabulary term: 'phylo_leaf'. It should " .
+      "already be present as part of the tripal_phylogeny vocabulary.");
+    return FALSE;
+  }
+  $values['name'] = 'phylo_interior';
+  $internal = chado_generate_var('cvterm', $values);
+  if (!$internal) {
+    tripal_report_error('tripal_phylogeny', TRIPAL_ERROR,
+      "Could not find the leaf vocabulary term: 'phylo_interior'. It should " .
+      "already be present as part of the tripal_phylogeny vocabulary.");
+    return FALSE;
+  }
+  $values['name'] = 'phylo_root';
+  $root = chado_generate_var('cvterm', $values);
+  if (!$root) {
+    tripal_report_error('tripal_phylogeny', TRIPAL_ERROR,
+      "Could not find the leaf vocabulary term: 'phylo_root'. It should " .
+      "already be present as part of the tripal_phylogeny vocabulary.");
+    return FALSE;
+  }
+  $vocab = array(
+    'leaf' => $leaf,
+    'internal' => $internal,
+    'root' => $root,
+  );
+  return $vocab;
+}
+
+/**
+ * Iterates through the tree and sets the left and right indicies .
+ *
+ * @param $tree
+ *   The tree array.
+ * @param $index
+ *   This parameters is not used when the function is first called. It
+ *   is used for recursive calls.
+ */
+function tripal_phylogeny_assign_tree_indices(&$tree, &$index = 1) {
+  // Assign a left and right index to each node.  The child node must
+  // have a right and left index less than that of it's parents.  We
+  // increment the index by 100 to give space for new nodes that might
+  // be added later.
+  if (array_key_exists('name', $tree)) {
+    $tree['left_index'] = $index += 100;
+    if (array_key_exists('is_leaf', $tree)) {
+      $tree['right_index'] = $index += 100;
+    }
+  }
+  if (array_key_exists('branch_set', $tree)) {
+    foreach ($tree['branch_set'] as $key => $node) {
+      tripal_phylogeny_assign_tree_indices($tree['branch_set'][$key], $index);
+      $tree['right_index'] = $index += 100;
+    }
+  }
+}
+
+/**
+ * Iterates through the tree array and creates phylonodes in Chado.
+ *
+ * The function iterates through the tree in a top-down approach adding
+ * parent internal nodes prior to leaf nodes.  Each node of the tree should have
+ * the following fields:
+ *
+ *   -name:         The name (or label) for this node.
+ *   -depth:        The depth of the node in the tree.
+ *   -is_root:      Set to 1 if this node is a root node.
+ *   -is_leaf:      Set to 1 if this node is a leaf node.
+ *   -is_internal:  Set to 1 if this node is an internal node.
+ *   -left_index:   The index of the node to the left in the tree.
+ *   -right_index:  The index of the node to the right in the tree.
+ *   -branch_set:   An array containing a list of nodes of that are children
+ *                  of the node.
+ *   -parent:       The name of the parent node.
+ *   -organism_id:  The organism_id for associtating the node with an organism.
+ *   -properties:   An array of key/value pairs where the key is the cvterm_id
+ *                  and the value is the property value.  These properties
+ *                  will be assocaited with the phylonode.
+ *
+ * Prior to importing the tree the indicies can be set by using the
+ * tripal_phylogeny_assign_tree_indices() function.
+ *
+ * @param $tree
+ *   The tree array.
+ * @param $options
+ *   The options provide some direction for how the tree is imported.  The
+ *   following keys can be used:
+ *   -taxonomy:  Set to 1 if this tree is a taxonomic tree. Set to 0
+ *               otherwise.
+ *   -leaf_type: Set to the leaf type name. If this is a non-taxonomic tree
+ *               that is associated with features, then this should be the
+ *               Sequence Ontology term for the feature (e.g. polypeptide).
+ *               If this is a taxonomic tree then this option is not needed.
+ *   -match:     Set to either 'name' or 'uniquename'.  This is used for
+ *               matching the feature name or uniquename with the node name.
+ *               This is not needed for taxonomic trees.
+ *   -match_re:  Set to a regular that can be used for matching the node
+ *               name with the feature name if the node name is not
+ *               identical to the feature name.
+ * @param $vocab
+ *   Optional. An array containing a set of key/value pairs that maps node
+ *   types to CV terms.  The keys must be 'root', 'internal' or 'leaf'.  If
+ *   no vocab is provded then the terms provided by the tripal_phylogeny
+ *   CV will be used.
+ * @param $parent
+ *   This argument is not needed when the funtion is first called. This
+ *   function is recursive and this argument is used on recursive calls.
+ */
+function tripal_phylogeny_import_tree(&$tree, $phylotree, $options, $vocab = array(), $parent = NULL) {
+
+  // Get the vocabulary terms used to describe nodes in the tree if one
+  // wasn't provided.
+  if (count($vocab) == 0) {
+    $vocab = tripal_phylogeny_get_node_types_vocab();
+  }
+
+  if (is_array($tree) and array_key_exists('name', $tree)) {
+    $values = array(
+      'phylotree_id' => $phylotree->phylotree_id,
+      'left_idx'  => $tree['left_index'],
+      'right_idx' => $tree['right_index'],
+    );
+    // Add in any optional values to the $values array if they are present
+    if (!empty($tree['name']) and $tree['name'] != '') {
+      $values['label'] = $tree['name'];
+    }
+    if (!empty($tree['length']) and $tree['length'] != '') {
+      $values['distance'] = $tree['length'];
+    }
+    // Set the type of node
+    if ($tree['is_root']) {
+      $values['type_id'] = $vocab['root']->cvterm_id;
+    }
+    else if ($tree['is_internal']) {
+      $values['type_id'] = $vocab['internal']->cvterm_id;
+      $values['parent_phylonode_id'] = $parent['phylonode_id'];
+      // TOOD: a feature may be associated here but it is recommended that it
+      // be a feature of type SO:match and should represent the alignment of
+      // all features beneath it.
+    }
+    else if ($tree['is_leaf']) {
+      $values['type_id'] = $vocab['leaf']->cvterm_id;
+      $values['parent_phylonode_id'] = $parent['phylonode_id'];
+
+      // Match this leaf node with an organism or feature depending on the
+      // type of tree. But we can't do that if we don't have a name.
+      if (!empty($tree['name']) and $tree['name'] != '') {
+        if (!$options['taxonomy']) {
+
+          // This is a sequence-based tree. Try to match leaf nodes with features.
+          // First, Get the Name and uniquename for the feature
+          $matches = array();
+          $sel_values = array();
+          if ($options['match'] == "name") {
+            $sel_values['name'] = $tree['name'];
+            $re = $options['name_re'];
+            if (preg_match("/$re/", $tree['name'], $matches)) {
+              $sel_values['name'] = $matches[1];
+            }
+          }
+          else {
+            $sel_values['uniquename'] = $tree['name'];
+            $re = $options['name_re'];
+            if (preg_match("/$re/", $tree['name'], $matches)) {
+              $sel_values['uniquename'] = $matches[1];
+            }
+          }
+          $sel_values['type_id'] = array(
+            'name' => $options['leaf_type'],
+            'cv_id' => array(
+              'name' => 'sequence'
+            ),
+          );
+          $sel_columns = array('feature_id');
+          $feature = chado_select_record('feature', $sel_columns, $sel_values);
+          if (count($feature) > 1) {
+            // Found multiple features, cannot make an association.
+          }
+          else if (count($feature) == 1) {
+            $values['feature_id'] = $feature[0]->feature_id;
+          }
+          else {
+            // Could not find a feature that matches the name or uniquename
+          }
+        }
+      }
+    }
+
+    // Insert the new node and then add it's assigned phylonode_id to the node
+    $phylonode = chado_insert_record('phylonode', $values);
+    $tree['phylonode_id'] = $phylonode['phylonode_id'];
+
+    // This is a taxonomic tree, so assocaite this node with an
+    // organism if one is provided.
+    if (array_key_exists('organism_id', $tree)) {
+      $values = array(
+        'phylonode_id' => $tree['phylonode_id'],
+        'organism_id' => $tree['organism_id']
+      );
+      $pylonode_organism = chado_insert_record('phylonode_organism', $values);
+    }
+
+    // Associate any properties
+    if (array_key_exists('properties', $tree)) {
+      foreach ($tree['properties'] as $type_id => $value) {
+        $values = array(
+          'phylonode_id' => $tree['phylonode_id'],
+          'type_id' => $type_id,
+          'value' => $value,
+        );
+        $pylonode_organism = chado_insert_record('phylonodeprop', $values);
+      }
+    }
+  }
+  if (is_array($tree) and array_key_exists('branch_set', $tree)) {
+    foreach ($tree['branch_set'] as $key => $node) {
+      tripal_phylogeny_import_tree($tree['branch_set'][$key], $phylotree, $options, $vocab, $tree);
+    }
+  }
+}

+ 411 - 0
tripal_phylogeny/includes/tripal_phylogeny.taxonomy.inc

@@ -0,0 +1,411 @@
+<?php
+
+/**
+ * Generates a page that contains the taxonomy view.
+ */
+function tripal_phylogeny_taxonomy_view() {
+  $values = array(
+    'type_id' => array(
+      'name' => 'taxonomy',
+    ),
+  );
+
+  $message = t('Site administrators:  This page is meant to provide
+      a heirarchical taxonomic tree for all of the organism present
+      in this site.  This may not be useful if you only have a few
+      species. If so, you can turn off this page by disabling this page on
+      the site\'s <a href="@menu">Navigation Menu</a>.  Otherwise, to generate the taxonomy go to this site\'s
+      <a href="@taxloader">NCBI taxonomy loader</a> to import the taxonomy information from NCBI.
+      <br><br>Note: If you add new species to this site, you should rerun the
+        NCBI taxonomy loader to update the view</p>',
+      array(
+        '@menu' => url('admin/structure/menu/manage/navigation'),
+        '@taxloader' => url('admin/tripal/loaders/ncbi_taxonomy_loader'
+      ))
+  );
+  $admin_message = tripal_set_message($message, TRIPAL_INFO, array('return_html' => TRUE));
+
+  $phylotree = chado_generate_var('phylotree', $values);
+  if ($phylotree) {
+    $node = new stdClass();
+    $node->phylotree = $phylotree;
+
+    $html =  theme('tripal_phylogeny_taxonomic_tree', array('node' => $node)) .
+      $admin_message;
+    return $html;
+  }
+
+  return array(
+    '#type' => 'markup',
+    '#markup' => t('This site has not yet prepared the taxonomy for viewing.') . $admin_message,
+  );
+}
+/**
+ *
+ */
+function tripal_phylogeny_taxonomy_load_form($form, &$form_state) {
+  $form['instructions'] = array(
+    '#type' => 'item',
+    '#markup' => '',
+  );
+
+  $form['import_existing'] = array(
+    '#type' => 'checkbox',
+    '#title' => 'Import taxonomy for existing species.',
+    '#description' =>  t('The NCBI Taxonmic Importer examines the organisms
+      currently present in the database and queries NCBI for the
+      taxonomic details.  If the importer is able to match the
+      genus and species with NCBI the species details will be imported,
+      and a page containing the taxonomic tree will be created.'),
+  );
+
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#name' => 'import',
+    '#value' => 'Submit',
+  );
+  return $form;
+}
+
+/**
+ *
+ * @param unknown $form
+ * @param unknown $form_state
+ */
+function tripal_phylogeny_taxonomy_load_form_validate($form, &$form_state) {
+  global $user;
+
+  if (!$form_state['values']['import_existing']) {
+    form_set_error('import_exists', 'Please confirm the import by clicking the checkbox.');
+  }
+}
+
+/**
+ *
+ * @param unknown $form
+ * @param unknown $form_state
+ */
+function tripal_phylogeny_taxonomy_load_form_submit($form, &$form_state) {
+  global $user;
+
+  if ($form_state['values']['import_existing']) {
+    $args = array();
+    tripal_add_job("Import NCBI Taxonomy", 'tripal_phylogeny',
+      'tripal_phylogeny_ncbi_taxonomy_import', $args, $user->uid);
+  }
+}
+
+/**
+ *
+ * @param unknown $job_id
+ */
+function tripal_phylogeny_ncbi_taxonomy_import($job_id) {
+
+  print "\nNOTE: Importing of NCBI taxonomy data is performed using a database transaction. \n" .
+    "If the load fails or is terminated prematurely then the entire set of \n" .
+    "insertions/updates is rolled back and will not be found in the database\n\n";
+
+  $transaction = db_transaction();
+  try {
+    // TDDO: there should be an API function named tripal_insert_analysis().
+    // But until then we have to insert the analysis manually.
+    // Get the version of this module for the analysis record:
+    $info = system_get_info('module', 'tripal_phylogeny');
+    $version = $info['version'];
+    $analysis_name = 'NCBI Taxonomy Tree Import';
+
+    // If the analysis record already exists then don't add it again.
+    $analysis = chado_select_record('analysis', array('*'), array('name' => $analysis_name));
+    if (count($analysis) == 0) {
+      $values = array(
+        'name' => 'NCBI Taxonomy Tree Import',
+        'description' => 'Used to import NCBI taxonomy details for organisms in this database.',
+        'program' => 'Tripal Phylogeny Module NCBI Taxonomy Importer',
+        'programversion' => $version,
+        'sourcename' => 'NCBI Taxonomy',
+        'sourceuri' => 'http://www.ncbi.nlm.nih.gov/taxonomy',
+      );
+      $analysis = chado_insert_record('analysis', $values);
+      if (!$analysis) {
+        throw new Exception("Cannot add NCBI Taxonomy Tree Import Analysis.");
+      }
+    }
+    else {
+      $analysis = $analysis[0];
+    }
+
+    // If the tree already exists then don't insert it again.
+    global $site_name;
+    $tree_name = $site_name . 'Taxonomy Tree';
+    $phylotree = chado_select_record('phylotree', array('*'), array('name' => $tree_name));
+    if (count($phylotree) == 0) {
+      // Add the taxonomic tree.
+      $options = array(
+        'name' =>  $site_name . 'Taxonomy Tree',
+        'description' => 'The taxonomic tree of species present on this site. Click a species name for more details.',
+        'leaf_type' => 'taxonomy',
+        'analysis_id' => $analysis->analysis_id,
+        'tree_file' => '/dev/null',
+        'format' => 'taxonomy',
+        'no_load' => TRUE,
+      );
+      $errors = array();
+      $warnings = array();
+      $success = tripal_insert_phylotree($options, $errors, $warnings);
+      if (!$success) {
+        throw new Exception("Cannot add the Taxonomy Tree record.");
+      }
+      $phylotree = (object) $options;
+    }
+    else {
+      $phylotree = $phylotree[0];
+    }
+
+    // Clean out the phylotree in the event this is a reload
+    chado_delete_record('phylonode', array('phylotree_id' => $phylotree->phylotree_id));
+
+    // The taxonomic tree must have a root, so create that first.
+    $tree = array(
+      'name' => 'root',
+      'depth' => 0,
+      'is_root' => 1,
+      'is_leaf' => 0,
+      'is_internal' => 0,
+      'left_index' => 0,
+      'right_index' => 0,
+      'branch_set' => array(),
+    );
+
+    // Get the "rank" cvterm. It requires that the TAXRANK vocabulary is loaded.
+    $rank_cvterm = tripal_get_cvterm(array(
+      'name' => 'rank',
+      'cv_id' => array('name' => 'tripal_phylogeny')
+    ));
+
+    // Get the list of organisms
+    $sql = "SELECT O.* FROM {organism} O";
+    $organisms = chado_query($sql);
+    while ($organism = $organisms->fetchObject()) {
+      // Build the query string to get the information about this species.
+      $term = $organism->genus . ' ' . $organism->species;
+      $term = urlencode($term);
+      $search_url = "http://www.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?".
+        "db=taxonomy" .
+        "&term=$term";
+
+      // Get the search response from NCBI.
+      $rfh = fopen($search_url, "r");
+      $xml_text = '';
+      while (!feof($rfh)) {
+        $xml_text .= fread($rfh, 255);
+      }
+      fclose($rfh);
+
+      // Parse the XML to get the taxonomy ID
+      $xml = new SimpleXMLElement($xml_text);
+      if ($xml) {
+        $taxid = (string) $xml->IdList->Id;
+        if ($taxid) {
+          print "$taxid\t$organism->genus $organism->species\n";
+          // If we have a taxonomy ID we can now get the details.
+          $fetch_url = "http://www.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?".
+            "db=taxonomy" .
+            "&id=$taxid";
+          // Get the search response from NCBI.
+          $rfh = fopen($fetch_url, "r");
+          $xml_text = '';
+          while (!feof($rfh)) {
+            $xml_text .= fread($rfh, 255);
+          }
+          fclose($rfh);
+
+          $xml = new SimpleXMLElement($xml_text);
+          if ($xml) {
+            $taxon = $xml->Taxon;
+
+            // Add in the organism properties
+            $lineage = (string) $taxon->Lineage;
+            tripal_phylogeny_taxonomy_add_organism_property($organism->organism_id, 'lineage', $lineage);
+
+            $genetic_code = (string) $taxon->GeneticCode->GCId;
+            tripal_phylogeny_taxonomy_add_organism_property($organism->organism_id, 'genetic_code', $genetic_code);
+
+            $genetic_code_name = (string) $taxon->GeneticCode->GCName;
+            tripal_phylogeny_taxonomy_add_organism_property($organism->organism_id, 'genetic_code_name', $genetic_code_name);
+
+            $mito_genetic_code = (string) $taxon->MitoGeneticCode->MGCId;
+            tripal_phylogeny_taxonomy_add_organism_property($organism->organism_id, 'mitochondrial_genetic_code', $mito_genetic_code);
+
+            $mito_genetic_code_name = (string) $taxon->MitoGeneticCode->MGCName;
+            tripal_phylogeny_taxonomy_add_organism_property($organism->organism_id, 'mitochondrial_genetic_code_name', $mito_genetic_code_name);
+
+            $division = (string) $taxon->Division;
+            tripal_phylogeny_taxonomy_add_organism_property($organism->organism_id, 'division', $division);
+
+            $name_ranks = array();
+            foreach ($taxon->OtherNames->children() as $child) {
+              $type = $child->getName();
+              $name = (string) $child;
+              if (!array_key_exists($type, $name_ranks)) {
+                $name_ranks[$type] = 0;
+              }
+              switch ($type) {
+                case 'GenbankCommonName':
+                  tripal_phylogeny_taxonomy_add_organism_property($organism->organism_id, 'genbank_common_name', $name, $name_ranks[$type]);
+                  break;
+                case 'Synonym':
+                  tripal_phylogeny_taxonomy_add_organism_property($organism->organism_id, 'synonym', $name, $name_ranks[$type]);
+                  break;
+                case 'CommonName':
+                case 'Includes':
+                  tripal_phylogeny_taxonomy_add_organism_property($organism->organism_id, 'other_name', $name, $name_ranks[$type]);
+                  break;
+                case 'EquivalentName':
+                  tripal_phylogeny_taxonomy_add_organism_property($organism->organism_id, 'equivalent_name', $name, $name_ranks[$type]);
+                  break;
+                case 'Anamorph':
+                  tripal_phylogeny_taxonomy_add_organism_property($organism->organism_id, 'anamorph', $name, $name_ranks[$type]);
+                  break;
+                case 'Name':
+                  // skip the Name stanza
+                  break;
+                default:
+                  print "NOTICE: Skipping unrecognzed name type: $type\n";
+                  // do nothing for unrecognized types
+              }
+              $name_ranks[$type]++;
+            }
+
+            // Generate a nested array structure that can be used for importing the tree.
+            $parent = (string) $taxon->ParentTaxId;
+            $rank = (string) $taxon->Rank;
+            $sci_name = (string) $taxon->ScientificName;
+            $lineage_depth = preg_split('/;\s*/', $lineage);
+            $parent = $tree;
+            $i = 1;
+            foreach ($taxon->LineageEx->children() as $child) {
+              $tid = (string) $child->TaxID;
+              $name = (string) $child->ScientificName;
+              $node_rank = (string) $child->Rank;
+              $node = array(
+                'name' => $name,
+                'depth' => $i,
+                'is_root' => 0,
+                'is_leaf' => 0,
+                'is_internal' => 1,
+                'left_index' => 0,
+                'right_index' => 0,
+                'parent' => $parent,
+                'branch_set' => array(),
+                'parent' => $parent['name'],
+                'properties' => array(
+                  $rank_cvterm->cvterm_id => $node_rank,
+                ),
+              );
+              $parent = $node;
+              tripal_phylogeny_taxonomy_import_add_node($tree, $node, $lineage_depth);
+              $i++;
+            }
+            // Now add in the leaf node
+            $node = array(
+              'name' => $sci_name,
+              'depth' => $i,
+              'is_root' => 0,
+              'is_leaf' => 1,
+              'is_internal' => 0,
+              'left_index' => 0,
+              'right_index' => 0,
+              'parent' => $parent['name'],
+              'organism_id' => $organism->organism_id,
+              'properties' => array(
+                $rank_cvterm->cvterm_id => $rank,
+              ),
+            );
+            tripal_phylogeny_taxonomy_import_add_node($tree, $node, $lineage_depth);
+
+            // Set the indecies for the tree.
+            tripal_phylogeny_assign_tree_indices($tree);
+          } // end: if ($xml) { ...
+        } // end: if ($taxid) { ...
+      } // end: if ($xml) { ...
+    } // end: while ($organism = $organisms->fetchObject()) { ...
+    // print json_encode(($tree));
+
+    // Now add the tree
+    $options = array('taxonomy' => 1);
+    tripal_phylogeny_import_tree($tree, $phylotree, $options);
+
+    // If ther user requested to sync the tree then do it.
+    //if ($sync) {
+      chado_node_sync_records('phylotree', FALSE, FALSE,
+        array(), $ids = array($phylotree->phylotree_id));
+    //}
+  }
+  catch (Exception $e) {
+    $transaction->rollback();
+    print "\n"; // make sure we start errors on new line
+    watchdog_exception('tripal_phylogeny', $e);
+    print "FAILED: Rolling back database changes...\n";
+  }
+}
+
+/**
+ *
+ * @param unknown $node
+ */
+function tripal_phylogeny_taxonomy_import_add_node(&$tree, $node, $lineage_depth) {
+
+   // Get the branch set for the tree root.
+   $branch_set = &$tree['branch_set'];
+
+   // Iterate through the tree up until the depth where this node will
+   // be placed.
+   $node_depth = $node['depth'];
+   for ($i = 1; $i <= $node_depth; $i++) {
+     // Iterate through any existing nodes in the branch set to see if
+     // the node name matches the correct name for the lineage at this
+     // depth. If it matches then it is inside of this branch set that
+     // we will place the node.
+     for ($j = 0; $j < count($branch_set); $j++) {
+       // If this node already exists in the tree then return.
+       if ($branch_set[$j]['name'] == $node['name'] and
+           $branch_set[$j]['depth'] = $node['depth']) {
+         return;
+       }
+       // Otherwise, set the branch to be the current branch and continue.
+       if ($branch_set[$j]['name'] == $lineage_depth[$i-1]) {
+         $branch_set = &$branch_set[$j]['branch_set'];
+         break;
+       }
+     }
+   }
+   // Add the node to the last branch set.  This should be where this node goes.
+   $branch_set[] = $node;
+}
+
+/**
+ *
+ * @param unknown $organism_id
+ * @param unknown $term_name
+ * @param unknown $value
+ */
+function tripal_phylogeny_taxonomy_add_organism_property($organism_id, $term_name, $value, $rank = 0) {
+  if (!$value) {
+    return;
+  }
+
+  $record = array(
+    'table' => 'organism',
+    'id' => $organism_id
+  );
+  $property = array(
+    'type_name' => $term_name,
+    'cv_name' => organism_property,
+    'value' => $value
+  );
+  // Delete all properties of this type if the rank is zero.
+  if ($rank == 0) {
+    chado_delete_property($record, $property);
+  }
+  chado_insert_property($record, $property);
+}

+ 0 - 0
tripal_phylogeny/theme/css/tripal_phylogeny.css


BIN
tripal_phylogeny/theme/images/ajax-loader.gif


+ 402 - 0
tripal_phylogeny/theme/js/d3.phylogram.js

@@ -0,0 +1,402 @@
+/*
+  (agr@ncgr.org : this is a significantly modified version of
+  d3.phylogram.js....  retaining attribution/copyright per below)
+
+  d3.phylogram.js http://bl.ocks.org/kueda/1036776
+
+  Wrapper around a d3-based phylogram (tree where branch lengths are scaled)
+  Also includes a radial dendrogram visualization (branch lengths not scaled)
+  along with some helper methods for building angled-branch trees.
+
+  Copyright (c) 2013, Ken-ichi Ueda
+
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are met:
+
+  Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer. Redistributions in binary
+  form must reproduce the above copyright notice, this list of conditions and
+  the following disclaimer in the documentation and/or other materials
+  provided with the distribution.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE.
+
+  DOCUEMENTATION
+
+  d3.phylogram.build(selector, nodes, options)
+    Creates a phylogram.
+    Arguments:
+      selector: selector of an element that will contain the SVG
+      nodes: JS object of nodes
+    Options:
+      width       
+        Width of the vis, will attempt to set a default based on the width of
+        the container.
+      height
+        Height of the vis, will attempt to set a default based on the height
+        of the container.
+      fill
+        Function for generating fill color for leaf nodes.
+      vis
+        Pre-constructed d3 vis.
+      tree
+        Pre-constructed d3 tree layout.
+      children
+        Function for retrieving an array of children given a node. Default is
+        to assume each node has an attribute called "children"
+      diagonal
+        Function that creates the d attribute for an svg:path. Defaults to a
+        right-angle diagonal.
+      skipTicks
+        Skip the tick rule.
+      skipBranchLengthScaling
+        Make a dendrogram instead of a phylogram.
+  
+  d3.phylogram.buildRadial(selector, nodes, options)
+    Creates a radial dendrogram.
+    Options: same as build, but without diagonal, skipTicks, and 
+      skipBranchLengthScaling
+  
+  d3.phylogram.rightAngleDiagonal()
+    Similar to d3.diagonal except it create an orthogonal crook instead of a
+    smooth Bezier curve.
+    
+  d3.phylogram.radialRightAngleDiagonal()
+    d3.phylogram.rightAngleDiagonal for radial layouts.
+*/
+
+if (!d3) { throw "d3 wasn't included!"};
+(function() {
+  d3.phylogram = {}
+  d3.phylogram.rightAngleDiagonal = function() {
+    var projection = function(d) { return [d.y, d.x]; }
+    
+    var path = function(pathData) {
+      return "M" + pathData[0] + ' ' + pathData[1] + " " + pathData[2];
+    }
+    
+    function diagonal(diagonalPath, i) {
+      var source = diagonalPath.source,
+          target = diagonalPath.target,
+          midpointX = (source.x + target.x) / 2,
+          midpointY = (source.y + target.y) / 2,
+          pathData = [source, {x: target.x, y: source.y}, target];
+      pathData = pathData.map(projection);
+      return path(pathData)
+    }
+    
+    diagonal.projection = function(x) {
+      if (!arguments.length) return projection;
+      projection = x;
+      return diagonal;
+    };
+    
+    diagonal.path = function(x) {
+      if (!arguments.length) return path;
+      path = x;
+      return diagonal;
+    };
+    
+    return diagonal;
+  }
+  
+  d3.phylogram.radialRightAngleDiagonal = function() {
+    return d3.phylogram.rightAngleDiagonal()
+      .path(function(pathData) {
+        var src = pathData[0],
+            mid = pathData[1],
+            dst = pathData[2],
+            radius = Math.sqrt(src[0]*src[0] + src[1]*src[1]),
+            srcAngle = d3.phylogram.coordinateToAngle(src, radius),
+            midAngle = d3.phylogram.coordinateToAngle(mid, radius),
+            clockwise = Math.abs(midAngle - srcAngle) > Math.PI ? midAngle <= srcAngle : midAngle > srcAngle,
+            rotation = 0,
+            largeArc = 0,
+            sweep = clockwise ? 0 : 1;
+        return 'M' + src + ' ' +
+          "A" + [radius,radius] + ' ' + rotation + ' ' + largeArc+','+sweep + ' ' + mid +
+          'L' + dst;
+      })
+      .projection(function(d) {
+        var r = d.y, a = (d.x - 90) / 180 * Math.PI;
+        return [r * Math.cos(a), r * Math.sin(a)];
+      })
+  }
+  
+  // Convert XY and radius to angle of a circle centered at 0,0
+  d3.phylogram.coordinateToAngle = function(coord, radius) {
+    var wholeAngle = 2 * Math.PI,
+        quarterAngle = wholeAngle / 4
+    
+    var coordQuad = coord[0] >= 0 ? (coord[1] >= 0 ? 1 : 2) : (coord[1] >= 0 ? 4 : 3),
+        coordBaseAngle = Math.abs(Math.asin(coord[1] / radius))
+    
+    // Since this is just based on the angle of the right triangle formed
+    // by the coordinate and the origin, each quad will have different 
+    // offsets
+    switch (coordQuad) {
+      case 1:
+        coordAngle = quarterAngle - coordBaseAngle
+        break
+      case 2:
+        coordAngle = quarterAngle + coordBaseAngle
+        break
+      case 3:
+        coordAngle = 2*quarterAngle + quarterAngle - coordBaseAngle
+        break
+      case 4:
+        coordAngle = 3*quarterAngle + coordBaseAngle
+    }
+    return coordAngle
+  }
+
+  function scaleBranchLengths(nodes, w) {
+    // Visit all nodes and adjust y pos width distance metric
+    var visitPreOrder = function(root, callback) {
+      callback(root)
+      if (root.children) {
+        for (var i = root.children.length - 1; i >= 0; i--){
+          visitPreOrder(root.children[i], callback);
+        };
+      }
+    }
+    visitPreOrder(nodes[0], function(node) {
+      node.rootDist = (node.parent ? node.parent.rootDist : 0) + (node.length || 0)
+    })
+    var rootDists = nodes.map(function(n) { return n.rootDist; });
+    var yscale = d3.scale.linear()
+      .domain([0, d3.max(rootDists)])
+      .range([0, w]);
+    visitPreOrder(nodes[0], function(node) {
+      node.y = yscale(node.rootDist)
+    })
+    return yscale
+  }
+  
+  d3.phylogram.build = function(selector, nodes, options) {
+    options = options || {}
+    var w = options.width || d3.select(selector).style('width') || d3.select(selector).attr('width'),
+        h = options.height || d3.select(selector).style('height') || d3.select(selector).attr('height'),
+        w = parseInt(w),
+        h = parseInt(h);
+    var fill = options.fill || function(d) {
+      return 'cyan';
+    };
+    var size = options.size || function(d) {
+      return 6;
+    }
+    var nodeMouseOver = options.nodeMouseOver || function(d) {};
+    var nodeMouseOut  = options.nodeMouseOut  || function(d) {};
+    var nodeMouseDown = options.nodeMouseDown || function(d) {};
+    
+    var tree = options.tree || d3.layout.cluster()
+      .size([h, w])
+      .sort(function(node) { return node.children ? node.children.length : -1; })
+      .children(options.children || function(node) {
+        return node.children;
+      });
+    var diagonal = options.diagonal || d3.phylogram.rightAngleDiagonal();
+    var vis = options.vis || d3.select(selector).append("svg:svg")
+        .attr("width", w + 300)
+        .attr("height", h + 30)
+        .append("svg:g")
+        .attr("transform", "translate(20, 20)");
+    var nodes = tree(nodes);
+    
+    if (options.skipBranchLengthScaling) {
+      var yscale = d3.scale.linear()
+        .domain([0, w])
+        .range([0, w]);
+    } 
+    else {
+      var yscale = scaleBranchLengths(nodes, w)
+    }
+    
+    if (!options.skipTicks) {
+      vis.selectAll('line')
+          .data(yscale.ticks(10))
+          .enter().append('svg:line')
+          .attr('y1', 0)
+          .attr('y2', h)
+          .attr('x1', yscale)
+          .attr('x2', yscale)
+          .attr("stroke", "#ddd");
+
+      vis.selectAll("text.rule")
+          .data(yscale.ticks(10))
+          .enter().append("svg:text")
+          .attr("class", "rule")
+          .attr("x", yscale)
+          .attr("y", 0)
+          .attr("dy", -3)
+          .attr("text-anchor", "middle")
+          .attr('font-size', '9px')
+          .attr('fill', 'grey')
+          .text(function(d) { return Math.round(d*100) / 100; });
+    }
+        
+    var link = vis.selectAll("path.link")
+        .data(tree.links(nodes))
+        .enter().append("svg:path")
+        .attr("class", "link")
+        .attr("d", diagonal)
+        .attr("fill", "none")
+        .attr("stroke", "#aaa")
+        .attr("stroke-width", "4px");
+        
+    var node = vis.selectAll("g.node")
+        .data(nodes)
+        .enter().append("svg:g")
+        .attr("class", function(n) {
+          if (n.children) {
+            if (n.depth == 0) {
+              return "root node"
+            } 
+            else {
+              return "inner node"
+            }
+          } 
+          else {
+            return "leaf node"
+          }
+        })
+        .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; })
+
+     // style the root node
+     vis.selectAll('g.root.node')
+      .append('svg:circle')
+      .on('click', nodeMouseDown)
+      .on('mouseover', nodeMouseOver)
+      .on('mouseout', nodeMouseOut)
+      .attr("r", size)
+      .attr('fill', 'dimgrey')
+      .attr('stroke', 'black')
+      .attr('stroke-width', '2px');
+
+    // style the leaf nodes and add js event handlers
+    vis.selectAll('g.leaf.node')
+      .on('click', nodeMouseDown)
+      .on('mouseover', nodeMouseOver)
+      .on('mouseout', nodeMouseOut)
+      .append("svg:circle")
+      .attr("r", size)
+      .attr('stroke', 'dimgrey')
+      .attr('fill', fill)
+      .attr('stroke-width', '2px');
+
+    vis.selectAll('g.inner.node')
+      .on('click', nodeMouseDown)
+      .on('mouseover', nodeMouseOver)
+      .on('mouseout', nodeMouseOut)
+      .append("svg:circle")
+      .attr("r", size)
+      .attr('stroke', 'dimgrey')
+      .attr('stroke-width', '2px')
+      .attr('fill', 'white');
+    
+    if (!options.skipLabels) {
+      vis.selectAll('g.inner.node')
+        .append("svg:text")
+          .attr("dx", -6)
+          .attr("dy", -6)
+          .attr("text-anchor", 'end')
+          .attr('font-size', '9px')
+          .attr('fill', 'black')
+        //.text(function(d) { return d.length.toFixed(4); }); // hide length
+
+      vis.selectAll('g.leaf.node').append("svg:text")
+        .attr("dx", 8)
+        .attr("dy", 3)
+        .attr("text-anchor", "start")
+        .attr('font-family', 'Helvetica Neue, Helvetica, sans-serif')
+        .attr('font-size', '10px')
+        .attr('fill', 'black')
+        .text(function(d) {
+          // return d.name + ' (' + d.length.toFixed(4) + ')'; // hide length
+          return d.name;
+         });
+    }
+    return {tree: tree, vis: vis}
+  }
+  
+  d3.phylogram.buildRadial = function(selector, nodes, options) {
+    options = options || {};
+    
+    var fill = options.fill || function(d) {
+      return 'cyan';
+    };
+    var size = options.size || function(d) {
+      return 6;
+    }
+    var nodeMouseOver = options.nodeMouseOver || function(d) {};
+    var nodeMouseOut = options.nodeMouseOut || function(d) {};
+    var nodeMouseDown = options.nodeMouseDown || function(d) {};
+    
+    var w = options.width || d3.select(selector).style('width') || d3.select(selector).attr('width'),
+        r = w / 2,
+        labelWidth = options.skipLabels ? 10 : options.labelWidth || 120;
+    
+    var vis = d3.select(selector).append("svg:svg")
+        .attr("width", r * 2)
+        .attr("height", r * 2)
+        .append("svg:g")
+        .attr("transform", "translate(" + r + "," + r + ")");
+        
+    var tree = d3.layout.tree()
+      .size([360, r - labelWidth])
+      .sort(function(node) { return node.children ? node.children.length : -1; })
+      .children(options.children || function(node) {
+        return node.children;
+      })
+      .separation(function(a, b) { return (a.parent == b.parent ? 1 : 2) / a.depth; });
+
+    var phylogram = d3.phylogram.build(selector, nodes, {
+      vis: vis,
+      tree: tree,
+      fill : fill,
+      size: size,
+      nodeMouseOver : nodeMouseOver,
+      nodeMouseOut : nodeMouseOut,
+      nodeMouseDown : nodeMouseDown,
+      skipBranchLengthScaling: true,
+      skipTicks: true,
+      skipLabels: options.skipLabels,
+      diagonal: d3.phylogram.radialRightAngleDiagonal()
+    })
+    vis.selectAll('g.node')
+      .attr("transform", function(d) { return "rotate(" + (d.x - 90) + ")translate(" + d.y + ")"; })
+    
+    if (!options.skipLabels) {
+      vis.selectAll('g.leaf.node text')
+        .attr("dx", function(d) { return d.x < 180 ? 8 : -8; })
+        .attr("dy", ".31em")
+        .attr("text-anchor", function(d) { return d.x < 180 ? "start" : "end"; })
+        .attr("transform", function(d) { return d.x < 180 ? null : "rotate(180)"; })
+        .attr('font-family', 'Helvetica Neue, Helvetica, sans-serif')
+        .attr('font-size', '10px')
+        .attr('fill', 'black')
+        .text(function(d) {
+          return d.name;
+        });
+
+      vis.selectAll('g.inner.node text')
+        .attr("dx", function(d) { return d.x < 180 ? -6 : 6; })
+        .attr("text-anchor", function(d) { return d.x < 180 ? "end" : "start"; })
+        .attr("transform", function(d) { return d.x < 180 ? null : "rotate(180)"; });
+    }
+    
+    return {tree: tree, vis: vis}
+  }
+}());

+ 130 - 0
tripal_phylogeny/theme/js/tripal_phylogeny.js

@@ -0,0 +1,130 @@
+/* phylotree d3js graphs */
+
+(function ($) {
+
+  var height = 0; // will be dynamically sized
+
+  $(document).ready( function () {
+
+    // Callback function to determine node size.
+    var nodeSize = function(d) {
+      var size;
+      if (d.cvterm_name == "phylo_root") {
+        size = treeOptions['root_node_size']; 
+      }
+      if (d.cvterm_name == "phylo_interior") {
+        size = treeOptions['interior_node_size']; 
+      }
+      if (d.cvterm_name == "phylo_leaf") {
+        size = treeOptions['leaf_node_size']; 
+      }
+      return size;
+    }
+
+    // Callback function to determine the node color.
+    var organismColor = function(d) {
+      var color = null;
+      if (d.genus) {
+        color = organismColors[d.genus + ' ' + d.species];
+      }
+      if (color) { 
+        return color; 
+      }
+      else { 
+        return 'grey'; 
+      }
+    };
+
+    // Callback for mouseover event on graph node d.
+    var nodeMouseOver = function(d) {
+      var el = $(this);
+      el.attr('cursor', 'pointer');
+      var circle = el.find('circle');
+      // highlight in yellow no matter if leaf or interior node
+      circle.attr('fill', 'yellow');
+      if(!d.children) {
+        // only leaf nodes have descriptive text
+        var txt = el.find('text');
+        txt.attr('font-weight', 'bold');
+      }
+    };
+    
+    // Callback for mouseout event on graph node d.
+    var nodeMouseOut = function(d) {
+      var el = $(this);
+      el.attr('cursor', 'default');
+      var circle = el.find('circle');
+      if(!d.children) {
+        // restore the color based on organism id for leaf nodes
+        circle.attr('fill', organismColor(d));
+        var txt = el.find('text');
+        txt.attr('font-weight', 'normal');
+      }
+      else {
+        // restore interior nodes to white
+        circle.attr('fill', 'white');
+      }
+    };
+    
+    // Callback for mousedown/click event on graph node d.
+    var nodeMouseDown = function(d) {
+      var el = $(this);
+      var title = (! d.children ) ? d.name : 'interior node ' + d.phylonode_id;
+
+      if(d.children) {
+        // interior node
+        if(d.phylonode_id) {
+        }
+        else {
+          // this shouldn't happen but ok
+        }
+      }
+      else {
+        // If this node is not associated with a feature but it has an 
+        // organism node then this is a taxonomic node and we want to
+        // link it to the organism page.
+        if (!d.feature_id && d.organism_node_id) {
+          window.location.replace(baseurl + '/node/' + d.organism_node_id);
+        }
+        // leaf node
+      }
+    };
+
+    // AJAX function for retrieving the tree data.
+    $.getJSON(phylotreeDataURL, function(treeData) {
+      displayData(treeData);
+      $('.phylogram-ajax-loader').hide();
+    });
+
+    // Creates the tree using the d3.phylogram.js library.
+    function displayData(treeData) {
+      height = graphHeight(treeData);
+      d3.phylogram.build('#phylogram', treeData, {
+        'width' : treeOptions['phylogram_width'],
+        'height' : height,
+        'fill' : organismColor,
+        'size' : nodeSize,
+        'nodeMouseOver' : nodeMouseOver,
+        'nodeMouseOut' : nodeMouseOut,
+        'nodeMouseDown' : nodeMouseDown,
+        'skipTicks' : treeOptions['skipTicks']
+      });
+    }
+
+    /* graphHeight() generate graph height based on leaf nodes */
+    function graphHeight(data) {
+      function countLeafNodes(node) {
+        if(! node.children) {
+          return 1;
+        }
+        var ct = 0;
+        node.children.forEach( function(child) {
+          ct+= countLeafNodes(child);
+        });
+        return ct;
+      }
+      var leafNodeCt = countLeafNodes(data);
+      return 22 * leafNodeCt;
+    }
+  });
+})(jQuery);

+ 80 - 0
tripal_phylogeny/theme/templates/tripal_phylogeny_analysis.tpl.php

@@ -0,0 +1,80 @@
+<?php
+$node = $variables['node'];
+$phylotree = $node->phylotree;
+
+if ($phylotree->analysis_id) {
+
+  // the $headers array is an array of fields to use as the colum headers.
+  // additional documentation can be found here
+  // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+  $header = array(
+    'Name',
+    'Description',
+    array(
+      'data' => 'Metadata',
+      'width' => '50%',
+    ),
+  );
+
+  // the $rows array contains an array of rows where each row is an array
+  // of values for each column of the table in that row.  Additional documentation
+  // can be found here:
+  // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+  $rows = array();
+
+  $analysis = $phylotree->analysis_id;
+  if ($analysis) {
+    $analysis = chado_expand_var($analysis, 'field', 'analysis.description');
+    // Source row
+    $source = '';
+    if($analysis->sourceuri){
+      $source = "<a href=\"$analysis->sourceuri\">$analysis->sourcename</a>";
+    }
+    else {
+      $source = $analysis->sourcename;
+    }
+    if($analysis->sourceversion){
+      $source = " (" . $analysis->sourceversion . ")";
+    }
+
+    $software = $analysis->program;
+    if($analysis->programversion != 'n/a'){
+      $software .=  " (" . $analysis->programversion . ")";
+    }
+    if($analysis->algorithm){
+      $software .= ". " . $analysis->algorithm;
+    }
+    $date = preg_replace("/^(\d+-\d+-\d+) .*/","$1", $analysis->timeexecuted);
+    $metadata = "
+      <dl class=\"tripal-dl\">
+        <dt>Method</dt> <dd>: $software</dd>
+        <dt>Source</dt> <dd>: $source</dd>
+        <dt>Date</dt>   <dd>: $date</dd>
+      </dl>
+    ";
+
+    $analysis_name = $analysis->name;
+    if (property_exists($analysis, 'nid')) {
+      $analysis_name = l($analysis_name, "node/" . $analysis->nid);
+    }
+    $rows[] = array($analysis_name, $analysis->description, $metadata);
+  }
+
+  // the $table array contains the headers and rows array as well as other
+  // options for controlling the display of the table.  Additional
+  // documentation can be found here:
+  // https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+  $table = array(
+    'header' => $header,
+    'rows' => $rows,
+    'attributes' => array(
+      'id' => 'tripal_phylogeny-table-analysis',
+      'class' => 'tripal-data-table'
+    ),
+    'sticky' => FALSE,
+    'caption' => '',
+    'colgroups' => array(),
+    'empty' => t('This tree is not associated with an analysis'),
+  );
+  print theme_table($table);
+}

+ 72 - 0
tripal_phylogeny/theme/templates/tripal_phylogeny_base.tpl.php

@@ -0,0 +1,72 @@
+<?php
+$phylotree = $variables['node']->phylotree;
+$phylotree = chado_expand_var($phylotree,'field','phylotree.comment'); ?>
+
+<div class="tripal_phylogeny-data-block-desc tripal-data-block-desc"> <?php
+
+// the $headers array is an array of fields to use as the colum headers.
+// additional documentation can be found here
+// https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+// This table for the analysis has a vertical header (down the first column)
+// so we do not provide headers here, but specify them in the $rows array below.
+$headers = array();
+
+// the $rows array contains an array of rows where each row is an array
+// of values for each column of the table in that row.  Additional documentation
+// can be found here:
+// https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+$rows = array();
+
+// Name row
+$rows[] = array(
+  array(
+    'data' => 'Tree Name',
+    'header' => TRUE,
+  ),
+  $phylotree->name
+);
+
+$leaf_type = 'N/A';
+if ($phylotree->type_id) {
+  $leaf_type = $phylotree->type_id->name;
+}
+$rows[] = array(
+  array(
+    'data' => 'Leaf type',
+    'header' => TRUE,
+  ),
+  $leaf_type
+);
+
+$description = 'N/A';
+if ($phylotree->comment) {
+  $description = $phylotree->comment;
+}
+$rows[] = array(
+  array(
+    'data' => 'Description',
+    'header' => TRUE,
+  ),
+  $description
+);
+
+// the $table array contains the headers and rows array as well as other
+// options for controlling the display of the table.  Additional
+// documentation can be found here:
+// https://api.drupal.org/api/drupal/includes%21theme.inc/function/theme_table/7
+$table = array(
+  'header' => $headers,
+  'rows' => $rows,
+  'attributes' => array(
+    'id' => 'tripal_phylogeny-table-base',
+    'class' => 'tripal-data-table'
+  ),
+  'sticky' => FALSE,
+  'caption' => '',
+  'colgroups' => array(),
+  'empty' => '',
+);
+
+// once we have our table array structure defined, we call Drupal's theme_table()
+// function to generate the table.
+print theme_table($table);

+ 11 - 0
tripal_phylogeny/theme/templates/tripal_phylogeny_help.tpl.php

@@ -0,0 +1,11 @@
+<h3>Module Description:</h3>
+
+<p>
+  The Tripal Phylotree module is an interface for the Chado Phylotree
+module for visualizing and browsing phylogenetic gene trees.
+</p>
+
+<h3>Setup Instructions:</h3>
+TODO
+<h3>Features of this Module:</h3>
+TODO

Неке датотеке нису приказане због велике количине промена