← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 9387: Analytics, testing

 

------------------------------------------------------------
revno: 9387
committer: Lars Helge Øverland <larshelge@xxxxxxxxx>
branch nick: dhis2
timestamp: Fri 2012-12-21 15:12:04 +0100
message:
  Analytics, testing
modified:
  dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/DataQueryParams.java
  dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultQueryPlanner.java
  dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/analytics/data/QueryPlannerTest.java
  dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/PaginatedList.java
  dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/AnalyticsController.java


--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk

Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== modified file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/DataQueryParams.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/DataQueryParams.java	2012-12-21 12:59:39 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/DataQueryParams.java	2012-12-21 14:12:04 +0000
@@ -145,11 +145,24 @@
         dimensions.put( dimension, values );
     }
     
+    /**
+     * Returns the dimensions which are part of dimensions and filters. If any
+     * such dimensions exist this object is in an illegal state.
+     */
     public Collection<String> dimensionsAsFilters()
     {
         return CollectionUtils.intersection( dimensions.keySet(), filters.keySet() );
     }
     
+    /**
+     * Indicates whether periods are present as a dimension or as a filter. If
+     * not this object is in an illegal state.
+     */
+    public boolean hasPeriods()
+    {
+        return dimensions.containsKey( PERIOD_DIM_ID ) || filters.containsKey( PERIOD_DIM_ID );
+    }
+    
     @Override
     public int hashCode()
     {
@@ -291,7 +304,7 @@
     }
     
     // -------------------------------------------------------------------------
-    // Get and set helpers
+    // Get and set helpers for dimensions
     // -------------------------------------------------------------------------
   
     public List<String> getDatElements()
@@ -321,6 +334,40 @@
     
     public void setOrganisationUnits( List<String> organisationUnits )
     {
-        this.dimensions.put( ORGUNIT_DIM_ID, organisationUnits );
-    }
+        dimensions.put( ORGUNIT_DIM_ID, organisationUnits );
+    }
+    
+    // -------------------------------------------------------------------------
+    // Get and set helpers for filters
+    // -------------------------------------------------------------------------
+
+    public List<String> getFilterDatElements()
+    {
+        return filters.get( DATAELEMENT_DIM_ID );
+    }
+    
+    public void setFilterDataElements( List<String> dataElements )
+    {
+        filters.put( DATAELEMENT_DIM_ID, dataElements );
+    }
+    
+    public List<String> getFilterPeriods()
+    {
+        return filters.get( PERIOD_DIM_ID );
+    }
+    
+    public void setFilterPeriods( List<String> periods )
+    {
+        filters.put( PERIOD_DIM_ID, periods );
+    }
+    
+    public List<String> getFilterOrganisationUnits()
+    {
+        return filters.get( ORGUNIT_DIM_ID );
+    }
+    
+    public void setFilterOrganisationUnits( List<String> organisationUnits )
+    {
+        filters.put( ORGUNIT_DIM_ID, organisationUnits );
+    }    
 }

