Răsfoiți Sursa

Have basic Sort field working :) -Sorting for aggregates if postgreSQL 9.0+

Lacey Sanderson 13 ani în urmă
părinte
comite
e245332e41

+ 50 - 0
base/tripal_core/views/handlers/chado_views_handler_sort.inc

@@ -0,0 +1,50 @@
+<?php
+
+class chado_views_handler_sort extends views_handler_sort {
+
+  /**
+   * Defines the options form (form available to admin when they add a field to a view)
+   */
+  function options_form(&$form, &$form_state) {
+    
+    $form['msg'] = array(
+      '#type' => 'item',
+      '#value' => '<b>Sorting of aggregated fields only works for PostgreSQL 9.0+. This is due to lack of support at the database level. With lower postgreSQL versions, no sorting is applied.</b>'
+    );
+
+    parent::options_form($form, $form_state);
+  }
+  
+  /**
+   * Adds the sort to the query only if the field isn't aggregated
+   * If the field is aggregated then the sort has to be applied at the join handler level
+   */
+  function query () {
+    
+    // Determine if the current field is part of an aggregated table
+    $table = $this->query->get_table_info($this->table);
+    if (preg_match('/aggregator/',$table['join']->definition['handler'])) {
+      $this->aggregated = TRUE;
+    } else {
+      $this->aggregated = FALSE;
+    }
+    
+    // One day when the aggregated sort will work (ie: Postgresql 9.0+)
+    // it will need to be applied in join handler
+    // thus tell join handler about the sort
+    $table['join']->sort[] = array(
+      'table' => $table['alias'],
+      'field' => $this->options['field'],
+      'order' => $this->options['order']
+    );
+    
+    
+    // if not then add the sort
+    if (!$this->aggregated) {
+      $this->ensure_my_table();
+      $this->query->add_orderby($this->table_alias, $this->real_field, $this->options['order']);
+    }
+    
+  }
+  
+}

+ 29 - 2
base/tripal_core/views/handlers/views_handler_join_chado_aggregator.inc

@@ -21,6 +21,17 @@ class views_handler_join_chado_aggregator extends views_join {
   // the call to constructors upstream where appropriate.
   function construct($table = NULL, $left_table = NULL, $left_field = NULL, $field = NULL, $extra = array(), $type = 'LEFT', $added = NULL) {
     parent::construct($table, $left_table, $left_field, $field, $extra, $type);
+    
+    // Determine the postgresql version
+    $postgresql_version = pg_version();
+    $this->postgresql_version = $postgresql_version['client'];
+
+    // If version is 9.0+ then indicate
+    // Needed to apply sorting for aggregated fields
+    if (intval($postgresql_version['client']) >= 9) {
+      $this->postgresql_9up = TRUE;
+    }
+
   }
 
   /**
@@ -51,6 +62,12 @@ class views_handler_join_chado_aggregator extends views_join {
       } 
     }
     
+    // Determine Order BY's for aggregates
+    $order_by = array();
+    foreach ($this->sort as $s) {
+      $order_by[] = $s['table'].'.'.$s['field'].' '.$s['order'];
+    }
+    
     
     // Fields to be selected
     foreach ($select_fields as $table => $table_fields) {
@@ -61,7 +78,12 @@ class views_handler_join_chado_aggregator extends views_join {
         }
         
         if ($fname != $this->definition['field']) {
-          $fields[] = 'array_agg('.$table.'.'.$fname.') as '.$alias.$fname;
+          // Add sort to aggregate field if postgreSQL 9.0+
+          if ($this->postgresql_9up && !empty($order_by)) {
+            $fields[] = 'array_agg('.$table.'.'.$fname.' ORDER BY '.implode(',',$order_by).') as '.$alias.$fname;
+          } else {
+            $fields[] = 'array_agg('.$table.'.'.$fname.') as '.$alias.$fname;
+          }
           $composite_field_parts[] = "'".$alias.$fname."::' ||".$table.'.'.$fname;
         } else {
           $fields[] = $fname;
@@ -72,7 +94,12 @@ class views_handler_join_chado_aggregator extends views_join {
     
     // composite field 
     // (combines all other fields before aggregating)
-    $composite_field = "array_agg('{'||".implode(" || ',' || ",$composite_field_parts)."||'}') as all";
+    // Add sort to aggregate field if postgreSQL 9.0+
+    if ($this->postgresql_9up && !empty($order_by)) {
+      $composite_field = "array_agg('{'||".implode(" || ',' || ",$composite_field_parts)."||'}' ORDER BY ".implode(',',$order_by).") as all";
+    } else {
+      $composite_field = "array_agg('{'||".implode(" || ',' || ",$composite_field_parts)."||'}') as all";
+    }
     $fields[] = $composite_field;
     
     // SQL to use in the join