Skip to content

Commit

Permalink
Merge pull request #642 from imranmaj/alerts
Browse files Browse the repository at this point in the history
Add alerts
  • Loading branch information
DwayneJengSage authored Feb 6, 2023
2 parents 134d03a + dab57ee commit e6fc682
Show file tree
Hide file tree
Showing 35 changed files with 2,439 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
import org.sagebionetworks.bridge.models.schedules2.adherence.AdherenceRecord;
import org.sagebionetworks.bridge.models.schedules2.adherence.weekly.WeeklyAdherenceReport;
import org.sagebionetworks.bridge.models.schedules2.timelines.TimelineMetadata;
import org.sagebionetworks.bridge.models.studies.Alert;
import org.sagebionetworks.bridge.models.studies.Demographic;
import org.sagebionetworks.bridge.models.studies.DemographicUser;
import org.sagebionetworks.bridge.models.studies.DemographicValue;
Expand Down Expand Up @@ -668,6 +669,7 @@ public SessionFactory hibernateSessionFactory(TagEventListener listener) {
metadataSources.addAnnotatedClass(Demographic.class);
metadataSources.addAnnotatedClass(DemographicUser.class);
metadataSources.addAnnotatedClass(DemographicValue.class);
metadataSources.addAnnotatedClass(Alert.class);

SessionFactory factory = metadataSources.buildMetadata().buildSessionFactory();

Expand Down
69 changes: 69 additions & 0 deletions src/main/java/org/sagebionetworks/bridge/dao/AlertDao.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package org.sagebionetworks.bridge.dao;

import java.util.List;
import java.util.Optional;
import java.util.Set;

import org.sagebionetworks.bridge.models.PagedResourceList;
import org.sagebionetworks.bridge.models.studies.Alert;
import org.sagebionetworks.bridge.models.studies.Alert.AlertCategory;
import org.sagebionetworks.bridge.models.studies.AlertCategoriesAndCounts;

public interface AlertDao {
/**
* Creates an alert.
*/
void createAlert(Alert alert);

/**
* Deletes a specific alert.
*/
void deleteAlert(Alert alert);

/**
* Fetches a single alert with filters.
*/
Optional<Alert> getAlert(String studyId, String appId, String userId, AlertCategory category);

/**
* Fetches a single alert by id.
*/
Optional<Alert> getAlertById(String alertId);

/**
* Fetches alerts for a study.
*/
PagedResourceList<Alert> getAlerts(String appId, String studyId, int offsetBy, int pageSize,
Set<AlertCategory> alertCategories);

/**
* Batch deletes alerts given a list of IDs of alerts to delete.
*/
void deleteAlerts(List<String> alertIds);

/**
* Deletes all alerts for all users in a study.
*/
void deleteAlertsForStudy(String appId, String studyId);

/**
* Deletes all alerts for a specific user in an app.
*/
void deleteAlertsForUserInApp(String appId, String userId);

/**
* Deletes all alerts for a specific user in a study.
*/
void deleteAlertsForUserInStudy(String appId, String studyId, String userId);

/**
* Fetches a list of alert categories and the number of alerts within that
* category for a study.
*/
AlertCategoriesAndCounts getAlertCategoriesAndCounts(String appId, String studyId);

/**
* Marks all specified alerts as read or unread, as specified.
*/
void setAlertsReadState(List<String> alertIds, boolean read);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
package org.sagebionetworks.bridge.hibernate;

import java.util.List;
import java.util.Optional;
import java.util.Set;

import javax.annotation.Resource;

import org.sagebionetworks.bridge.dao.AlertDao;
import org.sagebionetworks.bridge.hibernate.QueryBuilder.WhereClauseBuilder;
import org.sagebionetworks.bridge.models.PagedResourceList;
import org.sagebionetworks.bridge.models.SearchTermPredicate;
import org.sagebionetworks.bridge.models.studies.Alert;
import org.sagebionetworks.bridge.models.studies.Alert.AlertCategory;
import org.sagebionetworks.bridge.models.studies.AlertCategoriesAndCounts;
import org.sagebionetworks.bridge.models.studies.AlertCategoryAndCount;
import org.springframework.stereotype.Component;

@Component
public class HibernateAlertDao implements AlertDao {
private HibernateHelper hibernateHelper;

@Resource(name = "mysqlHibernateHelper")
public final void setHibernateHelper(HibernateHelper hibernateHelper) {
this.hibernateHelper = hibernateHelper;
}

@Override
public void createAlert(Alert alert) {
hibernateHelper.create(alert);
}

@Override
public void deleteAlert(Alert alert) {
hibernateHelper.deleteById(Alert.class, alert.getId());
}

@Override
public Optional<Alert> getAlert(String studyId, String appId, String userId, AlertCategory category) {
QueryBuilder builder = new QueryBuilder();
builder.append("FROM Alert a");
WhereClauseBuilder where = builder.startWhere(SearchTermPredicate.AND);
where.append("a.studyId = :studyId", "studyId", studyId);
where.append("a.appId = :appId", "appId", appId);
where.append("a.userId = :userId", "userId", userId);
where.append("a.category = :category", "category", category);
return hibernateHelper.queryGetOne(builder.getQuery(), builder.getParameters(), Alert.class);
}

@Override
public Optional<Alert> getAlertById(String alertId) {
return Optional.ofNullable(hibernateHelper.getById(Alert.class, alertId));
}

@Override
public PagedResourceList<Alert> getAlerts(String appId, String studyId, int offsetBy, int pageSize,
Set<AlertCategory> alertCategories) {
QueryBuilder builder = new QueryBuilder();
builder.append("FROM Alert a");
WhereClauseBuilder where = builder.startWhere(SearchTermPredicate.AND);
where.append("a.appId = :appId", "appId", appId);
where.append("a.studyId = :studyId", "studyId", studyId);
where.append("a.category in (:alertCategories)", "alertCategories", alertCategories);
builder.append("ORDER BY createdOn DESC");
int count = hibernateHelper.queryCount("SELECT COUNT(*) " + builder.getQuery(), builder.getParameters());
List<Alert> alerts = hibernateHelper.queryGet(builder.getQuery(), builder.getParameters(), offsetBy, pageSize,
Alert.class);
return new PagedResourceList<>(alerts, count, true)
.withRequestParam("offsetBy", offsetBy)
.withRequestParam("pageSize", pageSize);
}

@Override
public void deleteAlerts(List<String> alertIds) {
QueryBuilder builder = new QueryBuilder();
builder.append("DELETE FROM Alert a");
WhereClauseBuilder where = builder.startWhere(SearchTermPredicate.AND);
where.append("a.id in (:alertIds)", "alertIds", alertIds);
hibernateHelper.query(builder.getQuery(), builder.getParameters());
}

@Override
public void deleteAlertsForStudy(String appId, String studyId) {
QueryBuilder builder = new QueryBuilder();
builder.append("DELETE FROM Alert a");
WhereClauseBuilder where = builder.startWhere(SearchTermPredicate.AND);
where.append("a.appId = :appId", "appId", appId);
where.append("a.studyId = :studyId", "studyId", studyId);
hibernateHelper.query(builder.getQuery(), builder.getParameters());
}

@Override
public void deleteAlertsForUserInApp(String appId, String userId) {
QueryBuilder builder = new QueryBuilder();
builder.append("DELETE FROM Alert a");
WhereClauseBuilder where = builder.startWhere(SearchTermPredicate.AND);
where.append("a.appId = :appId", "appId", appId);
where.append("a.userId = :userId", "userId", userId);
hibernateHelper.query(builder.getQuery(), builder.getParameters());
}

@Override
public void deleteAlertsForUserInStudy(String appId, String studyId, String userId) {
QueryBuilder builder = new QueryBuilder();
builder.append("DELETE FROM Alert a");
WhereClauseBuilder where = builder.startWhere(SearchTermPredicate.AND);
where.append("a.appId = :appId", "appId", appId);
where.append("a.studyId = :studyId", "studyId", studyId);
where.append("a.userId = :userId", "userId", userId);
hibernateHelper.query(builder.getQuery(), builder.getParameters());
}

@Override
public AlertCategoriesAndCounts getAlertCategoriesAndCounts(String appId, String studyId) {
QueryBuilder builder = new QueryBuilder();
builder.append("SELECT NEW " + AlertCategoryAndCount.class.getName() + "(category, COUNT(*) as count)");
builder.append("FROM Alert a");
WhereClauseBuilder where = builder.startWhere(SearchTermPredicate.AND);
where.append("a.appId = :appId", "appId", appId);
where.append("a.studyId = :studyId", "studyId", studyId);
builder.append("GROUP BY category");
builder.append("ORDER BY category");
List<AlertCategoryAndCount> alertCategoriesAndCounts = hibernateHelper.queryGet(builder.getQuery(),
builder.getParameters(), null, null, AlertCategoryAndCount.class);
return new AlertCategoriesAndCounts(alertCategoriesAndCounts);
}

@Override
public void setAlertsReadState(List<String> alertIds, boolean read) {
QueryBuilder builder = new QueryBuilder();
builder.append("UPDATE Alert a");
builder.append("SET a.read = :read", "read", read);
WhereClauseBuilder where = builder.startWhere(SearchTermPredicate.AND);
where.append("a.id in (:alertIds)", "alertIds", alertIds);
hibernateHelper.query(builder.getQuery(), builder.getParameters());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ public int nativeQueryUpdate(String queryString, Map<String,Object> parameters)
}

/**
* Execute SQL query with no return value, like a batch delete.
* Execute HQL query with no return value, like a batch delete.
*/
public void query(String queryString, Map<String,Object> parameters) {
executeWithExceptionHandling(null, session -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public String getEventId(String objectId, ActivityEventType eventType, String an
*/
TIMELINE_RETRIEVED(IMMUTABLE) {
public String getEventId(String objectId, ActivityEventType eventType, String answerValue) {
return this.name().toLowerCase();
return TIMELINE_RETRIEVED_ID;
}
},
/**
Expand Down Expand Up @@ -180,9 +180,11 @@ public String getEventId(String objectId, ActivityEventType eventType, String an
}

public abstract String getEventId(String objectId, ActivityEventType eventType, String answerValue);

public static final String TIMELINE_RETRIEVED_ID = TIMELINE_RETRIEVED.name().toLowerCase();

private final ActivityEventUpdateType updateType;

public ActivityEventUpdateType getUpdateType() {
return updateType;
}
Expand Down
Loading

0 comments on commit e6fc682

Please sign in to comment.