package edu.harvard.i2b2.crc.loader.dao; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.SQLException; import java.sql.Types; import java.util.List; 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.PidType; import edu.harvard.i2b2.crc.datavo.pdo.PidType.PatientMapId; /** * Patient Dimension data access object. * * @author rk903 */ public class PidDAO extends CRCLoaderDAO implements IPidDAO { private int DB_BATCH_INSERT_SIZE = 2000; private static Log log = LogFactory.getLog(PidDAO.class); private DataSourceLookup dataSourceLookup = null; public PidDAO(DataSourceLookup dataSourceLookup, DataSource ds) { setDataSource(ds); setDbSchemaName(dataSourceLookup.getFullSchema()); this.dataSourceLookup = dataSourceLookup; } public int getRecordCountByUploadId(int uploadId) { JdbcTemplate jdbcTemplate = new JdbcTemplate(getDataSource()); int insertCount = jdbcTemplate.queryForInt("select count(1) from " + getDbSchemaName() + " patient_mapping where upload_id =?", new Object[] { uploadId }); return insertCount; } /** * Function to create temp visit dimension table using stored proc. * * @param tempTableName * @throws Exception */ public void createTempTable(String tempPatientMappingTableName) throws I2B2Exception { Connection conn = null; try { conn = getDataSource().getConnection(); CallableStatement callStmt = conn.prepareCall("{call " + getDbSchemaName() + "CREATE_TEMP_PID_TABLE(?,?)}"); callStmt.setString(1, tempPatientMappingTableName); 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); } } } } /** * Create batch insert handle for temp observation fact table. * * @param tempTableName * @return */ public TempPidInsertHandler createTempPidInsert(String tempTableName) { TempPidInsert tempPidInsert = new TempPidInsert(getDataSource(), tempTableName, this.getDbSchemaName()); tempPidInsert.setBatchSize(DB_BATCH_INSERT_SIZE); return new TempPidInsertHandler(tempPidInsert); } /** * Function to create new encounter/visit from temp_visit_dimension table * using stored proc. * * @param tempTableName * @throws Exception */ public void createPidFromTempTable(String tempMapTableName, int uploadId) throws I2B2Exception { Connection conn = null; try { conn = getDataSource().getConnection(); CallableStatement callStmt = conn.prepareCall("{call " + this.getDbSchemaName() + "INSERT_PID_MAP_FROMTEMP(?,?,?)}"); callStmt.setString(1, tempMapTableName); callStmt.setInt(2, uploadId); callStmt.registerOutParameter(3, java.sql.Types.VARCHAR); callStmt.execute(); this.getSQLServerProcedureError(dataSourceLookup.getServerType(), callStmt, 3); } 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); } } } } /** * Patient_Mapping insert code. */ protected class TempPidInsert extends BatchSqlUpdate { /** * Create a new instance of Patient_MappingInsert. * * @param ds * the DataSource to use for the insert */ protected TempPidInsert(DataSource ds, String tempTableName, String schemaName) { super(ds, "INSERT INTO " + schemaName + tempTableName + " (" + "patient_map_id, " + "patient_map_id_source, " + "patient_id, " + "patient_id_source, " + "PATIENT_MAP_ID_STATUS, " + " UPDATE_DATE, " + "DOWNLOAD_DATE," + " SOURCESYSTEM_CD )" + " 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.TIMESTAMP)); declareParameter(new SqlParameter(Types.TIMESTAMP)); declareParameter(new SqlParameter(Types.VARCHAR)); compile(); } protected void insert(PidType pid) { String patientId = pid.getPatientId().getValue(); String patientIdSource = pid.getPatientId().getSource(); List<PatientMapId> mapIdList = pid.getPatientMapId(); for (PatientMapId mapId : mapIdList) { Object[] objs = new Object[] { mapId.getValue(), mapId.getSource(), patientId, patientIdSource, mapId.getStatus(), (mapId.getUpdateDate() != null) ? mapId.getUpdateDate() .toGregorianCalendar().getTime() : null, (mapId.getDownloadDate() != null) ? mapId .getDownloadDate().toGregorianCalendar() .getTime() : null, mapId.getSourcesystemCd() }; super.update(objs); } // do self insert Object[] objs = new Object[] { patientId, patientIdSource, patientId, patientIdSource, pid.getPatientId().getStatus(), (pid.getPatientId().getUpdateDate() != null) ? pid .getPatientId().getUpdateDate() .toGregorianCalendar().getTime() : null, (pid.getPatientId().getDownloadDate() != null) ? pid .getPatientId().getDownloadDate() .toGregorianCalendar().getTime() : null, pid.getPatientId().getSourcesystemCd() }; super.update(objs); } } }