package org.ohdsi.webapi.service; import java.sql.ResultSet; import java.sql.SQLException; import java.util.*; import java.util.AbstractMap.SimpleEntry; import javax.annotation.PostConstruct; import javax.ws.rs.*; import javax.ws.rs.core.MediaType; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; import org.apache.commons.lang3.StringUtils; import org.ohdsi.sql.SqlRender; import org.ohdsi.sql.SqlTranslate; import org.ohdsi.webapi.report.*; import org.ohdsi.webapi.helper.ResourceHelper; import org.ohdsi.webapi.source.Source; import org.ohdsi.webapi.source.SourceDaimon; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Component; /** * @author fdefalco */ @Path("/cdmresults") @Component public class CDMResultsService extends AbstractDaoService { private CDMResultsAnalysisRunner queryRunner = null; @PostConstruct public void init() { queryRunner = new CDMResultsAnalysisRunner(this.getSourceDialect()); } private final RowMapper<SimpleEntry<Long, Long[]>> rowMapper = new RowMapper<SimpleEntry<Long, Long[]>>() { @Override public SimpleEntry<Long, Long[]> mapRow(final ResultSet resultSet, final int arg1) throws SQLException { long id = resultSet.getLong("concept_id"); long record_count = resultSet.getLong("record_count"); long descendant_record_count = resultSet.getLong("descendant_record_count"); SimpleEntry<Long, Long[]> entry = new SimpleEntry<Long, Long[]>(id, new Long[]{record_count, descendant_record_count}); return entry; } }; @Path("{sourceKey}/conceptRecordCount") @POST @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public List<SimpleEntry<Long, Long[]>> getConceptRecordCount(@PathParam("sourceKey") String sourceKey, String[] identifiers) { Source source = getSourceRepository().findBySourceKey(sourceKey); String resultTableQualifier = source.getTableQualifier(SourceDaimon.DaimonType.Results); String vocabularyTableQualifier = source.getTableQualifier(SourceDaimon.DaimonType.Vocabulary); for (int i = 0; i < identifiers.length; i++) { identifiers[i] = "'" + identifiers[i] + "'"; } String identifierList = StringUtils.join(identifiers, ","); String sql_statement = ResourceHelper.GetResourceAsString("/resources/cdmresults/sql/getConceptRecordCount.sql"); sql_statement = SqlRender.renderSql(sql_statement, new String[]{"resultTableQualifier", "vocabularyTableQualifier", "conceptIdentifiers"}, new String[]{resultTableQualifier, vocabularyTableQualifier, identifierList}); sql_statement = SqlTranslate.translateSql(sql_statement, "sql server", source.getSourceDialect()); return getSourceJdbcTemplate(source).query(sql_statement, rowMapper); } /** * Queries for dashboard report for the sourceKey * * @return CDMDashboard */ @GET @Path("{sourceKey}/dashboard") @Produces(MediaType.APPLICATION_JSON) public CDMDashboard getDashboard(@PathParam("sourceKey") final String sourceKey) { Source source = getSourceRepository().findBySourceKey(sourceKey); CDMDashboard dashboard = queryRunner.getDashboard(getSourceJdbcTemplate(source), source); return dashboard; } /** * Queries for person report for the sourceKey * * @return CDMPersonSummary */ @GET @Path("{sourceKey}/person") @Produces(MediaType.APPLICATION_JSON) public CDMPersonSummary getPerson(@PathParam("sourceKey") final String sourceKey, @DefaultValue("false") @QueryParam("refresh") boolean refresh) { Source source = getSourceRepository().findBySourceKey(sourceKey); CDMPersonSummary person = this.queryRunner.getPersonResults(this.getSourceJdbcTemplate(source), source); return person; } /** * Queries for achilles heel report for the given sourceKey * * @return CDMAchillesHeel */ @GET @Path("{sourceKey}/achillesheel") @Produces(MediaType.APPLICATION_JSON) public CDMAchillesHeel getAchillesHeelReport(@PathParam("sourceKey") final String sourceKey, @DefaultValue("false") @QueryParam("refresh") boolean refresh) { Source source = getSourceRepository().findBySourceKey(sourceKey); CDMAchillesHeel cdmAchillesHeel = this.queryRunner.getHeelResults(this.getSourceJdbcTemplate(source), source); return cdmAchillesHeel; } /** * Queries for data density report for the given sourceKey * * @return CDMDataDensity */ @GET @Path("{sourceKey}/datadensity") @Produces(MediaType.APPLICATION_JSON) public CDMDataDensity getDataDensity(@PathParam("sourceKey") final String sourceKey, @DefaultValue("false") @QueryParam("refresh") boolean refresh) { CDMDataDensity cdmDataDensity; Source source = getSourceRepository().findBySourceKey(sourceKey); cdmDataDensity = this.queryRunner.getDataDensityResults(this.getSourceJdbcTemplate(source), source); return cdmDataDensity; } /** * Queries for death report for the given sourceKey * Queries for treemap results * * @return CDMDataDensity */ @GET @Path("{sourceKey}/death") @Produces(MediaType.APPLICATION_JSON) public CDMDeath getDeath(@PathParam("sourceKey") final String sourceKey, @DefaultValue("false") @QueryParam("refresh") boolean refresh) { CDMDeath cdmDeath; Source source = getSourceRepository().findBySourceKey(sourceKey); cdmDeath = this.queryRunner.getDeathResults(this.getSourceJdbcTemplate(source), source); return cdmDeath; } @Path("{sourceKey}/{conceptId}/drugeraprevalence") @GET @Produces(MediaType.APPLICATION_JSON) public List<DrugEraPrevalence> getDrugEraPrevalenceByGenderAgeYear(@PathParam("sourceKey") String sourceKey, @PathParam("conceptId") String conceptId) { Source source = getSourceRepository().findBySourceKey(sourceKey); String tableQualifier = source.getTableQualifier(SourceDaimon.DaimonType.Results); String vocabularyTableQualifier = source.getTableQualifier(SourceDaimon.DaimonType.Vocabulary); String sql_statement = ResourceHelper.GetResourceAsString("/resources/cdmresults/sql/getDrugEraPrevalenceByGenderAgeYear.sql"); sql_statement = SqlRender.renderSql(sql_statement, new String[]{"ohdsi_database_schema", "vocabulary_database_schema", "conceptId"}, new String[]{tableQualifier, vocabularyTableQualifier, conceptId}); sql_statement = SqlTranslate.translateSql(sql_statement, "sql server", source.getSourceDialect()); List<Map<String, Object>> rows = getSourceJdbcTemplate(source).queryForList(sql_statement); List<DrugEraPrevalence> listOfResults = new ArrayList<DrugEraPrevalence>(); for (Map rs : rows) { DrugEraPrevalence d = new DrugEraPrevalence(); d.conceptId = Long.valueOf(String.valueOf(rs.get("concept_id"))); d.trellisName = String.valueOf(rs.get("trellis_name")); d.seriesName = String.valueOf(rs.get("series_name")); d.xCalendarYear = Long.valueOf(String.valueOf(rs.get("x_calendar_year"))); d.yPrevalence1000Pp = Float.valueOf(String.valueOf(rs.get("y_prevalence_1000pp"))); listOfResults.add(d); } return listOfResults; } @Path("{sourceKey}/conditionoccurrencetreemap") @POST @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public List<ConditionOccurrenceTreemapNode> getConditionOccurrenceTreemap(@PathParam("sourceKey") String sourceKey, String[] identifiers) { Source source = getSourceRepository().findBySourceKey(sourceKey); String tableQualifier = source.getTableQualifier(SourceDaimon.DaimonType.Results); String cdmTableQualifier = source.getTableQualifier(SourceDaimon.DaimonType.CDM); for (int i = 0; i < identifiers.length; i++) { identifiers[i] = "'" + identifiers[i] + "'"; } String identifierList = StringUtils.join(identifiers, ","); String sql_statement = ResourceHelper.GetResourceAsString("/resources/cdmresults/sql/getConditionOccurrenceTreemap.sql"); sql_statement = SqlRender.renderSql(sql_statement, new String[]{"ohdsi_database_schema", "cdm_database_schema", "conceptIdList"}, new String[]{tableQualifier, cdmTableQualifier, identifierList}); sql_statement = SqlTranslate.translateSql(sql_statement, "sql server", source.getSourceDialect()); List<Map<String, Object>> rows = getSourceJdbcTemplate(source).queryForList(sql_statement); List<ConditionOccurrenceTreemapNode> listOfResults = new ArrayList<ConditionOccurrenceTreemapNode>(); for (Map rs : rows) { ConditionOccurrenceTreemapNode c = new ConditionOccurrenceTreemapNode(); c.conceptId = Long.valueOf(String.valueOf(rs.get("concept_id"))); c.conceptPath = String.valueOf(rs.get("concept_path")); c.numPersons = Long.valueOf(String.valueOf(rs.get("num_persons"))); c.percentPersons = Float.valueOf(String.valueOf(rs.get("percent_persons"))); c.recordsPerPerson = Float.valueOf(String.valueOf(rs.get("records_per_person"))); listOfResults.add(c); } return listOfResults; } /** * Queries for measurement treemap results * * @return List<ArrayNode> */ @GET @Path("{sourceKey}/{domain}/") @Produces(MediaType.APPLICATION_JSON) public ArrayNode getTreemap( @PathParam("domain") final String domain, @PathParam("sourceKey") final String sourceKey) { Source source = getSourceRepository().findBySourceKey(sourceKey); return queryRunner.getTreemap(this.getSourceJdbcTemplate(source), domain, source); } /** * Queries for drilldown results * * @return List<ArrayNode> */ @GET @Path("{sourceKey}/{domain}/{conceptId}") @Produces(MediaType.APPLICATION_JSON) public JsonNode getDrilldown(@PathParam("domain") final String domain, @PathParam("conceptId") final int conceptId, @PathParam("sourceKey") final String sourceKey) { Source source = getSourceRepository().findBySourceKey(sourceKey); JdbcTemplate jdbcTemplate = this.getSourceJdbcTemplate(source); return queryRunner.getDrilldown(jdbcTemplate, domain, conceptId, source); } }