package edu.harvard.i2b2.crc.loader.dao;
import java.io.BufferedWriter;
import java.io.IOException;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.Date;
import javax.sql.DataSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.object.BatchSqlUpdate;
import edu.harvard.i2b2.common.exception.I2B2Exception;
import edu.harvard.i2b2.crc.loader.datavo.loader.DataSourceLookup;
import edu.harvard.i2b2.crc.datavo.pdo.ObservationType;
/**
* Observation Fact data access object.
*
* @author rk903
*
*/
public class ObservationFactDAO extends CRCLoaderDAO implements
IObservationFactDAO {
private int DB_BATCH_INSERT_SIZE = 1;
private static Log log = LogFactory.getLog(ObservationFactDAO.class);
private DataSourceLookup dataSourceLookup = null;
public ObservationFactDAO(DataSourceLookup dataSourceLookup, DataSource ds) {
setDataSource(ds);
setDbSchemaName(dataSourceLookup.getFullSchema());
this.dataSourceLookup = dataSourceLookup;
}
public int getRecordCountByUploadId(int uploadId) {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
int insertCount = jdbcTemplate.queryForInt("select count(1) from "
+ getDbSchemaName() + "observation_fact where upload_id =?",
new Object[] { uploadId });
return insertCount;
}
/**
* Create batch insert handle for temp observation fact table.
*
* @param tempTableName
* @return
*/
public ObservationFactInsertHandle createObservationFactInserter(
String tempTableName) {
ObservationFactInsert observationFactInsert = new ObservationFactInsert(
getDataSource(), tempTableName, getDbSchemaName());
observationFactInsert.setBatchSize(DB_BATCH_INSERT_SIZE);
return new ObservationFactInsertHandle(observationFactInsert);
}
/**
* Function to check if given table exists
*
* @param tableName
* @return boolean
* @throws Exception
*/
public boolean checkTableExists(String tableName) throws I2B2Exception {
Connection conn = null;
boolean returnFlag = false;
try {
conn = getDataSource().getConnection();
CallableStatement callStmt = conn.prepareCall("{? = call "
+ this.getDbSchemaName() + "isTableExists(?)}");
callStmt.registerOutParameter(1, Types.VARCHAR);
callStmt.setString(2, tableName.toUpperCase());
callStmt.execute();
String stringFlag = callStmt.getString(1);
if (stringFlag.equalsIgnoreCase("TRUE")) {
returnFlag = true;
} else {
returnFlag = false;
}
} catch (SQLException sqlEx) {
sqlEx.printStackTrace();
log.error("SQLException occured" + sqlEx.getMessage(), sqlEx);
throw new I2B2Exception(
"SQLException occured" + sqlEx.getMessage(), sqlEx);
} catch (Exception ex) {
ex.printStackTrace();
throw new I2B2Exception("Exception occured" + ex.getMessage(), ex);
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException sqlEx) {
sqlEx.printStackTrace();
log.error("Error while closing connection", sqlEx);
}
}
}
return returnFlag;
}
/**
* Function to call MERGE_TEMP_OBSERVATION_FACT(?) stored procedure.
*
* @param tempTableName
* @throws Exception
*/
public void doTempTableMerge(String tempTableName, int uploadId,
boolean appendFlag) throws I2B2Exception {
Connection conn = null;
try {
conn = getDataSource().getConnection();
CallableStatement callStmt = conn.prepareCall("{call "
+ this.getDbSchemaName()
+ "UPDATE_OBSERVATION_FACT(?,?,?,?)}");
callStmt.setString(1, tempTableName);
callStmt.setInt(2, uploadId);
if (appendFlag == true) {
callStmt.setInt(3, 1);
} else {
callStmt.setInt(3, 0);
}
callStmt.registerOutParameter(4, java.sql.Types.VARCHAR);
callStmt.execute();
this.getSQLServerProcedureError(dataSourceLookup.getServerType(),
callStmt, 4);
} catch (SQLException sqlEx) {
sqlEx.printStackTrace();
throw new I2B2Exception(
"SQLException occured" + sqlEx.getMessage(), sqlEx);
} catch (Exception ex) {
ex.printStackTrace();
throw new I2B2Exception("Exception occured" + ex.getMessage(), ex);
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException sqlEx) {
sqlEx.printStackTrace();
log.error("Error while closing connection", sqlEx);
}
}
}
}
/**
* Function to call remove temp table stored procedure.
*
* @param tempTableName
* @throws Exception
*/
public void removeTempTable(String tempTableName) throws I2B2Exception {
Connection conn = null;
try {
conn = getDataSource().getConnection();
CallableStatement callStmt = conn.prepareCall("{call "
+ this.getDbSchemaName() + "REMOVE_TEMP_TABLE(?)}");
callStmt.setString(1, tempTableName);
callStmt.execute();
} catch (SQLException sqlEx) {
sqlEx.printStackTrace();
throw new I2B2Exception(
"SQLException occured" + sqlEx.getMessage(), sqlEx);
} catch (Exception ex) {
ex.printStackTrace();
throw new I2B2Exception("Exception occured" + ex.getMessage(), ex);
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException sqlEx) {
sqlEx.printStackTrace();
log.error("Error while closing connection", sqlEx);
}
}
}
}
/**
* Function to create create temp table stored proc.
*
* @param tempTableName
* @throws Exception
*/
public void createTempTable(String tempTableName) throws I2B2Exception {
Connection conn = null;
try {
conn = getDataSource().getConnection();
CallableStatement callStmt = conn.prepareCall("{call "
+ this.getDbSchemaName() + "CREATE_TEMP_TABLE(?,?)}");
callStmt.setString(1, tempTableName);
callStmt.registerOutParameter(2, java.sql.Types.VARCHAR);
callStmt.execute();
this.getSQLServerProcedureError(dataSourceLookup.getServerType(),
callStmt, 2);
} catch (SQLException sqlEx) {
sqlEx.printStackTrace();
throw new I2B2Exception(
"SQLException occured" + sqlEx.getMessage(), sqlEx);
} catch (Exception ex) {
ex.printStackTrace();
throw new I2B2Exception("Exception occured" + ex.getMessage(), ex);
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException sqlEx) {
sqlEx.printStackTrace();
log.error("Error while closing connection", sqlEx);
}
}
}
}
public void writeMissedDataLog(BufferedWriter bufWriter,
String tempTableName) throws I2B2Exception {
String queryString = "select a.* "
+ " from (select utemp.encounter_ide, utemp.patient_ide, utemp.concept_cd, "
+ " utemp.provider_id,utemp.start_date,utemp.modifier_cd "
+ " from temp_upload_try1 utemp "
+ " where utemp.encounter_ide not in (select emap.encounter_ide from encounter_mapping emap) "
+ " union "
+ " select utemp1.encounter_ide, utemp1.patient_ide, utemp1.concept_cd, "
+ " utemp1.provider_id,utemp1.start_date,utemp1.modifier_cd "
+ " from temp_upload_try1 utemp1 "
+ " where utemp1.patient_ide not in (select patmap.patient_ide from patient_mapping patmap ) "
+ " union "
+ " select utemp.encounter_ide, utemp.patient_ide, utemp.concept_cd, "
+ " utemp.provider_id,utemp.start_date,utemp.modifier_cd "
+ " from temp_upload_try1 utemp "
+ " where utemp.concept_cd is null " + " ) a ";
Statement stmt = null;
try {
stmt = getDataSource().getConnection().createStatement();
stmt.setFetchSize(5000);
ResultSet resultSet = stmt.executeQuery(queryString);
String encounterIde = "", patientIde = "", conceptCd = "", providerId = "";
Date startDate = null;
while (resultSet.next()) {
encounterIde = resultSet.getString("encounter_ide");
patientIde = resultSet.getString("patient_ide");
conceptCd = resultSet.getString("concept_cd");
providerId = resultSet.getString("provider_id");
startDate = resultSet.getDate("start_date");
// write to logwriter
bufWriter.write(encounterIde + "|" + patientIde + "|"
+ conceptCd + "|" + providerId + "\n");
}
} catch (IOException ioEx) {
log.error("IOException ", ioEx);
throw new I2B2Exception("IOException " + ioEx.getMessage(), ioEx);
} catch (SQLException sqlEx) {
log.error("SQLException ", sqlEx);
throw new I2B2Exception("SQLException " + sqlEx.getMessage(), sqlEx);
} catch (Exception ex) {
log.error("Exception ", ex);
throw new I2B2Exception("Exception " + ex.getMessage(), ex);
} finally {
try {
stmt.close();
} catch (SQLException sqlEx) {
log.info("Unable to close statment", sqlEx);
}
}
}
// ************* Operation Objects section ***************
/**
* <code>ObservationFact</code> Insert Object.
*/
protected class ObservationFactInsert extends BatchSqlUpdate {
/**
* Create a new instance of ObservationInsert.
*
* @param ds
* the DataSource to use for the insert
*/
protected ObservationFactInsert(DataSource ds,
String observationFactTable, String schemaName) {
super(
ds,
"INSERT INTO "
+ schemaName
+ observationFactTable
+ " ("
+ "encounter_id, "
+ "encounter_id_source, "
+ "concept_cd, "
+ "patient_id, "
+ "patient_id_source, "
+ "provider_id, "
+ "start_date, "
+ "modifier_cd, "
+ "instance_num, "
+ "valtype_cd, "
+ "tval_char, "
+ "nval_num, "
+ "valueflag_cd, "
+ "quantity_num, "
+ "confidence_num, "
+ "observation_blob, "
+ "units_cd, "
+ "end_date, "
+ "location_cd, "
+ "update_date, "
+ "download_date, "
+ "import_Date, "
+ "sourcesystem_cd,"
+ "upload_id) "
+ " VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
declareParameter(new SqlParameter(Types.VARCHAR));
declareParameter(new SqlParameter(Types.VARCHAR));
declareParameter(new SqlParameter(Types.VARCHAR));
declareParameter(new SqlParameter(Types.VARCHAR));
declareParameter(new SqlParameter(Types.VARCHAR));
declareParameter(new SqlParameter(Types.VARCHAR));
declareParameter(new SqlParameter(Types.TIMESTAMP));
declareParameter(new SqlParameter(Types.VARCHAR));
declareParameter(new SqlParameter(Types.INTEGER));
declareParameter(new SqlParameter(Types.VARCHAR));
declareParameter(new SqlParameter(Types.VARCHAR));
declareParameter(new SqlParameter(Types.FLOAT));
declareParameter(new SqlParameter(Types.VARCHAR));
declareParameter(new SqlParameter(Types.FLOAT));
declareParameter(new SqlParameter(Types.BIGINT));
declareParameter(new SqlParameter(Types.LONGVARCHAR)); // Types.CLOB
declareParameter(new SqlParameter(Types.VARCHAR));
declareParameter(new SqlParameter(Types.TIMESTAMP));
declareParameter(new SqlParameter(Types.VARCHAR));
declareParameter(new SqlParameter(Types.TIMESTAMP));
declareParameter(new SqlParameter(Types.TIMESTAMP));
declareParameter(new SqlParameter(Types.TIMESTAMP));
declareParameter(new SqlParameter(Types.VARCHAR));
declareParameter(new SqlParameter(Types.INTEGER));
compile();
}
protected void insert(ObservationType observationType) {
// new SqlLobValue(observationType
// .getObservationBlob().getContent().get(0))
Object[] objs = new Object[] {
// observationFactMap.get("encounter_ide"),
observationType.getEventId().getValue(),
observationType.getEventId().getSource(),
// observationFactMap.get("concept_cd"),
observationType.getConceptCd().getValue(),
// observationFactMap.get("patient_ide"),
(observationType.getPatientId() != null) ? observationType
.getPatientId().getValue() : null,
(observationType.getPatientId() != null) ? observationType
.getPatientId().getSource() : null,
// observationFactMap.get("provider_id"),
(observationType.getObserverCd() != null) ? observationType
.getObserverCd().getValue() : null,
// observationFactMap.get("start_date"),
(observationType.getStartDate() != null) ? observationType
.getStartDate().toGregorianCalendar().getTime()
: null,
// observationFactMap.get("modifier_cd"),
(observationType.getModifierCd() != null) ? observationType
.getModifierCd().getValue() : null,
(observationType.getInstanceNum() != null) ? observationType
.getInstanceNum().getValue()
: null,
// observationFactMap.get("valtype_cd"),
observationType.getValuetypeCd(),
// observationFactMap.get("tval_char"),
observationType.getTvalChar(),
// (Float)observationFactMap.get("nval_num"),
(observationType.getNvalNum() != null) ? observationType
.getNvalNum().getValue() : null,
// observationFactMap.get("valueflag_cd"),
(observationType.getValueflagCd() != null) ? observationType
.getValueflagCd().getValue()
: null,
// (Float)observationFactMap.get("quantity_num"),
(observationType.getQuantityNum() != null) ? observationType
.getQuantityNum()
: null,
// observationFactMap.get("confidence_num"),
// TODO add confidence number to observation
null,
// observationFactMap.get("observation_blob"),
(observationType.getObservationBlob() != null) ? observationType
.getObservationBlob().getContent().get(0)
.toString()
: null,
// observationFactMap.get("units_cd"),
observationType.getUnitsCd(),
// observationFactMap.get("end_date"),
(observationType.getEndDate() != null) ? observationType
.getEndDate().toGregorianCalendar().getTime()
: null,
// observationFactMap.get("location_cd"),
(observationType.getLocationCd() != null) ? observationType
.getLocationCd().getValue() : null,
// (Date) observationFactMap.get("update_date"),
(observationType.getUpdateDate() != null) ? observationType
.getUpdateDate().toGregorianCalendar().getTime()
: null,
// (Date) observationFactMap.get("download_date"),
(observationType.getDownloadDate() != null) ? observationType
.getDownloadDate().toGregorianCalendar().getTime()
: null,
// (Date) observationFactMap.get("import_date"),
(observationType.getImportDate() != null) ? observationType
.getImportDate().toGregorianCalendar().getTime()
: null,
// observationFactMap.get("sourcesystem_cd"),
observationType.getSourcesystemCd(),
// observationFactMap.get("upload_id")
observationType.getUploadId() };
update(objs);
}
}
}