diff --git a/dhis-2/dhis-api/src/main/java/org/hisp/dhis/analytics/table/EnrollmentAnalyticsColumnName.java b/dhis-2/dhis-api/src/main/java/org/hisp/dhis/analytics/table/EnrollmentAnalyticsColumnName.java index df4e708abfd2..16bce0442f5c 100644 --- a/dhis-2/dhis-api/src/main/java/org/hisp/dhis/analytics/table/EnrollmentAnalyticsColumnName.java +++ b/dhis-2/dhis-api/src/main/java/org/hisp/dhis/analytics/table/EnrollmentAnalyticsColumnName.java @@ -31,7 +31,6 @@ @NoArgsConstructor(access = lombok.AccessLevel.PRIVATE) public final class EnrollmentAnalyticsColumnName { - public static final String ENROLLMENT_COLUMN_NAME = "enrollment"; public static final String TRACKED_ENTITY_COLUMN_NAME = "trackedentity"; public static final String ENROLLMENT_DATE_COLUMN_NAME = "enrollmentdate"; diff --git a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/EnrollmentAnalyticsColumn.java b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/EnrollmentAnalyticsColumn.java index 1cbca99e8be3..ff2f4dc1270c 100644 --- a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/EnrollmentAnalyticsColumn.java +++ b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/EnrollmentAnalyticsColumn.java @@ -49,137 +49,146 @@ @NoArgsConstructor(access = lombok.AccessLevel.PRIVATE) public final class EnrollmentAnalyticsColumn { - private static final AnalyticsTableColumn ENROLLMENT = - AnalyticsTableColumn.builder() - .name(EnrollmentAnalyticsColumnName.ENROLLMENT_COLUMN_NAME) - .dataType(CHARACTER_11) - .nullable(NOT_NULL) - .selectExpression("en.uid") - .build(); - static final AnalyticsTableColumn TRACKED_ENTITY = + public static final AnalyticsTableColumn TRACKED_ENTITY = AnalyticsTableColumn.builder() .name(EnrollmentAnalyticsColumnName.TRACKED_ENTITY_COLUMN_NAME) .dataType(CHARACTER_11) .selectExpression("te.uid") .build(); - private static final AnalyticsTableColumn ENROLLMENT_DATE = - AnalyticsTableColumn.builder() - .name(EnrollmentAnalyticsColumnName.ENROLLMENT_DATE_COLUMN_NAME) - .dataType(TIMESTAMP) - .selectExpression("en.enrollmentdate") - .build(); - private static final AnalyticsTableColumn OCCURRED_DATE = - AnalyticsTableColumn.builder() - .name(EnrollmentAnalyticsColumnName.OCCURRED_DATE_COLUMN_NAME) - .dataType(TIMESTAMP) - .selectExpression("en.occurreddate") - .build(); - private static final AnalyticsTableColumn COMPLETED_DATE = - AnalyticsTableColumn.builder() - .name(EnrollmentAnalyticsColumnName.COMPLETED_DATE_COLUMN_NAME) - .dataType(TIMESTAMP) - .selectExpression("case en.status when 'COMPLETED' then en.completeddate end") - .build(); - private static final AnalyticsTableColumn LAST_UPDATED = - AnalyticsTableColumn.builder() - .name(EnrollmentAnalyticsColumnName.LAST_UPDATED_COLUMN_NAME) - .dataType(TIMESTAMP) - .selectExpression("en.lastupdated") - .build(); - private static final AnalyticsTableColumn STORED_BY = - AnalyticsTableColumn.builder() - .name(EnrollmentAnalyticsColumnName.STORED_BY_COLUMN_NAME) - .dataType(VARCHAR_255) - .selectExpression("en.storedby") - .build(); - private static final AnalyticsTableColumn ENROLLMENT_STATUS = - AnalyticsTableColumn.builder() - .name(EnrollmentAnalyticsColumnName.ENROLLMENT_STATUS_COLUMN_NAME) - .dataType(VARCHAR_50) - .selectExpression("en.status") - .build(); - private static final AnalyticsTableColumn LONGITUDE = - AnalyticsTableColumn.builder() - .name(EnrollmentAnalyticsColumnName.LONGITUDE_COLUMN_NAME) - .dataType(DOUBLE) - .selectExpression( - "CASE WHEN 'POINT' = GeometryType(en.geometry) THEN ST_X(en.geometry) ELSE null END") - .build(); - private static final AnalyticsTableColumn LATITUDE = - AnalyticsTableColumn.builder() - .name(EnrollmentAnalyticsColumnName.LATITUDE_COLUMN_NAME) - .dataType(DOUBLE) - .selectExpression( - "CASE WHEN 'POINT' = GeometryType(en.geometry) THEN ST_Y(en.geometry) ELSE null END") - .build(); - private static final AnalyticsTableColumn OU = - AnalyticsTableColumn.builder() - .name(EnrollmentAnalyticsColumnName.OU_COLUMN_NAME) - .dataType(CHARACTER_11) - .nullable(NOT_NULL) - .selectExpression("ou.uid") - .build(); - private static final AnalyticsTableColumn OU_NAME = - AnalyticsTableColumn.builder() - .name(EnrollmentAnalyticsColumnName.OU_NAME_COLUMN_NAME) - .dataType(TEXT) - .nullable(NOT_NULL) - .selectExpression("ou.name") - .build(); - private static final AnalyticsTableColumn OU_CODE = - AnalyticsTableColumn.builder() - .name(EnrollmentAnalyticsColumnName.OU_CODE_COLUMN_NAME) - .dataType(TEXT) - .selectExpression("ou.code") - .build(); - private static final AnalyticsTableColumn OU_LEVEL = - AnalyticsTableColumn.builder() - .name(EnrollmentAnalyticsColumnName.OU_LEVEL_COLUMN_NAME) - .dataType(INTEGER) - .selectExpression("ous.level") - .build(); - private static final AnalyticsTableColumn ENROLLMENT_GEOMETRY = - AnalyticsTableColumn.builder() - .name(EnrollmentAnalyticsColumnName.ENROLLMENT_GEOMETRY_COLUMN_NAME) - .dataType(GEOMETRY) - .selectExpression("en.geometry") - .indexType(IndexType.GIST) - .build(); - private static final AnalyticsTableColumn REGISTRATION_OU = - AnalyticsTableColumn.builder() - .name(EnrollmentAnalyticsColumnName.REGISTRATION_OU_COLUMN_NAME) - .dataType(CHARACTER_11) - .nullable(NOT_NULL) - .selectExpression("coalesce(registrationou.uid,ou.uid)") - .build(); - static final AnalyticsTableColumn TRACKED_ENTITY_GEOMETRY = + public static final AnalyticsTableColumn TRACKED_ENTITY_GEOMETRY = AnalyticsTableColumn.builder() .name(EnrollmentAnalyticsColumnName.TRACKED_ENTITY_GEOMETRY_COLUMN_NAME) .dataType(GEOMETRY) .selectExpression("te.geometry") .build(); - private static final List COMMON_COLUMNS = - List.of( - ENROLLMENT, - ENROLLMENT_DATE, - OCCURRED_DATE, - COMPLETED_DATE, - LAST_UPDATED, - STORED_BY, - ENROLLMENT_STATUS, - OU, - OU_NAME, - OU_CODE, - OU_LEVEL, - REGISTRATION_OU); + /** + * Returns a list of {@link AnalyticsTableColumn}. + * + * @param sqlBuilder the {@link SqlBuilder}. + * @return a list of {@link AnalyticsTableColumn}. + */ + public static List getColumns(SqlBuilder sqlBuilder) { + List columns = new ArrayList<>(); + columns.addAll(getCommonColumns(sqlBuilder)); + columns.addAll(getJsonColumns(sqlBuilder)); + + if (sqlBuilder.supportsGeospatialData()) { + columns.addAll(getGeometryColumns(sqlBuilder)); + } + + return columns; + } - // Geometry-specific columns - private static final List GEOMETRY_COLUMNS = - List.of(ENROLLMENT_GEOMETRY, LONGITUDE, LATITUDE); + /** + * Returns a list of {@link AnalyticsTableColumn}. + * + * @param sqlBuilder the {@link SqlBuilder}. + * @return a list of {@link AnalyticsTableColumn}. + */ + private static List getCommonColumns(SqlBuilder sqlBuilder) { + return List.of( + AnalyticsTableColumn.builder() + .name(EnrollmentAnalyticsColumnName.ENROLLMENT_COLUMN_NAME) + .dataType(CHARACTER_11) + .nullable(NOT_NULL) + .selectExpression("en.uid") + .build(), + AnalyticsTableColumn.builder() + .name(EnrollmentAnalyticsColumnName.ENROLLMENT_DATE_COLUMN_NAME) + .dataType(TIMESTAMP) + .selectExpression("en.enrollmentdate") + .build(), + AnalyticsTableColumn.builder() + .name(EnrollmentAnalyticsColumnName.OCCURRED_DATE_COLUMN_NAME) + .dataType(TIMESTAMP) + .selectExpression("en.occurreddate") + .build(), + AnalyticsTableColumn.builder() + .name(EnrollmentAnalyticsColumnName.COMPLETED_DATE_COLUMN_NAME) + .dataType(TIMESTAMP) + .selectExpression("case en.status when 'COMPLETED' then en.completeddate end") + .build(), + AnalyticsTableColumn.builder() + .name(EnrollmentAnalyticsColumnName.LAST_UPDATED_COLUMN_NAME) + .dataType(TIMESTAMP) + .selectExpression("en.lastupdated") + .build(), + AnalyticsTableColumn.builder() + .name(EnrollmentAnalyticsColumnName.STORED_BY_COLUMN_NAME) + .dataType(VARCHAR_255) + .selectExpression("en.storedby") + .build(), + AnalyticsTableColumn.builder() + .name(EnrollmentAnalyticsColumnName.ENROLLMENT_STATUS_COLUMN_NAME) + .dataType(VARCHAR_50) + .selectExpression("en.status") + .build(), + AnalyticsTableColumn.builder() + .name(EnrollmentAnalyticsColumnName.OU_COLUMN_NAME) + .dataType(CHARACTER_11) + .nullable(NOT_NULL) + .selectExpression("ou.uid") + .build(), + AnalyticsTableColumn.builder() + .name(EnrollmentAnalyticsColumnName.OU_NAME_COLUMN_NAME) + .dataType(TEXT) + .nullable(NOT_NULL) + .selectExpression("ou.name") + .build(), + AnalyticsTableColumn.builder() + .name(EnrollmentAnalyticsColumnName.OU_CODE_COLUMN_NAME) + .dataType(TEXT) + .selectExpression("ou.code") + .build(), + AnalyticsTableColumn.builder() + .name(EnrollmentAnalyticsColumnName.OU_LEVEL_COLUMN_NAME) + .dataType(INTEGER) + .selectExpression("ous.level") + .build(), + AnalyticsTableColumn.builder() + .name(EnrollmentAnalyticsColumnName.REGISTRATION_OU_COLUMN_NAME) + .dataType(CHARACTER_11) + .nullable(NOT_NULL) + .selectExpression("coalesce(registrationou.uid,ou.uid)") + .build()); + } - private static List createJsonColumns(SqlBuilder sqlBuilder) { + /** + * Returns a list of geometry {@link AnalyticsTableColumn}. + * + * @param sqlBuilder the {@link SqlBuilder}. + * @return a list of {@link AnalyticsTableColumn}. + */ + private static List getGeometryColumns(SqlBuilder sqlBuilder) { + return List.of( + AnalyticsTableColumn.builder() + .name(EnrollmentAnalyticsColumnName.ENROLLMENT_GEOMETRY_COLUMN_NAME) + .dataType(GEOMETRY) + .selectExpression("en.geometry") + .indexType(IndexType.GIST) + .build(), + AnalyticsTableColumn.builder() + .name(EnrollmentAnalyticsColumnName.LONGITUDE_COLUMN_NAME) + .dataType(DOUBLE) + .selectExpression( + "CASE WHEN 'POINT' = GeometryType(en.geometry) THEN ST_X(en.geometry) ELSE null END") + .build(), + AnalyticsTableColumn.builder() + .name(EnrollmentAnalyticsColumnName.LATITUDE_COLUMN_NAME) + .dataType(DOUBLE) + .selectExpression( + "CASE WHEN 'POINT' = GeometryType(en.geometry) THEN ST_Y(en.geometry) ELSE null END") + .build()); + } + /** + * Returns a list of {@link AnalyticsTableColumn}. + * + * @param sqlBuilder the {@link SqlBuilder}. + * @return a list of {@link AnalyticsTableColumn}. + */ + private static List getJsonColumns(SqlBuilder sqlBuilder) { return List.of( AnalyticsTableColumn.builder() .name(EnrollmentAnalyticsColumnName.CREATED_BY_USERNAME_COLUMN_NAME) @@ -241,14 +250,4 @@ private static List createJsonColumns(SqlBuilder sqlBuilde .skipIndex(Skip.SKIP) .build()); } - - public static List getColumns(SqlBuilder sqlBuilder) { - List columns = new ArrayList<>(COMMON_COLUMNS); - columns.addAll(createJsonColumns(sqlBuilder)); - // Add database-specific columns based on SqlBuilder capabilities - if (sqlBuilder.supportsGeospatialData()) { - columns.addAll(GEOMETRY_COLUMNS); - } - return columns; - } } diff --git a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/EventAnalyticsColumn.java b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/EventAnalyticsColumn.java index e5ad325bdf89..cd65f8081200 100644 --- a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/EventAnalyticsColumn.java +++ b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/table/EventAnalyticsColumn.java @@ -49,184 +49,12 @@ @NoArgsConstructor(access = lombok.AccessLevel.PRIVATE) public final class EventAnalyticsColumn { - // Common columns that work across all databases - - private static final AnalyticsTableColumn EVENT = - AnalyticsTableColumn.builder() - .name(EventAnalyticsColumnName.EVENT_COLUMN_NAME) - .dataType(CHARACTER_11) - .nullable(NOT_NULL) - .selectExpression("ev.uid") - .build(); - private static final AnalyticsTableColumn ENROLLMENT = - AnalyticsTableColumn.builder() - .name(EventAnalyticsColumnName.ENROLLMENT_COLUMN_NAME) - .dataType(CHARACTER_11) - .nullable(NOT_NULL) - .selectExpression("en.uid") - .build(); public static final AnalyticsTableColumn TRACKED_ENTITY = AnalyticsTableColumn.builder() .name(EventAnalyticsColumnName.TRACKED_ENTITY_COLUMN_NAME) .dataType(CHARACTER_11) .selectExpression("te.uid") .build(); - private static final AnalyticsTableColumn PS = - AnalyticsTableColumn.builder() - .name(EventAnalyticsColumnName.PS_COLUMN_NAME) - .dataType(CHARACTER_11) - .nullable(NOT_NULL) - .selectExpression("ps.uid") - .build(); - private static final AnalyticsTableColumn AO = - AnalyticsTableColumn.builder() - .name(EventAnalyticsColumnName.AO_COLUMN_NAME) - .dataType(CHARACTER_11) - .nullable(NOT_NULL) - .selectExpression("acs.categoryoptioncombouid") - .build(); - private static final AnalyticsTableColumn ENROLLMENT_DATE = - AnalyticsTableColumn.builder() - .name(EventAnalyticsColumnName.ENROLLMENT_DATE_COLUMN_NAME) - .dataType(TIMESTAMP) - .selectExpression("en.enrollmentdate") - .build(); - private static final AnalyticsTableColumn ENROLLMENT_OCCURRED_DATE = - AnalyticsTableColumn.builder() - .name(EventAnalyticsColumnName.ENROLLMENT_OCCURRED_DATE_COLUMN_NAME) - .dataType(TIMESTAMP) - .selectExpression("en.occurreddate") - .build(); - private static final AnalyticsTableColumn OCCURRED_DATE = - AnalyticsTableColumn.builder() - .name(EventAnalyticsColumnName.OCCURRED_DATE_COLUMN_NAME) - .dataType(TIMESTAMP) - .selectExpression("ev.occurreddate") - .build(); - private static final AnalyticsTableColumn SCHEDULED_DATE = - AnalyticsTableColumn.builder() - .name(EventAnalyticsColumnName.SCHEDULED_DATE_COLUMN_NAME) - .dataType(TIMESTAMP) - .selectExpression("ev.scheduleddate") - .build(); - private static final AnalyticsTableColumn COMPLETED_DATE = - AnalyticsTableColumn.builder() - .name(EventAnalyticsColumnName.COMPLETED_DATE_COLUMN_NAME) - .dataType(TIMESTAMP) - .selectExpression("ev.completeddate") - .build(); - - /* - * DHIS2-14981: Use the client-side timestamp if available, otherwise - * the server-side timestamp. Applies to both created and lastupdated. - */ - private static final AnalyticsTableColumn CREATED = - AnalyticsTableColumn.builder() - .name(EventAnalyticsColumnName.CREATED_COLUMN_NAME) - .dataType(TIMESTAMP) - .selectExpression(firstIfNotNullOrElse("ev.createdatclient", "ev.created")) - .build(); - private static final AnalyticsTableColumn LAST_UPDATED = - AnalyticsTableColumn.builder() - .name(EventAnalyticsColumnName.LAST_UPDATED_COLUMN_NAME) - .dataType(TIMESTAMP) - .selectExpression(firstIfNotNullOrElse("ev.lastupdatedatclient", "ev.lastupdated")) - .build(); - private static final AnalyticsTableColumn STOREDBY = - AnalyticsTableColumn.builder() - .name(EventAnalyticsColumnName.STORED_BY_COLUMN_NAME) - .dataType(VARCHAR_255) - .selectExpression("ev.storedby") - .build(); - - private static final AnalyticsTableColumn EVENT_STATUS = - AnalyticsTableColumn.builder() - .name(EventAnalyticsColumnName.EVENT_STATUS_COLUMN_NAME) - .dataType(VARCHAR_50) - .selectExpression("ev.status") - .build(); - private static final AnalyticsTableColumn ENROLLMENT_STATUS = - AnalyticsTableColumn.builder() - .name(EventAnalyticsColumnName.ENROLLMENT_STATUS_COLUMN_NAME) - .dataType(VARCHAR_50) - .selectExpression("en.status") - .build(); - private static final AnalyticsTableColumn EVENT_GEOMETRY = - AnalyticsTableColumn.builder() - .name(EventAnalyticsColumnName.EVENT_GEOMETRY_COLUMN_NAME) - .dataType(GEOMETRY) - .selectExpression("ev.geometry") - .indexType(IndexType.GIST) - .build(); - // TODO latitude and longitude deprecated in 2.30, remove in 2.33 - private static final AnalyticsTableColumn LONGITUDE = - AnalyticsTableColumn.builder() - .name(EventAnalyticsColumnName.LONGITUDE_COLUMN_NAME) - .dataType(DOUBLE) - .selectExpression( - "CASE WHEN 'POINT' = GeometryType(ev.geometry) THEN ST_X(ev.geometry) ELSE null END") - .build(); - private static final AnalyticsTableColumn LATITUDE = - AnalyticsTableColumn.builder() - .name(EventAnalyticsColumnName.LATITUDE_COLUMN_NAME) - .dataType(DOUBLE) - .selectExpression( - "CASE WHEN 'POINT' = GeometryType(ev.geometry) THEN ST_Y(ev.geometry) ELSE null END") - .build(); - private static final AnalyticsTableColumn OU = - AnalyticsTableColumn.builder() - .name(EventAnalyticsColumnName.OU_COLUMN_NAME) - .dataType(CHARACTER_11) - .nullable(NOT_NULL) - .selectExpression("ou.uid") - .build(); - private static final AnalyticsTableColumn OU_NAME = - AnalyticsTableColumn.builder() - .name(EventAnalyticsColumnName.OU_NAME_COLUMN_NAME) - .dataType(TEXT) - .nullable(NOT_NULL) - .selectExpression("ou.name") - .build(); - private static final AnalyticsTableColumn OU_CODE = - AnalyticsTableColumn.builder() - .name(EventAnalyticsColumnName.OU_CODE_COLUMN_NAME) - .dataType(TEXT) - .selectExpression("ou.code") - .build(); - private static final AnalyticsTableColumn OU_LEVEL = - AnalyticsTableColumn.builder() - .name(EventAnalyticsColumnName.OU_LEVEL_COLUMN_NAME) - .dataType(INTEGER) - .selectExpression("ous.level") - .build(); - private static final AnalyticsTableColumn OU_GEOMETRY = - AnalyticsTableColumn.builder() - .name(EventAnalyticsColumnName.OU_GEOMETRY_COLUMN_NAME) - .dataType(GEOMETRY) - .selectExpression("ou.geometry") - .indexType(IndexType.GIST) - .build(); - private static final AnalyticsTableColumn ENROLLMENT_GEOMETRY = - AnalyticsTableColumn.builder() - .name(EventAnalyticsColumnName.ENROLLMENT_GEOMETRY_COLUMN_NAME) - .dataType(GEOMETRY) - .selectExpression("en.geometry") - .indexType(IndexType.GIST) - .build(); - private static final AnalyticsTableColumn REGISTRATION_OU = - AnalyticsTableColumn.builder() - .name(EventAnalyticsColumnName.REGISTRATION_OU_COLUMN_NAME) - .dataType(CHARACTER_11) - .nullable(NOT_NULL) - .selectExpression("coalesce(registrationou.uid,ou.uid)") - .build(); - private static final AnalyticsTableColumn ENROLLMENT_OU = - AnalyticsTableColumn.builder() - .name(EventAnalyticsColumnName.ENROLLMENT_OU_COLUMN_NAME) - .dataType(CHARACTER_11) - .nullable(NOT_NULL) - .selectExpression("coalesce(enrollmentou.uid,ou.uid)") - .build(); public static final AnalyticsTableColumn TRACKED_ENTITY_GEOMETRY = AnalyticsTableColumn.builder() .name(EventAnalyticsColumnName.TRACKED_ENTITY_GEOMETRY_COLUMN_NAME) @@ -234,35 +62,189 @@ public final class EventAnalyticsColumn { .selectExpression("te.geometry") .build(); - private static final List COMMON_COLUMNS = - List.of( - EVENT, - ENROLLMENT, - PS, - AO, - ENROLLMENT_DATE, - ENROLLMENT_OCCURRED_DATE, - OCCURRED_DATE, - SCHEDULED_DATE, - COMPLETED_DATE, - CREATED, - LAST_UPDATED, - STOREDBY, - EVENT_STATUS, - ENROLLMENT_STATUS, - OU, - OU_NAME, - OU_CODE, - OU_LEVEL, - REGISTRATION_OU, - ENROLLMENT_OU); + /** + * Returns a list of {@link AnalyticsTableColumn}. + * + * @param sqlBuilder the {@link SqlBuilder}. + * @return a list of {@link AnalyticsTableColumn}. + */ + public static List getColumns(SqlBuilder sqlBuilder) { + List columns = new ArrayList<>(); + columns.addAll(getCommonColumns(sqlBuilder)); + columns.addAll(getJsonColumns(sqlBuilder)); + + if (sqlBuilder.supportsGeospatialData()) { + columns.addAll(getGeometryColumns(sqlBuilder)); + } + + return columns; + } + + /** + * Returns a list of {@link AnalyticsTableColumn}. + * + * @param sqlBuilder the {@link SqlBuilder}. + * @return a list of {@link AnalyticsTableColumn}. + */ + private static List getCommonColumns(SqlBuilder sqlBuilder) { + return List.of( + AnalyticsTableColumn.builder() + .name(EventAnalyticsColumnName.EVENT_COLUMN_NAME) + .dataType(CHARACTER_11) + .nullable(NOT_NULL) + .selectExpression("ev.uid") + .build(), + AnalyticsTableColumn.builder() + .name(EventAnalyticsColumnName.ENROLLMENT_COLUMN_NAME) + .dataType(CHARACTER_11) + .nullable(NOT_NULL) + .selectExpression("en.uid") + .build(), + AnalyticsTableColumn.builder() + .name(EventAnalyticsColumnName.PS_COLUMN_NAME) + .dataType(CHARACTER_11) + .nullable(NOT_NULL) + .selectExpression("ps.uid") + .build(), + AnalyticsTableColumn.builder() + .name(EventAnalyticsColumnName.AO_COLUMN_NAME) + .dataType(CHARACTER_11) + .nullable(NOT_NULL) + .selectExpression("acs.categoryoptioncombouid") + .build(), + AnalyticsTableColumn.builder() + .name(EventAnalyticsColumnName.ENROLLMENT_DATE_COLUMN_NAME) + .dataType(TIMESTAMP) + .selectExpression("en.enrollmentdate") + .build(), + AnalyticsTableColumn.builder() + .name(EventAnalyticsColumnName.ENROLLMENT_OCCURRED_DATE_COLUMN_NAME) + .dataType(TIMESTAMP) + .selectExpression("en.occurreddate") + .build(), + AnalyticsTableColumn.builder() + .name(EventAnalyticsColumnName.OCCURRED_DATE_COLUMN_NAME) + .dataType(TIMESTAMP) + .selectExpression("ev.occurreddate") + .build(), + AnalyticsTableColumn.builder() + .name(EventAnalyticsColumnName.SCHEDULED_DATE_COLUMN_NAME) + .dataType(TIMESTAMP) + .selectExpression("ev.scheduleddate") + .build(), + AnalyticsTableColumn.builder() + .name(EventAnalyticsColumnName.COMPLETED_DATE_COLUMN_NAME) + .dataType(TIMESTAMP) + .selectExpression("ev.completeddate") + .build(), + AnalyticsTableColumn.builder() + .name(EventAnalyticsColumnName.CREATED_COLUMN_NAME) + .dataType(TIMESTAMP) + .selectExpression(firstIfNotNullOrElse("ev.createdatclient", "ev.created")) + .build(), + AnalyticsTableColumn.builder() + .name(EventAnalyticsColumnName.LAST_UPDATED_COLUMN_NAME) + .dataType(TIMESTAMP) + .selectExpression(firstIfNotNullOrElse("ev.lastupdatedatclient", "ev.lastupdated")) + .build(), + AnalyticsTableColumn.builder() + .name(EventAnalyticsColumnName.STORED_BY_COLUMN_NAME) + .dataType(VARCHAR_255) + .selectExpression("ev.storedby") + .build(), + AnalyticsTableColumn.builder() + .name(EventAnalyticsColumnName.EVENT_STATUS_COLUMN_NAME) + .dataType(VARCHAR_50) + .selectExpression("ev.status") + .build(), + AnalyticsTableColumn.builder() + .name(EventAnalyticsColumnName.ENROLLMENT_STATUS_COLUMN_NAME) + .dataType(VARCHAR_50) + .selectExpression("en.status") + .build(), + AnalyticsTableColumn.builder() + .name(EventAnalyticsColumnName.OU_COLUMN_NAME) + .dataType(CHARACTER_11) + .nullable(NOT_NULL) + .selectExpression("ou.uid") + .build(), + AnalyticsTableColumn.builder() + .name(EventAnalyticsColumnName.OU_NAME_COLUMN_NAME) + .dataType(TEXT) + .nullable(NOT_NULL) + .selectExpression("ou.name") + .build(), + AnalyticsTableColumn.builder() + .name(EventAnalyticsColumnName.OU_CODE_COLUMN_NAME) + .dataType(TEXT) + .selectExpression("ou.code") + .build(), + AnalyticsTableColumn.builder() + .name(EventAnalyticsColumnName.OU_LEVEL_COLUMN_NAME) + .dataType(INTEGER) + .selectExpression("ous.level") + .build(), + AnalyticsTableColumn.builder() + .name(EventAnalyticsColumnName.REGISTRATION_OU_COLUMN_NAME) + .dataType(CHARACTER_11) + .nullable(NOT_NULL) + .selectExpression("coalesce(registrationou.uid,ou.uid)") + .build(), + AnalyticsTableColumn.builder() + .name(EventAnalyticsColumnName.ENROLLMENT_OU_COLUMN_NAME) + .dataType(CHARACTER_11) + .nullable(NOT_NULL) + .selectExpression("coalesce(enrollmentou.uid,ou.uid)") + .build()); + } - // Geometry-specific columns - private static final List GEOMETRY_COLUMNS = - List.of(EVENT_GEOMETRY, OU_GEOMETRY, ENROLLMENT_GEOMETRY, LONGITUDE, LATITUDE); + /** + * Returns a list of geometry {@link AnalyticsTableColumn}. + * + * @param sqlBuilder the {@link SqlBuilder}. + * @return a list of {@link AnalyticsTableColumn}. + */ + private static List getGeometryColumns(SqlBuilder sqlBuilder) { + return List.of( + AnalyticsTableColumn.builder() + .name(EventAnalyticsColumnName.EVENT_GEOMETRY_COLUMN_NAME) + .dataType(GEOMETRY) + .selectExpression("ev.geometry") + .indexType(IndexType.GIST) + .build(), + AnalyticsTableColumn.builder() + .name(EventAnalyticsColumnName.OU_GEOMETRY_COLUMN_NAME) + .dataType(GEOMETRY) + .selectExpression("ou.geometry") + .indexType(IndexType.GIST) + .build(), + AnalyticsTableColumn.builder() + .name(EventAnalyticsColumnName.ENROLLMENT_GEOMETRY_COLUMN_NAME) + .dataType(GEOMETRY) + .selectExpression("en.geometry") + .indexType(IndexType.GIST) + .build(), + AnalyticsTableColumn.builder() + .name(EventAnalyticsColumnName.LONGITUDE_COLUMN_NAME) + .dataType(DOUBLE) + .selectExpression( + "CASE WHEN 'POINT' = GeometryType(ev.geometry) THEN ST_X(ev.geometry) ELSE null END") + .build(), + AnalyticsTableColumn.builder() + .name(EventAnalyticsColumnName.LATITUDE_COLUMN_NAME) + .dataType(DOUBLE) + .selectExpression( + "CASE WHEN 'POINT' = GeometryType(ev.geometry) THEN ST_Y(ev.geometry) ELSE null END") + .build()); + } - // JSON-specific columns (might vary by database) - private static List createJsonColumns(SqlBuilder sqlBuilder) { + /** + * Returns a list of {@link AnalyticsTableColumn}. + * + * @param sqlBuilder the {@link SqlBuilder}. + * @return a list of {@link AnalyticsTableColumn}. + */ + private static List getJsonColumns(SqlBuilder sqlBuilder) { return List.of( AnalyticsTableColumn.builder() .name(EventAnalyticsColumnName.CREATED_BY_USERNAME_COLUMN_NAME) @@ -325,20 +307,6 @@ private static List createJsonColumns(SqlBuilder sqlBuilde .build()); } - /** Returns the appropriate set of columns based on the SqlBuilder type */ - public static List getColumns(SqlBuilder sqlBuilder) { - List columns = new ArrayList<>(COMMON_COLUMNS); - - // Add database-specific columns based on SqlBuilder capabilities - if (sqlBuilder.supportsGeospatialData()) { - columns.addAll(GEOMETRY_COLUMNS); - } - - columns.addAll(createJsonColumns(sqlBuilder)); - - return columns; - } - /** * Returns a SQL expression that returns the first argument if it is not null, otherwise the * second argument.