package edu.harvard.i2b2.crc.dao.pdo; import java.io.IOException; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Map; 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.support.JdbcUtils; import edu.harvard.i2b2.common.exception.I2B2DAOException; import edu.harvard.i2b2.common.util.db.JDBCUtil; import edu.harvard.i2b2.crc.dao.CRCDAO; import edu.harvard.i2b2.crc.dao.DAOFactoryHelper; import edu.harvard.i2b2.crc.datavo.db.DataSourceLookup; public class MetadataDao extends CRCDAO implements IMetadataDao { /** log * */ protected final Log log = LogFactory.getLog(getClass()); private ArrayList<String> PATIENT_DIMENSION_REQUIRED_FIELDS = new ArrayList<String>(); private ArrayList<String> VISIT_DIMENSION_REQUIRED_FIELDS = new ArrayList<String>(); private ArrayList<String> VISIT_DIMENSION_REQUIRED_DETAIL_FIELDS = new ArrayList<String>(); private ArrayList<String> PATIENT_DIMENSION_REQUIRED_DETAIL_FIELDS = new ArrayList<String>(); private String[] patient_dim_required_field = new String[] { "patient_num", "vital_status_cd", "birth_date", "death_date", "patient_blob", "update_date", "download_date", "import_date", "sourcesystem_cd", "upload_id" }; private String[] patient_dim_detail_field = new String[] { "vital_status_cd","birth_date"}; private String[] visit_dim_detail_field = new String[] {"active_status_cd"}; private String[] visit_dim_required_field = new String[] { "encounter_num", "patient_num", "start_date", "end_date", "active_status_cd", "visit_blob", "update_date", "download_date", "import_date", "sourcesystem_cd", "upload_id" }; public final static String CRC_COLUMN_DESCRIPTOR = "crc_column_descriptor"; private DataSourceLookup dataSourceLookup = null; public MetadataDao(DataSourceLookup dataSourceLookup, DataSource dataSource) { this.dataSourceLookup = dataSourceLookup; setDataSource(dataSource); setDbSchemaName(dataSourceLookup.getFullSchema()); PATIENT_DIMENSION_REQUIRED_FIELDS.addAll(Arrays .asList(patient_dim_required_field)); VISIT_DIMENSION_REQUIRED_FIELDS.addAll(Arrays .asList(visit_dim_required_field)); PATIENT_DIMENSION_REQUIRED_DETAIL_FIELDS.addAll(Arrays .asList(patient_dim_detail_field)); VISIT_DIMENSION_REQUIRED_DETAIL_FIELDS.addAll(Arrays .asList(visit_dim_detail_field)); } /* * (non-Javadoc) * * @see edu.harvard.i2b2.crc.dao.pdo.IMetadataDao#blah(java.lang.String) */ public Map getMetadataForOptionalField(String tableName) throws I2B2DAOException { ArrayList<String> requiredFieldLookupList = null; ArrayList<String> requiredDetailFieldLookupList = null; if (tableName.equalsIgnoreCase(DimensionTable.PATIENT_DIMENSION)) { requiredFieldLookupList = PATIENT_DIMENSION_REQUIRED_FIELDS; requiredDetailFieldLookupList = PATIENT_DIMENSION_REQUIRED_DETAIL_FIELDS; } else if (tableName.equalsIgnoreCase(DimensionTable.VISIT_DIMENSION)) { requiredFieldLookupList = VISIT_DIMENSION_REQUIRED_FIELDS; requiredDetailFieldLookupList = VISIT_DIMENSION_REQUIRED_DETAIL_FIELDS; } Map<String, TableMetaData> columnMap = new HashMap<String, TableMetaData>(); Connection conn = null; Statement stmt = null; try { conn = getDataSource().getConnection(); Map<String,String> columnDescriptorMap = getColumnDescription(conn, tableName) ; stmt = conn.createStatement(); // Execute the query ResultSet rs = stmt.executeQuery("SELECT * FROM " + getDbSchemaName() + tableName + " WHERE 1 = 2"); // Get the metadata ResultSetMetaData md = rs.getMetaData(); String columnName = "", columnType = ""; int columnSize = 0; // Print the column labels for (int i = 1; i <= md.getColumnCount(); i++) { TableMetaData tableMetaData = new TableMetaData(); boolean requiredDetailFieldFlag = false; if (requiredDetailFieldLookupList.contains(md.getColumnLabel(i) .toLowerCase())) { requiredDetailFieldFlag = true; } if (requiredDetailFieldFlag || (!requiredFieldLookupList.contains(md.getColumnLabel(i) .toLowerCase()))) { columnName = md.getColumnLabel(i).toLowerCase(); columnType = md.getColumnTypeName(i).toLowerCase(); columnSize = md.getColumnDisplaySize(i); log.debug("column name " + columnName); log.debug(" column type name" + columnType ); log.debug(" column display type size " + columnSize); tableMetaData.column_name = columnName; tableMetaData.column_type = columnType; tableMetaData.column_comment = columnName; tableMetaData.column_type_size = String.valueOf(columnSize); tableMetaData.column_comment = columnDescriptorMap.get(columnName); columnMap.put(columnName, tableMetaData); } } } catch (SQLException sqlEx) { sqlEx.printStackTrace(); log.error("", sqlEx); throw new I2B2DAOException("", sqlEx); } finally { try { JDBCUtil.closeJdbcResource(null, stmt, conn); } catch (SQLException sqlEx) { sqlEx.printStackTrace(); } } System.out.println(); return columnMap; } private Map<String,String> getColumnDescription(Connection conn, String tableName) throws SQLException { Map<String,String> columnDescriptorMap = new HashMap<String,String>(); PreparedStatement pStmt = conn.prepareStatement("select * from " + getDbSchemaName() + "code_lookup where lower(table_cd) = ? and lower(code_cd) = ?"); pStmt.setString(1, tableName.toLowerCase()); pStmt.setString(2, CRC_COLUMN_DESCRIPTOR); ResultSet resultSet = pStmt.executeQuery(); String columnCd = null, columnDescriptor = null; while (resultSet.next()) { columnCd = resultSet.getString("column_cd"); columnDescriptor = resultSet.getString("name_char"); if (columnCd != null && columnDescriptor != null) { columnDescriptorMap.put(columnCd.trim().toLowerCase() , columnDescriptor); } } return columnDescriptorMap; } public class TableMetaData { public String column_name; public String column_type; public String column_type_size; public String column_comment; public String column_xml_type; } }