=== modified file 'dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultQueryPlanner.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultQueryPlanner.java	2012-12-21 12:59:39 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/data/DefaultQueryPlanner.java	2012-12-21 14:12:04 +0000
@@ -54,8 +54,9 @@
     
     public List<DataQueryParams> planQuery( DataQueryParams params, int optimalQueries )
     {
-        Assert.isTrue( params.getDimensions().size() > 0 );
+        Assert.isTrue( !params.getDimensions().isEmpty() );
         Assert.isTrue( params.dimensionsAsFilters().isEmpty() );
+        Assert.isTrue( params.hasPeriods() );
 
         // ---------------------------------------------------------------------
         // Group queries by partition, period type and organisation unit level
@@ -122,7 +123,7 @@
      */
     private List<DataQueryParams> splitByDimension( List<DataQueryParams> queries, String dimension, int optimalQueries )
     {
-        int pageNo = MathUtils.divideToCeil( optimalQueries, queries.size() );
+        int optimalForSubQuery = MathUtils.divideToCeil( optimalQueries, queries.size() );
         
         List<DataQueryParams> subQueries = new ArrayList<DataQueryParams>();
         
@@ -130,14 +131,20 @@
         {
             List<String> values = query.getDimensions().get( dimension );
 
-            List<List<String>> valuePages = new PaginatedList<String>( values ).setNumberOfPages( pageNo ).getPages();
+            if ( values == null || values.isEmpty() )
+            {
+                subQueries.add( new DataQueryParams( query ) );
+                continue;
+            }
+            
+            List<List<String>> valuePages = new PaginatedList<String>( values ).setNumberOfPages( optimalForSubQuery ).getPages();
             
             for ( List<String> valuePage : valuePages )
             {
                 DataQueryParams subQuery = new DataQueryParams( query );
                 subQuery.setDimension( dimension, valuePage );
                 subQueries.add( subQuery );
-            }            
+            }
         }
 
         return subQueries;
@@ -146,20 +153,35 @@
     /**
      * Groups the given query into sub queries based on its periods and which 
      * partition it should be executed against. Sets the partition table name on
-     * each query.
+     * each query. Queries are grouped based on both dimensions and filters.
      */
     private List<DataQueryParams> groupByPartition( DataQueryParams params )
     {
         List<DataQueryParams> queries = new ArrayList<DataQueryParams>();
 
-        ListMap<String, String> tablePeriodMap = PartitionUtils.getTablePeriodMap( params.getPeriods() );
-        
-        for ( String tableName : tablePeriodMap.keySet() )
-        {
-            DataQueryParams query = new DataQueryParams( params );
-            query.setPeriods( tablePeriodMap.get( tableName ) );
-            query.setTableName( tableName );
-            queries.add( query );            
+        if ( params.getPeriods() != null && !params.getPeriods().isEmpty() )
+        {
+            ListMap<String, String> tablePeriodMap = PartitionUtils.getTablePeriodMap( params.getPeriods() );
+            
+            for ( String tableName : tablePeriodMap.keySet() )
+            {
+                DataQueryParams query = new DataQueryParams( params );
+                query.setPeriods( tablePeriodMap.get( tableName ) );
+                query.setTableName( tableName );
+                queries.add( query );            
+            }
+        }
+        else
+        {
+            ListMap<String, String> tablePeriodMap = PartitionUtils.getTablePeriodMap( params.getFilterPeriods() );
+            
+            for ( String tableName : tablePeriodMap.keySet() )
+            {
+                DataQueryParams query = new DataQueryParams( params );
+                query.setFilterPeriods( tablePeriodMap.get( tableName ) );
+                query.setTableName( tableName );
+                queries.add( query );            
+            }
         }
         
         return queries;
@@ -172,6 +194,12 @@
     private List<DataQueryParams> groupByPeriodType( DataQueryParams params )
     {
         List<DataQueryParams> queries = new ArrayList<DataQueryParams>();
+
+        if ( params.getPeriods() == null || params.getPeriods().isEmpty() )
+        {
+            queries.add( new DataQueryParams( params ) );
+            return queries;
+        }
         
         ListMap<String, String> periodTypePeriodMap = getPeriodTypePeriodMap( params.getPeriods() );
 
@@ -193,6 +221,12 @@
     private List<DataQueryParams> groupByOrgUnitLevel( DataQueryParams params )
     {
         List<DataQueryParams> queries = new ArrayList<DataQueryParams>();
+
+        if ( params.getOrganisationUnits() == null || params.getOrganisationUnits().isEmpty() )
+        {
+            queries.add( new DataQueryParams( params ) );
+            return queries;
+        }
         
         ListMap<Integer, String> levelOrgUnitMap = getLevelOrgUnitMap( params.getOrganisationUnits() );
         

=== modified file 'dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/analytics/data/QueryPlannerTest.java'
--- dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/analytics/data/QueryPlannerTest.java	2012-12-19 15:51:21 +0000
+++ dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/analytics/data/QueryPlannerTest.java	2012-12-21 14:12:04 +0000
@@ -192,6 +192,61 @@
         }
     }
     
+    /**
+     * Splits on 3 data elements. No organisation units specified.
+     */
+    @Test
+    public void planQueryE()
+    {
+        DataQueryParams params = new DataQueryParams();
+        params.setDataElements( Arrays.asList( "a", "b", "c" ) );
+        params.setPeriods( Arrays.asList( "200001", "200002", "200003", "200004", "200005", "200006", "200007", "200008", "200009" ) );
+
+        List<DataQueryParams> queries = queryPlanner.planQuery( params, 4 );
+
+        assertEquals( 3, queries.size() );
+
+        for ( DataQueryParams query : queries )
+        {
+            assertTrue( samePeriodType( query.getPeriods() ) );
+            assertTrue( samePartition( query.getPeriods() ) );
+        }
+    }
+
+    /**
+     * Splits on 5 organisation units. No data elements units specified.
+     */
+    @Test
+    public void planQueryF()
+    {
+        DataQueryParams params = new DataQueryParams();
+        params.setOrganisationUnits( Arrays.asList( ouA.getUid(), ouB.getUid(), ouC.getUid(), ouD.getUid(), ouE.getUid() ) );
+        params.setPeriods( Arrays.asList( "200001", "200002", "200003", "200004", "200005", "200006", "200007", "200008", "200009" ) );
+
+        List<DataQueryParams> queries = queryPlanner.planQuery( params, 4 );
+
+        assertEquals( 3, queries.size() );
+
+        for ( DataQueryParams query : queries )
+        {
+            assertTrue( samePeriodType( query.getPeriods() ) );
+            assertTrue( samePartition( query.getPeriods() ) );
+        }
+    }
+    
+    /**
+     * Expected to fail because of no periods specified.
+     */
+    @Test( expected = IllegalArgumentException.class )
+    public void planQueryG()
+    {
+        DataQueryParams params = new DataQueryParams();
+        params.setDataElements( Arrays.asList( "a", "b", "c" ) );
+        params.setOrganisationUnits( Arrays.asList( ouA.getUid(), ouB.getUid(), ouC.getUid(), ouD.getUid(), ouE.getUid() ) );
+
+        queryPlanner.planQuery( params, 4 );
+    }
+    
     // -------------------------------------------------------------------------
     // Supportive methods
     // -------------------------------------------------------------------------

=== modified file 'dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/PaginatedList.java'
--- dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/PaginatedList.java	2011-12-26 10:07:59 +0000
+++ dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/PaginatedList.java	2012-12-21 14:12:04 +0000
@@ -66,7 +66,8 @@
     
     /**
      * Sets the number of pages. The page size will be calculated and set in
-     * order to provide the appropriate total number of pages.
+     * order to provide the appropriate total number of pages. The resulting
+     * number of pages can be lower than the given argument but not higher.
      */
     public PaginatedList<T> setNumberOfPages( int pages )
     {

=== modified file 'dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/AnalyticsController.java'
--- dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/AnalyticsController.java	2012-12-21 12:59:39 +0000
+++ dhis-2/dhis-web/dhis-web-api/src/main/java/org/hisp/dhis/api/controller/AnalyticsController.java	2012-12-21 14:12:04 +0000
@@ -148,6 +148,12 @@
             return false;
         }
         
+        if ( !params.hasPeriods() )
+        {
+            ContextUtils.conflictResponse( response, "Periods must be specified as dimension or filter" );
+            return false;
+        }
+        
         return true;        
     }
 }