dhis2-devs team mailing list archive
-
dhis2-devs team
-
Mailing list archive
-
Message #39199
[Branch ~dhis2-devs-core/dhis2/trunk] Rev 19874: Program indicator / event analytics. Impl support for d2:daysBetween / days between two dates.
------------------------------------------------------------
revno: 19874
committer: Lars Helge Overland <larshelge@xxxxxxxxx>
branch nick: dhis2
timestamp: Thu 2015-08-27 19:18:00 +0200
message:
Program indicator / event analytics. Impl support for d2:daysBetween / days between two dates.
added:
dhis-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/sqlfunc/DaysBetweenSqlFunction.java
modified:
dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramIndicator.java
dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/program/DefaultProgramIndicatorService.java
dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/program/ProgramIndicatorServiceTest.java
dhis-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/sqlfunc/OneIfZeroOrPositiveSqlFunction.java
dhis-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/sqlfunc/SqlFunction.java
dhis-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/sqlfunc/ZeroIfNegativeSqlFunction.java
dhis-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/util/ExpressionFunctions.java
dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/DateUtils.java
dhis-2/dhis-support/dhis-support-system/src/test/java/org/hisp/dhis/system/util/ExpressionUtilsTest.java
dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/programIndicatorForm.vm
--
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-api/src/main/java/org/hisp/dhis/program/ProgramIndicator.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramIndicator.java 2015-08-25 14:09:25 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramIndicator.java 2015-08-27 17:18:00 +0000
@@ -74,7 +74,7 @@
private static final String EXPRESSION_REGEXP = "(" + KEY_DATAELEMENT + "|" + KEY_ATTRIBUTE + "|" + KEY_PROGRAM_VARIABLE + "|" + KEY_CONSTANT + ")\\{(\\w+|" +
VAR_INCIDENT_DATE + "|" + VAR_ENROLLMENT_DATE + "|" + VAR_CURRENT_DATE + ")" + SEPARATOR_ID + "?(\\w*)\\}";
- private static final String SQL_FUNC_REGEXP = "d2:(.+?)\\((.+?)\\)";
+ private static final String SQL_FUNC_REGEXP = "d2:(.+?)\\(([^,]+)\\,?([^,]*)\\,?([^,]*)\\)";
public static final Pattern EXPRESSION_PATTERN = Pattern.compile( EXPRESSION_REGEXP );
public static final Pattern SQL_FUNC_PATTERN = Pattern.compile( SQL_FUNC_REGEXP );
=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/program/DefaultProgramIndicatorService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/program/DefaultProgramIndicatorService.java 2015-08-25 18:37:50 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/program/DefaultProgramIndicatorService.java 2015-08-27 17:18:00 +0000
@@ -38,6 +38,7 @@
import java.util.Set;
import java.util.regex.Matcher;
+import org.hisp.dhis.commons.sqlfunc.DaysBetweenSqlFunction;
import org.hisp.dhis.commons.sqlfunc.OneIfZeroOrPositiveSqlFunction;
import org.hisp.dhis.commons.sqlfunc.SqlFunction;
import org.hisp.dhis.commons.sqlfunc.ZeroIfNegativeSqlFunction;
@@ -73,7 +74,8 @@
{
private static final Map<String, SqlFunction> SQL_FUNC_MAP = ImmutableMap.<String, SqlFunction>builder().
put( ZeroIfNegativeSqlFunction.KEY, new ZeroIfNegativeSqlFunction() ).
- put( OneIfZeroOrPositiveSqlFunction.KEY, new OneIfZeroOrPositiveSqlFunction() ).build();
+ put( OneIfZeroOrPositiveSqlFunction.KEY, new OneIfZeroOrPositiveSqlFunction() ).
+ put( DaysBetweenSqlFunction.KEY, new DaysBetweenSqlFunction() ).build();
// -------------------------------------------------------------------------
// Dependencies
@@ -398,7 +400,9 @@
while ( matcher.find() )
{
String func = matcher.group( 1 );
- String column = matcher.group( 2 );
+ String arg1 = matcher.group( 2 );
+ String arg2 = matcher.group( 3 );
+ String arg3 = matcher.group( 4 );
SqlFunction function = SQL_FUNC_MAP.get( func );
@@ -407,7 +411,7 @@
throw new IllegalStateException( "Function not recognized: " + func );
}
- String result = function.evaluate( column );
+ String result = function.evaluate( arg1, arg2, arg3 );
matcher.appendReplacement( buffer, result );
}
@@ -481,7 +485,7 @@
if ( programStage != null && dataElement != null )
{
- String sample = dataElement.isNumericType() ? String.valueOf( 1 ) : "'A'";
+ String sample = dataElement.isNumericType() ? String.valueOf( 1 ) : dataElement.isDateType() ? "'2000-01-01'" : "'A'";
matcher.appendReplacement( expr, sample );
}
@@ -496,7 +500,7 @@
if ( attribute != null )
{
- String sample = attribute.isNumericType() ? String.valueOf( 1 ) : "'A'";
+ String sample = attribute.isNumericType() ? String.valueOf( 1 ) : attribute.isDateType() ? "'2000-01-01'" : "'A'";
matcher.appendReplacement( expr, sample );
}
=== modified file 'dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/program/ProgramIndicatorServiceTest.java'
--- dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/program/ProgramIndicatorServiceTest.java 2015-08-23 13:22:07 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/program/ProgramIndicatorServiceTest.java 2015-08-27 17:18:00 +0000
@@ -528,8 +528,19 @@
assertEquals( expected, programIndicatorService.getAnalyticsSQl( expression ) );
}
+ @Test
+ public void testGetAnalyticsSqlWithFunctionsC()
+ {
+ String col1 = COL_QUOTE + deA.getUid() + COL_QUOTE;
+ String col2 = COL_QUOTE + deB.getUid() + COL_QUOTE;
+ String expected = "(cast(" + col2 + " as date) - cast(" + col1 + " as date))";
+ String expression = "d2:daysBetween(" + col1 + "," + col2 + ")";
+
+ assertEquals( expected, programIndicatorService.getAnalyticsSQl( expression ) );
+ }
+
@Test( expected = IllegalStateException.class )
- public void testGetAnalyticsSqlWithFunctionsC()
+ public void testGetAnalyticsSqlWithFunctionsInvalid()
{
String col = COL_QUOTE + deA.getUid() + COL_QUOTE;
String expected = "case when " + col + " >= 0 then 1 else " + col + " end";
=== added file 'dhis-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/sqlfunc/DaysBetweenSqlFunction.java'
--- dhis-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/sqlfunc/DaysBetweenSqlFunction.java 1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/sqlfunc/DaysBetweenSqlFunction.java 2015-08-27 17:18:00 +0000
@@ -0,0 +1,44 @@
+package org.hisp.dhis.commons.sqlfunc;
+
+/*
+ * Copyright (c) 2004-2015, University of Oslo
+ * 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.
+ * Neither the name of the HISP project nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * 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 OWNER 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.
+ */
+
+/**
+ * @author Lars Helge Overland
+ */
+public class DaysBetweenSqlFunction
+ implements SqlFunction
+{
+ public static final String KEY = "daysBetween";
+
+ @Override
+ public String evaluate( String arg1, String arg2, String arg3 )
+ {
+ return "(cast(" + arg2 + " as date) - cast(" + arg1 + " as date))";
+ }
+}
=== modified file 'dhis-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/sqlfunc/OneIfZeroOrPositiveSqlFunction.java'
--- dhis-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/sqlfunc/OneIfZeroOrPositiveSqlFunction.java 2015-08-22 14:51:53 +0000
+++ dhis-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/sqlfunc/OneIfZeroOrPositiveSqlFunction.java 2015-08-27 17:18:00 +0000
@@ -40,8 +40,8 @@
public static final String KEY = "oizp";
@Override
- public String evaluate( String column )
+ public String evaluate( String arg1, String arg2, String arg )
{
- return "case when " + column + " >= 0 then 1 else 0 end";
+ return "case when " + arg1 + " >= 0 then 1 else 0 end";
}
}
=== modified file 'dhis-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/sqlfunc/SqlFunction.java'
--- dhis-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/sqlfunc/SqlFunction.java 2015-08-22 13:42:01 +0000
+++ dhis-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/sqlfunc/SqlFunction.java 2015-08-27 17:18:00 +0000
@@ -36,8 +36,11 @@
/**
* Evaluates the function using the given column name.
*
- * @param column the quoted column name.
+ * @param arg1 argument 1.
+ * @param arg2 argument 2.
+ * @param arg3 argument 3.
+ *
* @return the result of the evaluation.
*/
- String evaluate( String column );
+ String evaluate( String arg1, String arg2, String arg );
}
=== modified file 'dhis-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/sqlfunc/ZeroIfNegativeSqlFunction.java'
--- dhis-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/sqlfunc/ZeroIfNegativeSqlFunction.java 2015-08-22 14:51:53 +0000
+++ dhis-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/sqlfunc/ZeroIfNegativeSqlFunction.java 2015-08-27 17:18:00 +0000
@@ -40,8 +40,8 @@
public static final String KEY = "zing";
@Override
- public String evaluate( String column )
+ public String evaluate( String arg1, String arg2, String arg )
{
- return "case when " + column + " < 0 then 0 else " + column + " end";
+ return "case when " + arg1 + " < 0 then 0 else " + arg1 + " end";
}
}
=== modified file 'dhis-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/util/ExpressionFunctions.java'
--- dhis-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/util/ExpressionFunctions.java 2015-07-14 09:47:47 +0000
+++ dhis-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/util/ExpressionFunctions.java 2015-08-27 17:18:00 +0000
@@ -28,6 +28,13 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * @author Lars Helge Overland
+ */
public class ExpressionFunctions
{
public static final String NAMESPACE = "d2";
@@ -64,4 +71,23 @@
return ( value.doubleValue() >= 0d ) ? 1d : 0d;
}
+
+ /**
+ * Function which will return the number of days between the two given dates.
+ *
+ * @param start the start date.
+ * @param end the end date.
+ * @return number of days between dates.
+ */
+ public static Long daysBetween( String start, String end )
+ throws ParseException
+ {
+ SimpleDateFormat format = new SimpleDateFormat();
+ format.applyPattern( "yyyy-MM-dd" );
+
+ Date startDate = format.parse( start );
+ Date endDate = format.parse( end );
+
+ return ( startDate.getTime() - endDate.getTime() ) / 31536000000l;
+ }
}
=== modified file 'dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/DateUtils.java'
--- dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/DateUtils.java 2015-07-08 05:02:25 +0000
+++ dhis-2/dhis-support/dhis-support-system/src/main/java/org/hisp/dhis/system/util/DateUtils.java 2015-08-27 17:18:00 +0000
@@ -53,7 +53,6 @@
/**
* @author Lars Helge Overland
- * @version $Id$
*/
public class DateUtils
{
=== modified file 'dhis-2/dhis-support/dhis-support-system/src/test/java/org/hisp/dhis/system/util/ExpressionUtilsTest.java'
--- dhis-2/dhis-support/dhis-support-system/src/test/java/org/hisp/dhis/system/util/ExpressionUtilsTest.java 2015-08-21 12:47:08 +0000
+++ dhis-2/dhis-support/dhis-support-system/src/test/java/org/hisp/dhis/system/util/ExpressionUtilsTest.java 2015-08-27 17:18:00 +0000
@@ -155,6 +155,7 @@
assertTrue( ExpressionUtils.isValid( "2 + 8", null ) );
assertTrue( ExpressionUtils.isValid( "3 - v1", vars ) );
assertTrue( ExpressionUtils.isValid( "d2:zing(1)", null ) );
+ assertTrue( ExpressionUtils.isValid( "d2:daysBetween('2015-02-01','2015-04-02')", null ) );
assertTrue( ExpressionUtils.isValid( "(d2:zing(1)+d2:zing(1))*50/1", null ) );
assertTrue( ExpressionUtils.isValid( "1/(1/100)", null ) );
assertTrue( ExpressionUtils.isValid( "SUM(1)", null ) );
=== modified file 'dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/programIndicatorForm.vm'
--- dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/programIndicatorForm.vm 2015-08-25 14:09:25 +0000
+++ dhis-2/dhis-web/dhis-web-maintenance/dhis-web-maintenance-program/src/main/webapp/dhis-web-maintenance-program/programIndicatorForm.vm 2015-08-27 17:18:00 +0000
@@ -115,7 +115,7 @@
</td>
</tr>
<tr>
- <th style="padding-top:15px">$i18n.getString( "expression" ) <span class="tipText">Tip: use zing(x) oizp(x)</span></th>
+ <th style="padding-top:15px">$i18n.getString( "expression" ) <span class="tipText">Tip: use d2:daysBetween(x,y) d2:zing(x) d2:oizp(x)</span></th>
</tr>
<tr>
<td>
@@ -259,7 +259,7 @@
</td>
</tr>
<tr>
- <th style="padding-top:15px">$i18n.getString( "filter" ) <span class="tipText">Tip: use oizp(x) zing(x)</span></th>
+ <th style="padding-top:15px">$i18n.getString( "filter" ) <span class="tipText">Tip: use d2:daysBetween(x,y) d2:zing(x) d2:oizp(x)</span></th>
</tr>
<tr>
<td>