Quellcode durchsuchen

Publish: switched to generic cache var and cached bundle and term for setAlias and setTitle.

Lacey Sanderson vor 6 Jahren
Ursprung
Commit
45b6ce92cd

+ 15 - 9
tripal/includes/TripalEntity.inc

@@ -18,17 +18,23 @@ class TripalEntity extends Entity {
   /**
    * Permanently saves the entity.
    *
-   * @param DatabaseTransaction $transaction
-   *    (OPTIONAL) Allows you to pass in your current transaction to save nested transaction overhead.
-   * @param boolean $clear_cached_fields
-   *    (OPTIONAL) Clearing cached fields is NECESSARY. IF you choose to set this to false then YOU
-   *    must clear the cache yourself using cache_clear_all('field:TripalEntity:[entity_id]', 'cache_field', TRUE).
-   *    The only known reason to set this to FALSE is to clear the cache in bulk for perfomance reasons.
-   *
+   * @param $cache
+   *   This array is used to store objects you want to cache for performance reasons,
+   *   as well as, cache related options. The following are supported:
+   *   - DatabaseTransaction $transaction
+   *       Allows you to pass in your current transaction to save nested transaction overhead.
+   *   - boolean $clear_cached_fields
+   *       Clearing cached fields is NECESSARY. IF you choose to set this to false then YOU
+   *       must clear the cache yourself using cache_clear_all('field:TripalEntity:[entity_id]', 'cache_field', TRUE).
+   *       The only known reason to set this to FALSE is to clear the cache in bulk for perfomance reasons.
+   *   - TripalBundle $bundle
+   *       The bundle for the current entity.
+   *   - TripalTerm $term
+   *       The term for the current entity.
    * @see entity_save()
    */
-  public function save(DatabaseTransaction $transaction = NULL, $clear_cached_fields = TRUE) {
-    return entity_get_controller($this->entityType)->save($this, $transaction, $clear_cached_fields);
+  public function save($cache = array()) {
+    return entity_get_controller($this->entityType)->save($this, $cache);
   }
 
 }

+ 65 - 40
tripal/includes/TripalEntityController.inc

@@ -109,10 +109,20 @@ class TripalEntityController extends EntityAPIController {
    *   The title to use. It can contain tokens the correspond to field values.
    *   Token should be be compatible with those returned by
    *   tripal_get_entity_tokens().
+   * @param $cache
+   *   This array is used to store objects you want to cache for performance reasons,
+   *   as well as, cache related options. The following are supported:
+   *   - TripalBundle $bundle
+   *       The bundle for the current entity.
    */
-  public function setTitle($entity, $title = NULL) {
+  public function setTitle($entity, $title = NULL, $cache = array()) {
 
-    $bundle = tripal_load_bundle_entity(array('name' => $entity->bundle));
+    if (isset($cache['bundle'])) {
+      $bundle = $cache['bundle'];
+    }
+    else {
+      $bundle = tripal_load_bundle_entity(array('name' => $entity->bundle));
+    }
 
     // If no title was supplied then we should try to generate one using the
     // default format set by admins.
@@ -140,18 +150,30 @@ class TripalEntityController extends EntityAPIController {
    *   The alias to use. It can contain tokens the correspond to field values.
    *   Token should be be compatible with those returned by
    *   tripal_get_entity_tokens().
+   * @param $cache
+   *   This array is used to store objects you want to cache for performance reasons,
+   *   as well as, cache related options. The following are supported:
+   *   - TripalBundle $bundle
+   *       The bundle for the current entity.
+   *   - TripalTerm $term
+   *       The term for the current entity.
    */
-  public function setAlias($entity, $alias = NULL) {
+  public function setAlias($entity, $alias = NULL, $cache = array()) {
     $source_url = "bio_data/$entity->id";
 
     // If no alias was supplied then we should try to generate one using the
     // default format set by admins.
     if (!$alias) {
 
-      // Load the TripalBundle entity for this TripalEntity.
+      // Load the TripalBundle entity for this TripalEntity (if it's not cached).
       // First get the format for the url alias based on the bundle of the entity.
       // Then replace all the tokens with values from the entity fields.
-      $bundle_entity = tripal_load_bundle_entity(array('name' => $entity->bundle));
+      if (isset($cache['bundle'])) {
+        $bundle_entity = $cache['bundle'];
+      }
+      else {
+        $bundle_entity = tripal_load_bundle_entity(array('name' => $entity->bundle));
+      }
       $alias = tripal_get_bundle_variable('url_format', $bundle_entity->id);
       $alias = tripal_replace_entity_tokens($alias, $entity, $bundle_entity);
     }
@@ -163,7 +185,7 @@ class TripalEntityController extends EntityAPIController {
       // Load the term for this TripalEntity. Set a default based on the term
       // name and entity id. Then replace all the tokens with values from
       // the entity fields.
-      $term = entity_load('TripalTerm', array('id' => $entity->term_id));
+      $term = (isset($cache['term'])) ? $cache['term'] : entity_load('TripalTerm', array('id' => $entity->term_id));
       $term = reset($term);
       $alias = str_replace(' ', '', $term->name) . '/[TripalEntity__entity_id]';
       $alias = tripal_replace_entity_tokens($alias, $entity, $bundle_entity);
@@ -173,7 +195,12 @@ class TripalEntityController extends EntityAPIController {
     // this TripalEntity. Then replace all the tokens with values from the
     // entity fields.
     if($alias && (preg_match_all("/\[[^\]]*\]/", $alias, $bundle_tokens))) {
-      $bundle_entity = tripal_load_bundle_entity(array('name' => $entity->bundle));
+      if (isset($cache['bundle'])) {
+        $bundle_entity = $cache['bundle'];
+      }
+      else {
+        $bundle_entity = tripal_load_bundle_entity(array('name' => $entity->bundle));
+      }
       $alias = tripal_replace_entity_tokens($alias, $entity, $bundle_entity);
     }
 
@@ -256,7 +283,12 @@ class TripalEntityController extends EntityAPIController {
       // already assigned this alias to this entity in a previous save.
       elseif ($num_aliases == 1) {
 
-        $bundle_entity = tripal_load_bundle_entity(array('name' => $entity->bundle));
+        if (isset($cache['bundle'])) {
+          $bundle_entity = $cache['bundle'];
+        }
+        else {
+          $bundle_entity = tripal_load_bundle_entity(array('name' => $entity->bundle));
+        }
 
         // Check to see if the single alias is for the same entity and if not
         // warn the admin that the alias is already used (ie: not unique?)
@@ -284,7 +316,12 @@ class TripalEntityController extends EntityAPIController {
       // If there are more then one alias' matching what we generated then there's
       // a real problem and we need to warn the administrator.
       else {
-        $bundle_entity = tripal_load_bundle_entity(array('name' => $entity->bundle));
+        if (isset($cache['bundle'])) {
+          $bundle_entity = $cache['bundle'];
+        }
+        else {
+          $bundle_entity = tripal_load_bundle_entity(array('name' => $entity->bundle));
+        }
 
         $aliases = db_query('SELECT source FROM {url_alias} WHERE alias=:alias',
           array(':alias' => $alias))->fetchAll();
@@ -317,29 +354,33 @@ class TripalEntityController extends EntityAPIController {
    *
    * @param $entity
    *   A TripalEntity object to save.
-   * @param $transaction
-   *   If you have a transaction open, you can pass it through to avoid the overhead of
-   *   creating nested transactions.
-   * @param $clear_cached_fields
-   *   Clearing cached fields is NECESSARY. IF you choose to set this to false then YOU
-   *   must clear the cache yourself using cache_clear_all('field:TripalEntity:[entity_id]', 'cache_field', TRUE).
-   *   The only known reason to set this to FALSE is to clear the cache in bulk for perfomance reasons.
+   * @param $cache
+   *   This array is used to store objects you want to cache for performance reasons,
+   *   as well as, cache related options. The following are supported:
+   *   - DatabaseTransaction $transaction
+   *       Allows you to pass in your current transaction to save nested transaction overhead.
+   *   - boolean $clear_cached_fields
+   *       Clearing cached fields is NECESSARY. IF you choose to set this to false then YOU
+   *       must clear the cache yourself using cache_clear_all('field:TripalEntity:[entity_id]', 'cache_field', TRUE).
+   *       The only known reason to set this to FALSE is to clear the cache in bulk for perfomance reasons.
+   *   - TripalBundle $bundle
+   *       The bundle for the current entity.
+   *   - TripalTerm $term
+   *       The term for the current entity.
    *
    * @return
    *   The saved entity object with updated properties.
    */
-  public function save($entity, DatabaseTransaction $transaction = NULL, $clear_cached_fields = TRUE) {
+  public function save($entity, $cache = array()) {
     global $user;
     $pkeys = array();
 
-    // @performance remove after development
-    // @performance $started_at = microtime(true);
+    if (!isset($cache['clear_cached_fields'])) $cache['clear_cached_fields'] = TRUE;
 
     $changed_date = time();
     $create_date = $changed_date;
     if (property_exists($entity, 'created')) {
       if (!is_numeric($entity->created)) {
-        print "IM CREATING A DATE!\n";
         $temp = new DateTime($entity->created);
         $create_date = $temp->getTimestamp();
       }
@@ -352,7 +393,7 @@ class TripalEntityController extends EntityAPIController {
       }
     }
 
-    $transaction = isset($transaction) ? $transaction : db_transaction();
+    $transaction = isset($cache['transaction']) ? $cache['transaction'] : db_transaction();
     try {
       // If our entity has no id, then we need to give it a
       // time of creation.
@@ -371,8 +412,6 @@ class TripalEntityController extends EntityAPIController {
       // Invoke hook_entity_presave().
       module_invoke_all('entity_presave', $entity, $entity->type);
 
-      // @performance print '      - After entity_presave :' . number_format(microtime(true) - $started_at, 4) . "s.\n";
-
       // Write out the entity record.
       $record = array(
         'term_id'   => $entity->term_id,
@@ -395,8 +434,6 @@ class TripalEntityController extends EntityAPIController {
         $entity->id = $record['id'];
       }
 
-      // @performance print '      - After drupal_write_record :' . number_format(microtime(true) - $started_at, 4) . "s.\n";
-
       // Now we need to either insert or update the fields which are
       // attached to this entity. We use the same primary_keys logic
       // to determine whether to update or insert, and which hook we
@@ -404,7 +441,6 @@ class TripalEntityController extends EntityAPIController {
       // This is because a field may have default values and if so, those fields
       // will be attached and the storage backend may then try to insert
       // fields which should not be inserted because they already exist.
-      // @performance print "      - Invocation: $invocation.\n";
       if ($invocation == 'entity_insert') {
         field_attach_insert('TripalEntity', $entity);
       }
@@ -413,27 +449,18 @@ class TripalEntityController extends EntityAPIController {
       }
 
       // Set the title for this entity.
-      $this->setTitle($entity);
-
-      // @performance print '      - After setTitle :' . number_format(microtime(true) - $started_at, 4) . "s.\n";
+      $this->setTitle($entity, NULL, $cache);
 
       // Set the path/url alias for this entity.
-      $this->setAlias($entity);
-
-      // @performance print '      - After setAlias :' . number_format(microtime(true) - $started_at, 4) . "s.\n";
+      $this->setAlias($entity, NULL, $cache);
 
       // Invoke either hook_entity_update() or hook_entity_insert().
       module_invoke_all('entity_postsave', $entity, $entity->type);
-
-      // @performance print '      - After entity_postsave :' . number_format(microtime(true) - $started_at, 4) . "s.\n";
-
       module_invoke_all($invocation, $entity, $entity->type);
 
-      // @performance print "      - After $invocation :" . number_format(microtime(true) - $started_at, 4) . "s.\n";
-
       // Clear any cache entries for this entity so it can be reloaded using
       // the values that were just saved.
-      if ($clear_cached_fields) {
+      if ($cache['clear_cached_fields']) {
         $cid = 'field:TripalEntity:' . $entity->id;
         cache_clear_all($cid, 'cache_field', TRUE);
       }
@@ -446,8 +473,6 @@ class TripalEntityController extends EntityAPIController {
       drupal_set_message("Could not save the entity: " . $e->getMessage(), "error");
       return FALSE;
     }
-
-
   }
 
   /**

+ 12 - 37
tripal_chado/api/tripal_chado.api.inc

@@ -55,6 +55,9 @@ function chado_publish_records($values, $job_id = NULL) {
     $report_progress = TRUE;
   }
 
+  // Start an array for caching objects to save performance.
+  $cache = array();
+
   // Make sure we have the required options: bundle_name.
   if (!array_key_exists('bundle_name', $values) or !$values['bundle_name']) {
     tripal_report_error('tripal_chado', TRIPAL_ERROR,
@@ -73,11 +76,10 @@ function chado_publish_records($values, $job_id = NULL) {
   // to be processed per chunk is set here:
   $chunk_size = 500;
 
-  // @performance remove after development: 0.00059294700622559s
-
   // Load the bundle entity so we can get information about which Chado
   // table/field this entity belongs to.
   $bundle = tripal_load_bundle_entity(array('name' => $bundle_name));
+  $cache['bundle'] = $bundle;
   if (!$bundle) {
     tripal_report_error('tripal_chado', TRIPAL_ERROR,
         "Unknown bundle. Could not publish record: @error",
@@ -86,8 +88,6 @@ function chado_publish_records($values, $job_id = NULL) {
   }
   $chado_entity_table = chado_get_bundle_entity_table($bundle);
 
-  // @performance remove after development: 0.05065393447876s
-
   // Get the mapping of the bio data type to the Chado table.
   $chado_bundle = db_select('chado_bundle', 'cb')
     ->fields('cb')
@@ -100,20 +100,20 @@ function chado_publish_records($values, $job_id = NULL) {
     return FALSE;
   }
 
+  // Load the term for use in setting the alias for each entity created.
+  $term = entity_load('TripalTerm', array('id' => $entity->term_id));
+  $cache['term'] = $term;
+
   $table = $chado_bundle->data_table;
   $type_column = $chado_bundle->type_column;
   $type_linker_table = $chado_bundle->type_linker_table;
   $cvterm_id  = $chado_bundle->type_id;
   $type_value = $chado_bundle->type_value;
 
-  // @performance remove after development:0.051163911819458s
-
   // Get the table information for the Chado table.
   $table_schema = chado_get_schema($table);
   $pkey_field = $table_schema['primary key'][0];
 
-  // @performance remove after development:0.05134105682373s
-
   // Construct the SQL for identifying which records should be published.
   // @performance find a way to optimize this?
   $args = array();
@@ -198,8 +198,6 @@ function chado_publish_records($values, $job_id = NULL) {
     }
   }
 
-  // @performance remove after development:0.060441970825195s
-
   // First get the count
   // @performance optimize, estimate or remove this. It's only used for reporting progress on the command-line.
   $sql = "SELECT count(*) as num_records " . $from . $where;
@@ -207,9 +205,6 @@ function chado_publish_records($values, $job_id = NULL) {
   $count = $result->fetchField();
   print "\nThere are $count records to publish.\n";
 
-  // @performance remove after development:0.25212502479553s
-  // @performance print 'Count amount to do :' . (microtime(true) - $started_at) . "s.\n";
-
   print "\nNOTE: publishing records is performed using database transactions. If the job fails\n" .
           "or is terminated prematurely then the current set of $chunk_size is rolled back with\n" .
           "no changes to the database. Simply re-run the publishing job to publish any remaining\n".
@@ -246,23 +241,18 @@ function chado_publish_records($values, $job_id = NULL) {
     // transactions. A better albeit more complicated approach might be to break the job into
     // chunks where each one is a single transaction.
     $transaction = db_transaction();
+    $cache['transaction'] = $transaction;
 
     try {
       $i = 0;
       while($record = $records->fetchObject()) {
 
-        // @performance remove after development
-        // @performance print 'Start current entity :' . number_format(microtime(true) - $started_at, 4) . "s.\n";
-
         // First save the tripal_entity record.
         // @performace This is likely a bottleneck. Too bad we can't create
         // multiple entities at once... sort of like the copy method.
         $record_id = $record->record_id;
         $ec = entity_get_controller('TripalEntity');
 
-        // @performance remove after development
-        // @performance print '  - After get controller :' . number_format(microtime(true) - $started_at, 4) . "s.\n";
-
         $entity = $ec->create(array(
           'bundle' => $bundle_name,
           'term_id' => $bundle->term_id,
@@ -275,23 +265,15 @@ function chado_publish_records($values, $job_id = NULL) {
           'bundle_object' => $bundle,
         ));
 
-        // @performance remove after development
-        // @performance print '  - After tripal_chado_entity_create() :' . number_format(microtime(true) - $started_at, 4) . "s.\n";
-
         // We pass in the transaction and tell save not to clear the field cache for
         // for performance reasons. We will clear the field cache in bulk below.
         // @todo clear the field cache in bulk below ;-p
-        $entity = $entity->save($transaction, FALSE);
+        $cache['clear_cached_fields'] = FALSE;
+        $entity = $entity->save($cache);
         if (!$entity) {
           throw new Exception('Could not create entity.');
         }
 
-        // @performance remove after development
-        // @performance print '  - After entity save :' . number_format(microtime(true) - $started_at, 4) . "s.\n";
-
-          // @performance remove after development: this takes 0.2-0.3s.
-          //print 'Create entity itself :' . (microtime(true) - $started_at) . "s.\n";
-
         // Next save the chado entity record.
         $entity_record = array(
           'entity_id' => $entity->id,
@@ -310,9 +292,6 @@ function chado_publish_records($values, $job_id = NULL) {
           throw new Exception('Could not create mapping of entity to Chado record.');
         }
 
-        // @performance remove after development: this takes <0.001s.
-        // @performance print '  - Relate back to chado :' . number_format(microtime(true) - $started_at,4) . "s.\n";
-
         $i++;
         $total_published++;
       }
@@ -334,11 +313,7 @@ function chado_publish_records($values, $job_id = NULL) {
     unset($transaction);
   }
 
-  drupal_set_message("Succesfully published $i " . $bundle->label . " record(s).");
-
-  // @performance remove after development
-  // @performance print 'Complete! Runtime:' . number_format(microtime(true) - $started_at) . " seconds.\n";
-
+  drupal_set_message("Succesfully published $total_published " . $bundle->label . " record(s).");
   return TRUE;
 }