Skip to content

Commit 073ee51

Browse files
Merge pull request #672 from DwayneJengSage/dev3
DHP-1071 CSV Storage API
2 parents e23516f + 38b5870 commit 073ee51

25 files changed

+1831
-3
lines changed

src/main/java/org/sagebionetworks/bridge/config/SpringConfig.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@
110110
import org.sagebionetworks.bridge.hibernate.HibernateAccountSecret;
111111
import org.sagebionetworks.bridge.hibernate.HibernateEnrollment;
112112
import org.sagebionetworks.bridge.hibernate.HibernateHelper;
113+
import org.sagebionetworks.bridge.hibernate.HibernateUploadTableRow;
113114
import org.sagebionetworks.bridge.hibernate.MySQLHibernatePersistenceExceptionConverter;
114115
import org.sagebionetworks.bridge.hibernate.HibernateSharedModuleMetadata;
115116
import org.sagebionetworks.bridge.hibernate.HibernateStudy;
@@ -645,6 +646,7 @@ public SessionFactory hibernateSessionFactory(TagEventListener listener) {
645646
MetadataSources metadataSources = new MetadataSources(reg);
646647
metadataSources.addAnnotatedClass(HibernateAccount.class);
647648
metadataSources.addAnnotatedClass(HibernateStudy.class);
649+
metadataSources.addAnnotatedClass(HibernateUploadTableRow.class);
648650
metadataSources.addAnnotatedClass(HibernateEnrollment.class);
649651
metadataSources.addAnnotatedClass(HibernateSharedModuleMetadata.class);
650652
metadataSources.addAnnotatedClass(HibernateAccountSecret.class);
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.sagebionetworks.bridge.dao;
2+
3+
import java.util.Optional;
4+
5+
import org.sagebionetworks.bridge.models.PagedResourceList;
6+
import org.sagebionetworks.bridge.upload.UploadTableRow;
7+
import org.sagebionetworks.bridge.upload.UploadTableRowQuery;
8+
9+
/** DAO to interact with upload table rows. */
10+
public interface UploadTableRowDao {
11+
/** Delete a single upload table row. */
12+
void deleteUploadTableRow(String appId, String studyId, String recordId);
13+
14+
/** Get a single upload table row. */
15+
Optional<UploadTableRow> getUploadTableRow(String appId, String studyId, String recordId);
16+
17+
/** Query for upload table rows. */
18+
PagedResourceList<UploadTableRow> queryUploadTableRows(UploadTableRowQuery query);
19+
20+
/** Create a new upload table row, or overwrite it if the row already exists. */
21+
void saveUploadTableRow(UploadTableRow row);
22+
}
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
package org.sagebionetworks.bridge.hibernate;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
import javax.persistence.Convert;
6+
import javax.persistence.Entity;
7+
import javax.persistence.Id;
8+
import javax.persistence.IdClass;
9+
import javax.persistence.Table;
10+
11+
import org.joda.time.DateTime;
12+
13+
import org.sagebionetworks.bridge.json.BridgeTypeName;
14+
import org.sagebionetworks.bridge.upload.UploadTableRow;
15+
16+
/** Hibernate implementation of UploadTableRow. */
17+
@BridgeTypeName("UploadTableRow")
18+
@Entity
19+
@IdClass(HibernateUploadTableRowId.class)
20+
@Table(name = "UploadTableRows")
21+
public class HibernateUploadTableRow implements UploadTableRow {
22+
private String appId;
23+
private String studyId;
24+
private String recordId;
25+
private String assessmentGuid;
26+
private DateTime createdOn;
27+
private boolean testData;
28+
private String healthCode;
29+
private Integer participantVersion;
30+
private Map<String, String> metadata = new HashMap<>();
31+
private Map<String, String> data = new HashMap<>();
32+
33+
@Id
34+
@Override
35+
public String getAppId() {
36+
return appId;
37+
}
38+
39+
@Override
40+
public void setAppId(String appId) {
41+
this.appId = appId;
42+
}
43+
44+
@Id
45+
@Override
46+
public String getStudyId() {
47+
return studyId;
48+
}
49+
50+
@Override
51+
public void setStudyId(String studyId) {
52+
this.studyId = studyId;
53+
}
54+
55+
@Id
56+
@Override
57+
public String getRecordId() {
58+
return recordId;
59+
}
60+
61+
@Override
62+
public void setRecordId(String recordId) {
63+
this.recordId = recordId;
64+
}
65+
66+
@Override
67+
public String getAssessmentGuid() {
68+
return assessmentGuid;
69+
}
70+
71+
@Override
72+
public void setAssessmentGuid(String assessmentGuid) {
73+
this.assessmentGuid = assessmentGuid;
74+
}
75+
76+
@Convert(converter = DateTimeToLongAttributeConverter.class)
77+
@Override
78+
public DateTime getCreatedOn() {
79+
return createdOn;
80+
}
81+
82+
@Override
83+
public void setCreatedOn(DateTime createdOn) {
84+
this.createdOn = createdOn;
85+
}
86+
87+
@Override
88+
public boolean isTestData() {
89+
return testData;
90+
}
91+
92+
@Override
93+
public void setTestData(boolean testData) {
94+
this.testData = testData;
95+
}
96+
97+
@Override
98+
public String getHealthCode() {
99+
return healthCode;
100+
}
101+
102+
@Override
103+
public void setHealthCode(String healthCode) {
104+
this.healthCode = healthCode;
105+
}
106+
107+
@Override
108+
public Integer getParticipantVersion() {
109+
return participantVersion;
110+
}
111+
112+
@Override
113+
public void setParticipantVersion(Integer participantVersion) {
114+
this.participantVersion = participantVersion;
115+
}
116+
117+
@Convert(converter = StringMapConverter.class)
118+
@Override
119+
public Map<String, String> getMetadata() {
120+
return metadata;
121+
}
122+
123+
@Override
124+
public void setMetadata(Map<String, String> metadata) {
125+
this.metadata = metadata != null ? metadata : new HashMap<>();
126+
}
127+
128+
@Convert(converter = StringMapConverter.class)
129+
@Override
130+
public Map<String, String> getData() {
131+
return data;
132+
}
133+
134+
@Override
135+
public void setData(Map<String, String> data) {
136+
this.data = data != null ? data : new HashMap<>();
137+
}
138+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package org.sagebionetworks.bridge.hibernate;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
import java.util.Optional;
6+
import javax.annotation.Resource;
7+
8+
import org.springframework.stereotype.Component;
9+
10+
import org.sagebionetworks.bridge.BridgeConstants;
11+
import org.sagebionetworks.bridge.dao.UploadTableRowDao;
12+
import org.sagebionetworks.bridge.models.PagedResourceList;
13+
import org.sagebionetworks.bridge.upload.UploadTableRow;
14+
import org.sagebionetworks.bridge.upload.UploadTableRowQuery;
15+
16+
/** Hibernate implementation of UploadTableRowDao. */
17+
@Component
18+
public class HibernateUploadTableRowDao implements UploadTableRowDao {
19+
private HibernateHelper hibernateHelper;
20+
21+
@Resource(name = "basicHibernateHelper")
22+
public final void setHibernateHelper(HibernateHelper hibernateHelper) {
23+
this.hibernateHelper = hibernateHelper;
24+
}
25+
26+
@Override
27+
public void deleteUploadTableRow(String appId, String studyId, String recordId) {
28+
HibernateUploadTableRowId id = new HibernateUploadTableRowId(appId, studyId, recordId);
29+
hibernateHelper.deleteById(HibernateUploadTableRow.class, id);
30+
}
31+
32+
@Override
33+
public Optional<UploadTableRow> getUploadTableRow(String appId, String studyId, String recordId) {
34+
HibernateUploadTableRowId id = new HibernateUploadTableRowId(appId, studyId, recordId);
35+
UploadTableRow row = hibernateHelper.getById(HibernateUploadTableRow.class, id);
36+
return Optional.ofNullable(row);
37+
}
38+
39+
@Override
40+
public PagedResourceList<UploadTableRow> queryUploadTableRows(UploadTableRowQuery query) {
41+
QueryBuilder builder = new QueryBuilder();
42+
builder.append("FROM HibernateUploadTableRow");
43+
44+
// appId and studyId are always required. (This is validated in the service.)
45+
builder.append("WHERE appId = :appId AND studyId = :studyId");
46+
builder.getParameters().put("appId", query.getAppId());
47+
builder.getParameters().put("studyId", query.getStudyId());
48+
49+
// Filter by assessment.
50+
if (query.getAssessmentGuid() != null) {
51+
builder.append("AND assessmentGuid = :assessmentGuid");
52+
builder.getParameters().put("assessmentGuid", query.getAssessmentGuid());
53+
}
54+
55+
// Filter by date range.
56+
if (query.getStartTime() != null) {
57+
builder.append("AND createdOn >= :startDate");
58+
builder.getParameters().put("startDate", query.getStartTime());
59+
}
60+
if (query.getEndTime() != null) {
61+
builder.append("AND createdOn < :endDate");
62+
builder.getParameters().put("endDate", query.getEndTime());
63+
}
64+
65+
// Include test data?
66+
if (!query.getIncludeTestData()) {
67+
builder.append("AND testData = 0");
68+
}
69+
70+
// Get total.
71+
int total = hibernateHelper.queryCount("SELECT COUNT(DISTINCT recordId) " + builder.getQuery(),
72+
builder.getParameters());
73+
74+
// Start and count.
75+
Integer start = query.getStart();
76+
if (start == null) {
77+
start = 0;
78+
}
79+
Integer pageSize = query.getPageSize();
80+
if (pageSize == null) {
81+
pageSize = BridgeConstants.API_DEFAULT_PAGE_SIZE;
82+
}
83+
84+
// Query.
85+
List<HibernateUploadTableRow> hibernateList = hibernateHelper.queryGet(builder.getQuery(),
86+
builder.getParameters(), start, pageSize, HibernateUploadTableRow.class);
87+
88+
// Because of Java generic typing issues, we need to convert this to a non-Hibernate UploadTableRow.
89+
List<UploadTableRow> list = new ArrayList<>(hibernateList);
90+
return new PagedResourceList<>(list, total)
91+
.withRequestParam("assessmentGuid", query.getAssessmentGuid())
92+
.withRequestParam("startTime", query.getStartTime())
93+
.withRequestParam("endTime", query.getEndTime())
94+
.withRequestParam("includeTestData", query.getIncludeTestData())
95+
.withRequestParam("start", start)
96+
.withRequestParam("pageSize", pageSize);
97+
}
98+
99+
@Override
100+
public void saveUploadTableRow(UploadTableRow row) {
101+
hibernateHelper.saveOrUpdate(row);
102+
}
103+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package org.sagebionetworks.bridge.hibernate;
2+
3+
import java.io.Serializable;
4+
5+
/**
6+
* Represents the composite key for UploadTableRow, which is appId, studyId, and recordId. Default constructor and
7+
* setters are required by Hibernate.
8+
*/
9+
@SuppressWarnings("serial")
10+
public class HibernateUploadTableRowId implements Serializable {
11+
private String appId;
12+
private String studyId;
13+
private String recordId;
14+
15+
public HibernateUploadTableRowId() {
16+
}
17+
18+
public HibernateUploadTableRowId(String appId, String studyId, String recordId) {
19+
this.appId = appId;
20+
this.studyId = studyId;
21+
this.recordId = recordId;
22+
}
23+
24+
public String getAppId() {
25+
return appId;
26+
}
27+
28+
public void setAppId(String appId) {
29+
this.appId = appId;
30+
}
31+
32+
public String getStudyId() {
33+
return studyId;
34+
}
35+
36+
public void setStudyId(String studyId) {
37+
this.studyId = studyId;
38+
}
39+
40+
public String getRecordId() {
41+
return recordId;
42+
}
43+
44+
public void setRecordId(String recordId) {
45+
this.recordId = recordId;
46+
}
47+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.sagebionetworks.bridge.hibernate;
2+
3+
import java.util.Map;
4+
import javax.persistence.Converter;
5+
6+
import com.fasterxml.jackson.core.type.TypeReference;
7+
8+
/** Hibernate converter that serializes a string map to JSON for storage in SQL. */
9+
@Converter
10+
public class StringMapConverter extends BaseJsonAttributeConverter<Map<String, String>> {
11+
static final TypeReference<Map<String, String>> TYPE_REFERENCE = new TypeReference<Map<String, String>>() {};
12+
13+
@Override
14+
public String convertToDatabaseColumn(Map<String, String> map) {
15+
return serialize(map);
16+
}
17+
18+
@Override
19+
public Map<String, String> convertToEntityAttribute(String value) {
20+
return deserialize(value, TYPE_REFERENCE);
21+
}
22+
}

0 commit comments

Comments
 (0)