Skip to content

Commit b59d156

Browse files
Make D2 dates related functions SqlBuilder aware (DHIS-16705) (#19380)
1 parent 27b233c commit b59d156

22 files changed

+958
-67
lines changed

dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/program/DefaultProgramIndicatorService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ public DefaultProgramIndicatorService(
126126
this.analyticsSqlCache = cacheProvider.createAnalyticsSqlCache();
127127
this.sqlBuilder = sqlBuilder;
128128

129-
this.programIndicatorItems = new ExpressionMapBuilder(sqlBuilder).getExpressionItemMap();
129+
this.programIndicatorItems = new ExpressionMapBuilder().getExpressionItemMap();
130130
}
131131

132132
// -------------------------------------------------------------------------

dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/program/ExpressionMapBuilder.java

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232

3333
import com.google.common.collect.ImmutableMap;
3434
import lombok.Getter;
35-
import org.hisp.dhis.db.sql.SqlBuilder;
3635
import org.hisp.dhis.parser.expression.ExpressionItem;
3736
import org.hisp.dhis.parser.expression.function.RepeatableProgramStageOffset;
3837
import org.hisp.dhis.parser.expression.function.VectorAvg;
@@ -72,7 +71,7 @@ public class ExpressionMapBuilder {
7271

7372
private final ImmutableMap<Integer, ExpressionItem> expressionItemMap;
7473

75-
public ExpressionMapBuilder(SqlBuilder sqlBuilder) {
74+
public ExpressionMapBuilder() {
7675
expressionItemMap =
7776
ImmutableMap.<Integer, ExpressionItem>builder()
7877

@@ -82,22 +81,22 @@ public ExpressionMapBuilder(SqlBuilder sqlBuilder) {
8281

8382
// Program functions
8483

85-
.put(D2_CONDITION, new D2Condition().withSqlBuilder(sqlBuilder))
86-
.put(D2_COUNT, new D2Count().withSqlBuilder(sqlBuilder))
87-
.put(D2_COUNT_IF_CONDITION, new D2CountIfCondition().withSqlBuilder(sqlBuilder))
88-
.put(D2_COUNT_IF_VALUE, new D2CountIfValue().withSqlBuilder(sqlBuilder))
89-
.put(D2_DAYS_BETWEEN, new D2DaysBetween().withSqlBuilder(sqlBuilder))
90-
.put(D2_HAS_VALUE, new D2HasValue().withSqlBuilder(sqlBuilder))
91-
.put(D2_MAX_VALUE, new D2MaxValue().withSqlBuilder(sqlBuilder))
92-
.put(D2_MINUTES_BETWEEN, new D2MinutesBetween().withSqlBuilder(sqlBuilder))
93-
.put(D2_MIN_VALUE, new D2MinValue().withSqlBuilder(sqlBuilder))
94-
.put(D2_MONTHS_BETWEEN, new D2MonthsBetween().withSqlBuilder(sqlBuilder))
95-
.put(D2_OIZP, new D2Oizp().withSqlBuilder(sqlBuilder))
96-
.put(D2_RELATIONSHIP_COUNT, new D2RelationshipCount().withSqlBuilder(sqlBuilder))
97-
.put(D2_WEEKS_BETWEEN, new D2WeeksBetween().withSqlBuilder(sqlBuilder))
98-
.put(D2_YEARS_BETWEEN, new D2YearsBetween().withSqlBuilder(sqlBuilder))
99-
.put(D2_ZING, new D2Zing().withSqlBuilder(sqlBuilder))
100-
.put(D2_ZPVC, new D2Zpvc().withSqlBuilder(sqlBuilder))
84+
.put(D2_CONDITION, new D2Condition())
85+
.put(D2_COUNT, new D2Count())
86+
.put(D2_COUNT_IF_CONDITION, new D2CountIfCondition())
87+
.put(D2_COUNT_IF_VALUE, new D2CountIfValue())
88+
.put(D2_DAYS_BETWEEN, new D2DaysBetween())
89+
.put(D2_HAS_VALUE, new D2HasValue())
90+
.put(D2_MAX_VALUE, new D2MaxValue())
91+
.put(D2_MINUTES_BETWEEN, new D2MinutesBetween())
92+
.put(D2_MIN_VALUE, new D2MinValue())
93+
.put(D2_MONTHS_BETWEEN, new D2MonthsBetween())
94+
.put(D2_OIZP, new D2Oizp())
95+
.put(D2_RELATIONSHIP_COUNT, new D2RelationshipCount())
96+
.put(D2_WEEKS_BETWEEN, new D2WeeksBetween())
97+
.put(D2_YEARS_BETWEEN, new D2YearsBetween())
98+
.put(D2_ZING, new D2Zing())
99+
.put(D2_ZPVC, new D2Zpvc())
101100

102101
// Program functions for custom aggregation
103102

@@ -111,13 +110,13 @@ public ExpressionMapBuilder(SqlBuilder sqlBuilder) {
111110

112111
// Data items
113112

114-
.put(HASH_BRACE, new ProgramItemStageElement().withSqlBuilder(sqlBuilder))
115-
.put(A_BRACE, new ProgramItemAttribute().withSqlBuilder(sqlBuilder))
116-
.put(PS_EVENTDATE, new ProgramItemPsEventdate().withSqlBuilder(sqlBuilder))
113+
.put(HASH_BRACE, new ProgramItemStageElement())
114+
.put(A_BRACE, new ProgramItemAttribute())
115+
.put(PS_EVENTDATE, new ProgramItemPsEventdate())
117116

118117
// Program variables
119118

120-
.put(V_BRACE, new ProgramVariableItem().withSqlBuilder(sqlBuilder))
119+
.put(V_BRACE, new ProgramVariableItem())
121120

122121
// . functions
123122
.put(STAGE_OFFSET, new RepeatableProgramStageOffset())

dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/program/ProgramExpressionItem.java

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
import org.hisp.dhis.analytics.DataType;
3737
import org.hisp.dhis.antlr.ParserExceptionWithoutContext;
3838
import org.hisp.dhis.common.ValueType;
39-
import org.hisp.dhis.db.sql.SqlBuilder;
4039
import org.hisp.dhis.parser.expression.CommonExpressionVisitor;
4140
import org.hisp.dhis.parser.expression.ExpressionItem;
4241
import org.hisp.dhis.program.dataitem.ProgramItemAttribute;
@@ -58,8 +57,6 @@
5857
*/
5958
public abstract class ProgramExpressionItem implements ExpressionItem {
6059

61-
private SqlBuilder sqlBuilder;
62-
6360
@Override
6461
public final Object getExpressionInfo(ExprContext ctx, CommonExpressionVisitor visitor) {
6562
throw new ParserExceptionWithoutContext(
@@ -124,11 +121,6 @@ protected String replaceNullSqlValues(
124121
if (dataType == NUMERIC || dataType == BOOLEAN) {
125122
dataType = visitor.getParams().getDataType() == BOOLEAN ? BOOLEAN : NUMERIC;
126123
}
127-
return replaceSqlNull(sqlBuilder.cast(column, dataType), dataType);
128-
}
129-
130-
protected ExpressionItem withSqlBuilder(SqlBuilder sqlBuilder) {
131-
this.sqlBuilder = sqlBuilder;
132-
return this;
124+
return replaceSqlNull(visitor.getSqlBuilder().cast(column, dataType), dataType);
133125
}
134126
}

dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/program/function/D2DaysBetween.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,18 @@
2727
*/
2828
package org.hisp.dhis.program.function;
2929

30+
import org.hisp.dhis.db.sql.SqlBuilder;
31+
import org.hisp.dhis.parser.expression.CommonExpressionVisitor;
32+
3033
/**
3134
* Program indicator function: d2 days between
3235
*
3336
* @author Jim Grace
3437
*/
3538
public class D2DaysBetween extends ProgramBetweenFunction {
3639
@Override
37-
public Object getSqlBetweenDates(String startDate, String endDate) {
38-
return "(cast(" + endDate + " as date) - cast(" + startDate + " as date))";
40+
public Object getSqlBetweenDates(
41+
String startDate, String endDate, CommonExpressionVisitor visitor) {
42+
return visitor.getSqlBuilder().dateDifference(startDate, endDate, SqlBuilder.DateUnit.DAYS);
3943
}
4044
}

dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/program/function/D2MinutesBetween.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,19 @@
2727
*/
2828
package org.hisp.dhis.program.function;
2929

30+
import static org.hisp.dhis.db.sql.SqlBuilder.DateUnit.MINUTES;
31+
32+
import org.hisp.dhis.parser.expression.CommonExpressionVisitor;
33+
3034
/**
3135
* Program indicator function: d2 minutes between
3236
*
3337
* @author Jim Grace
3438
*/
3539
public class D2MinutesBetween extends ProgramBetweenFunction {
3640
@Override
37-
public Object getSqlBetweenDates(String startDate, String endDate) {
38-
return "(extract(epoch from (cast("
39-
+ endDate
40-
+ " as timestamp) - cast("
41-
+ startDate
42-
+ " as timestamp))) / 60)";
41+
public Object getSqlBetweenDates(
42+
String startDate, String endDate, CommonExpressionVisitor visitor) {
43+
return visitor.getSqlBuilder().dateDifference(startDate, endDate, MINUTES);
4344
}
4445
}

dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/program/function/D2MonthsBetween.java

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,23 +27,19 @@
2727
*/
2828
package org.hisp.dhis.program.function;
2929

30+
import static org.hisp.dhis.db.sql.SqlBuilder.DateUnit.MONTHS;
31+
32+
import org.hisp.dhis.parser.expression.CommonExpressionVisitor;
33+
3034
/**
3135
* Program indicator function: d2 months between
3236
*
3337
* @author Jim Grace
3438
*/
3539
public class D2MonthsBetween extends ProgramBetweenFunction {
3640
@Override
37-
public Object getSqlBetweenDates(String startDate, String endDate) {
38-
return "((date_part('year',age(cast("
39-
+ endDate
40-
+ " as date), cast("
41-
+ startDate
42-
+ " as date)))) * 12 + "
43-
+ "date_part('month',age(cast("
44-
+ endDate
45-
+ " as date), cast("
46-
+ startDate
47-
+ " as date))))";
41+
public Object getSqlBetweenDates(
42+
String startDate, String endDate, CommonExpressionVisitor visitor) {
43+
return visitor.getSqlBuilder().dateDifference(startDate, endDate, MONTHS);
4844
}
4945
}

dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/program/function/D2WeeksBetween.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,19 @@
2727
*/
2828
package org.hisp.dhis.program.function;
2929

30+
import static org.hisp.dhis.db.sql.SqlBuilder.DateUnit.WEEKS;
31+
32+
import org.hisp.dhis.parser.expression.CommonExpressionVisitor;
33+
3034
/**
3135
* Program indicator function: d2 weeks between
3236
*
3337
* @author Jim Grace
3438
*/
3539
public class D2WeeksBetween extends ProgramBetweenFunction {
3640
@Override
37-
public Object getSqlBetweenDates(String startDate, String endDate) {
38-
return "((cast(" + endDate + " as date) - cast(" + startDate + " as date))/7)";
41+
public Object getSqlBetweenDates(
42+
String startDate, String endDate, CommonExpressionVisitor visitor) {
43+
return visitor.getSqlBuilder().dateDifference(startDate, endDate, WEEKS);
3944
}
4045
}

dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/program/function/D2YearsBetween.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,19 @@
2727
*/
2828
package org.hisp.dhis.program.function;
2929

30+
import static org.hisp.dhis.db.sql.SqlBuilder.DateUnit.YEARS;
31+
32+
import org.hisp.dhis.parser.expression.CommonExpressionVisitor;
33+
3034
/**
3135
* Program indicator function: d2 years between
3236
*
3337
* @author Jim Grace
3438
*/
3539
public class D2YearsBetween extends ProgramBetweenFunction {
3640
@Override
37-
public Object getSqlBetweenDates(String startDate, String endDate) {
38-
return "(date_part('year',age(cast("
39-
+ endDate
40-
+ " as date), cast("
41-
+ startDate
42-
+ " as date))))";
41+
public Object getSqlBetweenDates(
42+
String startDate, String endDate, CommonExpressionVisitor visitor) {
43+
return visitor.getSqlBuilder().dateDifference(startDate, endDate, YEARS);
4344
}
4445
}

dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/program/function/ProgramBetweenFunction.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public final Object getSql(ExprContext ctx, CommonExpressionVisitor visitor) {
5454
String startDate = castString(visitor.visitAllowingNulls(ctx.expr(0)));
5555
String endDate = castString(visitor.visitAllowingNulls(ctx.expr(1)));
5656

57-
return getSqlBetweenDates(startDate, endDate);
57+
return getSqlBetweenDates(startDate, endDate, visitor);
5858
}
5959

6060
/**
@@ -64,5 +64,6 @@ public final Object getSql(ExprContext ctx, CommonExpressionVisitor visitor) {
6464
* @param endDate ending date
6565
* @return the SQL to compare the dates based on the time/date unit
6666
*/
67-
public abstract Object getSqlBetweenDates(String startDate, String endDate);
67+
public abstract Object getSqlBetweenDates(
68+
String startDate, String endDate, CommonExpressionVisitor visitor);
6869
}

dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/program/ProgramSqlGeneratorFunctionsTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,7 @@ void testWeeksBetween() {
557557
sql,
558558
is(
559559
"((cast(case when ax.\"ps\" = 'ProgrmStagA' then \"DataElmentD\" else null end as date) - "
560-
+ "cast(case when ax.\"ps\" = 'ProgrmStagA' then \"DataElmentC\" else null end as date))/7)"));
560+
+ "cast(case when ax.\"ps\" = 'ProgrmStagA' then \"DataElmentC\" else null end as date)) / 7)"));
561561
}
562562

563563
@Test
@@ -800,7 +800,7 @@ private Object test(
800800
.programIndicatorService(programIndicatorService)
801801
.programStageService(programStageService)
802802
.i18nSupplier(() -> new I18n(null, null))
803-
.itemMap(new ExpressionMapBuilder(sqlBuilder).getExpressionItemMap())
803+
.itemMap(new ExpressionMapBuilder().getExpressionItemMap())
804804
.itemMethod(itemMethod)
805805
.params(params)
806806
.progParams(progParams)

0 commit comments

Comments
 (0)