diff --git a/DaoCancerStudy.java b/DaoCancerStudy.java new file mode 100644 index 0000000..fffd699 --- /dev/null +++ b/DaoCancerStudy.java @@ -0,0 +1,626 @@ +/* + * Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS + * FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder + * is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no + * obligations to provide maintenance, support, updates, enhancements or + * modifications. In no event shall Memorial Sloan-Kettering Cancer Center be + * liable to any party for direct, indirect, special, incidental or + * consequential damages, including lost profits, arising out of the use of this + * software and its documentation, even if Memorial Sloan-Kettering Cancer + * Center has been advised of the possibility of such damage. + */ + +/* + * This file is part of cBioPortal. + * + * cBioPortal is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . +*/ + +package org.mskcc.cbio.portal.dao; + +import org.mskcc.cbio.portal.util.*; + +import edu.jhu.u01.DBProperties; + +import org.mskcc.cbio.portal.model.*; + +import org.apache.commons.lang.StringUtils; + +import java.sql.*; +import java.util.*; +import java.text.*; + +/** + * Analogous to and replaces the old DaoCancerType. A CancerStudy has a NAME and + * DESCRIPTION. If PUBLIC is true a CancerStudy can be accessed by anyone, + * otherwise can only be accessed through access control. + * + * @author Ethan Cerami + * @author Arthur Goldberg goldberg@cbio.mskcc.org + * @author Ersin Ciftci + */ +public final class DaoCancerStudy { + + public static enum Status + { + UNAVAILABLE, AVAILABLE + } + + private DaoCancerStudy() {} + + private static final Map cacheDateByStableId = new HashMap(); + private static final Map cacheDateByInternalId = new HashMap(); + private static final Map byStableId = new HashMap(); + private static final Map byInternalId = new HashMap(); + + static { + SpringUtil.initDataSource(); + reCacheAll(); + } + + public static synchronized void reCacheAll() { + + System.out.println("Recaching... "); + DaoCancerStudy.reCache(); + DaoGeneticProfile.reCache(); + DaoPatient.reCache(); + DaoSample.reCache(); + DaoClinicalData.reCache(); + DaoInfo.setVersion(); + System.out.println("Finished recaching... "); + } + + private static synchronized void reCache() { + cacheDateByStableId.clear(); + cacheDateByInternalId.clear(); + byStableId.clear(); + byInternalId.clear(); + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoCancerStudy.class); + pstmt = con.prepareStatement("SELECT * FROM cancer_study"); + rs = pstmt.executeQuery(); + while (rs.next()) { + CancerStudy cancerStudy = extractCancerStudy(rs); + cacheCancerStudy(cancerStudy, new java.util.Date()); + } + } catch (SQLException e) { + e.printStackTrace(); + } finally { + JdbcUtil.closeAll(DaoCancerStudy.class, con, pstmt, rs); + } + } + + private static void cacheCancerStudy(CancerStudy study, java.util.Date importDate) { + cacheDateByStableId.put(study.getCancerStudyStableId(), importDate); + cacheDateByInternalId.put(study.getInternalId(), importDate); + byStableId.put(study.getCancerStudyStableId(), study); + byInternalId.put(study.getInternalId(), study); + } + + /** + * Removes the cancer study from cache + * @param internalCancerStudyId Internal cancer study ID + */ + private static void removeCancerStudyFromCache(int internalCancerStudyId) { + + String stableId = byInternalId.get(internalCancerStudyId).getCancerStudyStableId(); + cacheDateByStableId.remove(stableId); + cacheDateByInternalId.remove(internalCancerStudyId); + byStableId.remove(stableId); + byInternalId.remove(internalCancerStudyId); + } + + public static void setStatus(Status status, String stableCancerStudyId, Integer ... internalId) throws DaoException + { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoCancerStudy.class); + if (internalId.length > 0) { + pstmt = con.prepareStatement("UPDATE cancer_study set status = ? where cancer_study_id = ?"); + pstmt.setInt(1, status.ordinal()); + pstmt.setInt(2, internalId[0]); + } + else { + pstmt = con.prepareStatement("UPDATE cancer_study set status = ? where cancer_study_identifier = ?"); + pstmt.setInt(1, status.ordinal()); + pstmt.setString(2, stableCancerStudyId); + } + pstmt.executeUpdate(); + } catch (SQLException e) { + if (!e.getMessage().toLowerCase().contains("unknown column")) { + throw new DaoException(e); + } + } finally { + JdbcUtil.closeAll(DaoCancerStudy.class, con, pstmt, rs); + } + } + + public static Status getStatus(String stableCancerStudyId, Integer ... internalId) throws DaoException + { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoCancerStudy.class); + if (internalId.length > 0) { + pstmt = con.prepareStatement("SELECT status FROM cancer_study where cancer_study_id = ?"); + pstmt.setInt(1, internalId[0]); + } + else { + pstmt = con.prepareStatement("SELECT status FROM cancer_study where cancer_study_identifier = ?"); + pstmt.setString(1, stableCancerStudyId); + } + rs = pstmt.executeQuery(); + if (rs.next()) { + Integer status = rs.getInt(1); + if (rs.wasNull()) { + return Status.AVAILABLE; + } + + if (status>=Status.values().length) { + return Status.AVAILABLE; + } + + return Status.values()[status]; + } + else { + return Status.AVAILABLE; + } + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoCancerStudy.class, con, pstmt, rs); + } + } + + private static Integer getStudyCount() throws DaoException + { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoCancerStudy.class); + pstmt = con.prepareStatement("SELECT count(*) from cancer_study"); + rs = pstmt.executeQuery(); + if (rs.next()) { + return rs.getInt(1); + } + else { + return 0; + } + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoCancerStudy.class, con, pstmt, rs); + } + } + + public static void setImportDate(Integer internalId) throws DaoException + { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + + try { + con = JdbcUtil.getDbConnection(DaoCancerStudy.class); + switch(DBProperties.getDBVendor()){ + case mssql: + pstmt = con.prepareStatement("UPDATE cancer_study set IMPORT_DATE = CURRENT_TIMESTAMP where cancer_study_id = ?"); + break; + default: + pstmt = con.prepareStatement("UPDATE cancer_study set IMPORT_DATE = NOW() where cancer_study_id = ?"); + break; + }//JK-UPDATED + + + pstmt.setInt(1, internalId); + pstmt.executeUpdate(); + } + catch (SQLException e) { + if (e.getMessage().toLowerCase().contains("unknown column")) { + return; + } + throw new DaoException(e); + } + finally { + JdbcUtil.closeAll(DaoCancerStudy.class, con, pstmt, rs); + } + } + + public static java.util.Date getImportDate(String stableCancerStudyId, Integer ... internalId) throws DaoException, ParseException + { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoCancerStudy.class); + if (internalId.length > 0) { + pstmt = con.prepareStatement("SELECT IMPORT_DATE FROM cancer_study where cancer_study_id = ?"); + pstmt.setInt(1, internalId[0]); + } + else { + pstmt = con.prepareStatement("SELECT IMPORT_DATE FROM cancer_study where cancer_study_identifier = ?"); + pstmt.setString(1, stableCancerStudyId); + } + rs = pstmt.executeQuery(); + if (rs.next()) { + java.sql.Timestamp importDate = rs.getTimestamp(1); + if (rs.wasNull()) { + return new SimpleDateFormat("yyyyMMdd").parse("19180511"); + } + else { + return importDate; + } + } + else { + return new SimpleDateFormat("yyyyMMdd").parse("19180511"); + } + } catch (SQLException e) { + if (e.getMessage().toLowerCase().contains("unknown column")) { + return new SimpleDateFormat("yyyyMMdd").parse("19180511"); + } + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoCancerStudy.class, con, pstmt, rs); + } + } + + /** + * Adds a cancer study to the Database. + * Updates cancerStudy with its auto incremented uid, in studyID. + * + * @param cancerStudy Cancer Study Object. + * @throws DaoException Database Error. + */ + public static void addCancerStudy(CancerStudy cancerStudy) throws DaoException { + addCancerStudy(cancerStudy, false); + } + + /** + * Adds a cancer study to the Database. + * @param cancerStudy + * @param overwrite if true, overwrite if exist. + * @throws DaoException + */ + public static void addCancerStudy(CancerStudy cancerStudy, boolean overwrite) throws DaoException { + + // make sure that cancerStudy refers to a valid TypeOfCancerId + // TODO: have a foreign key constraint do this; why not? + TypeOfCancer aTypeOfCancer = DaoTypeOfCancer.getTypeOfCancerById + (cancerStudy.getTypeOfCancerId()); + if (null == aTypeOfCancer) { + throw new DaoException("cancerStudy.getTypeOfCancerId() '" + + cancerStudy.getTypeOfCancerId() + + "' does not refer to a TypeOfCancer."); + } + + // CANCER_STUDY_IDENTIFIER cannot be null + String stableId = cancerStudy.getCancerStudyStableId(); + if (stableId == null) { + throw new DaoException("Cancer study stable ID cannot be null."); + } + + CancerStudy existing = getCancerStudyByStableId(stableId); + if (existing!=null) { + if (overwrite) { + //setStatus(Status.UNAVAILABLE, stableId); + deleteCancerStudy(existing.getInternalId()); + } else { + throw new DaoException("Cancer study " + stableId + "is already imported."); + } + } + + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoCancerStudy.class); + switch(DBProperties.getDBVendor()){ + case mssql: + pstmt = con.prepareStatement("INSERT INTO cancer_study " + + "( [CANCER_STUDY_IDENTIFIER], [NAME], " + + "[DESCRIPTION], [PUBLIC], [TYPE_OF_CANCER_ID], " + + "[PMID], [CITATION], [GROUPS], [SHORT_NAME], [STATUS] ) VALUES (?,?,?,?,?,?,?,?,?,?)", + Statement.RETURN_GENERATED_KEYS); + + break; + default: + pstmt = con.prepareStatement("INSERT INTO cancer_study " + + "( `CANCER_STUDY_IDENTIFIER`, `NAME`, " + + "`DESCRIPTION`, `PUBLIC`, `TYPE_OF_CANCER_ID`, " + + "`PMID`, `CITATION`, `GROUPS`, `SHORT_NAME`, `STATUS` ) VALUES (?,?,?,?,?,?,?,?,?,?)", + Statement.RETURN_GENERATED_KEYS); + + break; + }//JK-UPDATED + + + pstmt.setString(1, stableId); + pstmt.setString(2, cancerStudy.getName()); + pstmt.setString(3, cancerStudy.getDescription()); + pstmt.setBoolean(4, cancerStudy.isPublicStudy()); + pstmt.setString(5, cancerStudy.getTypeOfCancerId()); + pstmt.setString(6, cancerStudy.getPmid()); + pstmt.setString(7, cancerStudy.getCitation()); + Set groups = cancerStudy.getGroups(); + if (groups==null) { + pstmt.setString(8, null); + } else { + pstmt.setString(8, StringUtils.join(groups, ";")); + } + pstmt.setString(9, cancerStudy.getShortName()); + //status is UNAVAILABLE until other data is loaded for this study. Once all is loaded, the + //data loading process can set this to AVAILABLE: + //TODO - use this field in parts of the system that build up the list of studies to display in home page: + pstmt.setInt(10, Status.UNAVAILABLE.ordinal()); + pstmt.executeUpdate(); + rs = pstmt.getGeneratedKeys(); + if (rs.next()) { + int autoId = rs.getInt(1); + cancerStudy.setInternalId(autoId); + } + + cacheCancerStudy(cancerStudy, new java.util.Date()); + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoCancerStudy.class, con, pstmt, rs); + } + + reCacheAll(); + } + + /** + * Return the cancerStudy identified by the internal cancer study ID, if it exists. + * + * @param cancerStudyID Internal (int) Cancer Study ID. + * @return Cancer Study Object, or null if there's no such study. + */ + public static CancerStudy getCancerStudyByInternalId(int internalId) throws DaoException + { + return byInternalId.get(internalId); + } + + /** + * Returns the cancerStudy identified by the stable identifier, if it exists. + * + * @param cancerStudyStableId Cancer Study Stable ID. + * @return the CancerStudy, or null if there's no such study. + */ + public static CancerStudy getCancerStudyByStableId(String stableId) throws DaoException + { + return byStableId.get(stableId); + } + + /** + * Indicates whether the cancerStudy identified by the stable ID exists. + * + * @param cancerStudyStableId Cancer Study Stable ID. + * @return true if the CancerStudy exists, otherwise false + */ + public static boolean doesCancerStudyExistByStableId(String cancerStudyStableId) { + return byStableId.containsKey(cancerStudyStableId); + } + + /** + * Indicates whether the cancerStudy identified by internal study ID exist. + * does no access control, so only returns a boolean. + * + * @param internalCancerStudyId Internal Cancer Study ID. + * @return true if the CancerStudy exists, otherwise false + */ + public static boolean doesCancerStudyExistByInternalId(int internalCancerStudyId) { + return byInternalId.containsKey(internalCancerStudyId); + } + + /** + * Returns all the cancerStudies. + * + * @return ArrayList of all CancerStudy Objects. + */ + public static ArrayList getAllCancerStudies() { + return new ArrayList(byStableId.values()); + } + + /** + * Gets Number of Cancer Studies. + * @return number of cancer studies. + */ + public static int getCount() { + return byStableId.size(); + } + + /** + * Deletes all Cancer Studies. + * @throws DaoException Database Error. + * + * @deprecated this should not be used. Use deleteCancerStudy(cancerStudyStableId) instead + */ + public static void deleteAllRecords() throws DaoException { + cacheDateByStableId.clear(); + cacheDateByInternalId.clear(); + byStableId.clear(); + byInternalId.clear(); + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoCancerStudy.class); + JdbcUtil.disableForeignKeyCheck(con); + pstmt = con.prepareStatement("TRUNCATE TABLE cancer_study"); + pstmt.executeUpdate(); + JdbcUtil.enableForeignKeyCheck(con); + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoCancerStudy.class, con, pstmt, rs); + } + } + + public static void deleteCancerStudy(String cancerStudyStableId) throws DaoException + { + CancerStudy study = getCancerStudyByStableId(cancerStudyStableId); + if (study != null){ + //setStatus(Status.UNAVAILABLE, cancerStudyStableId); + deleteCancerStudy(study.getInternalId()); + } + } + + public static Set getFreshGroups(int internalCancerStudyId) throws DaoException + { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoCancerStudy.class); + pstmt = con.prepareStatement("SELECT * FROM cancer_study where cancer_study_id = ?"); + pstmt.setInt(1, internalCancerStudyId); + rs = pstmt.executeQuery(); + if (rs.next()) { + CancerStudy cancerStudy = extractCancerStudy(rs); + return cancerStudy.getGroups(); + } + else { + return Collections.emptySet(); + } + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoCancerStudy.class, con, pstmt, rs); + } + } + + /** + * Deletes the Specified Cancer Study. + * + * @param internalCancerStudyId Internal Cancer Study ID. + * @throws DaoException Database Error. + */ + static void deleteCancerStudy(int internalCancerStudyId) throws DaoException { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoCancerStudy.class); + + // this is a hacky way to delete all associated data with on cancer study. + // ideally database dependency should be modeled with option of delete on cascade. + // remember to update this code if new tables are added or existing tables are changed. + String[] sqls = { + "delete from sample_cna_event where GENETIC_PROFILE_ID IN (select GENETIC_PROFILE_ID from genetic_profile where CANCER_STUDY_ID=?);", + "delete from genetic_alteration where GENETIC_PROFILE_ID IN (select GENETIC_PROFILE_ID from genetic_profile where CANCER_STUDY_ID=?);", + "delete from genetic_profile_samples where GENETIC_PROFILE_ID IN (select GENETIC_PROFILE_ID from genetic_profile where CANCER_STUDY_ID=?);", + "delete from sample_profile where GENETIC_PROFILE_ID IN (select GENETIC_PROFILE_ID from genetic_profile where CANCER_STUDY_ID=?);", + "delete from mutation where GENETIC_PROFILE_ID IN (select GENETIC_PROFILE_ID from genetic_profile where CANCER_STUDY_ID=?);", + "delete from mutation_event where MUTATION_EVENT_ID NOT IN (select MUTATION_EVENT_ID from mutation);", + "delete from mutation_count where GENETIC_PROFILE_ID IN (select GENETIC_PROFILE_ID from genetic_profile where CANCER_STUDY_ID=?);", + "delete from clinical_attribute_meta where CANCER_STUDY_ID=?;", + "delete from clinical_event_data where CLINICAL_EVENT_ID IN (select CLINICAL_EVENT_ID from clinical_event where PATIENT_ID in (SELECT INTERNAL_ID FROM patient where CANCER_STUDY_ID=?))", + "delete from clinical_event where PATIENT_ID in (SELECT INTERNAL_ID FROM patient where CANCER_STUDY_ID=?)", + "delete from sample_list_list where LIST_ID IN (select LIST_ID from sample_list where CANCER_STUDY_ID=?);", + "delete from clinical_sample where INTERNAL_ID IN (select INTERNAL_ID from sample where PATIENT_ID in (select INTERNAL_ID from patient where CANCER_STUDY_ID=?));", + "delete from sample where PATIENT_ID IN (select INTERNAL_ID from patient where CANCER_STUDY_ID=?);", + "delete from clinical_patient where INTERNAL_ID IN (select INTERNAL_ID from patient where CANCER_STUDY_ID=?);", + "delete from patient where CANCER_STUDY_ID=?;", + "delete from copy_number_seg where CANCER_STUDY_ID=?;", + "delete from sample_list where CANCER_STUDY_ID=?;", + "delete from genetic_profile where CANCER_STUDY_ID=?;", + "delete from gistic_to_gene where GISTIC_ROI_ID IN (select GISTIC_ROI_ID from gistic where CANCER_STUDY_ID=?);", + "delete from gistic where CANCER_STUDY_ID=?;", + "delete from mut_sig where CANCER_STUDY_ID=?;", + "delete from protein_array_data where CANCER_STUDY_ID=?;", + "delete from protein_array_cancer_study where CANCER_STUDY_ID=?;", + "delete from cancer_study where CANCER_STUDY_ID=?;" + }; + for (String sql : sqls) { + pstmt = con.prepareStatement(sql); + if (sql.contains("?")) { + pstmt.setInt(1, internalCancerStudyId); + } + pstmt.executeUpdate(); + } + + removeCancerStudyFromCache(internalCancerStudyId); + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoCancerStudy.class, con, pstmt, rs); + } + reCacheAll(); + System.out.println("deleted study:\nID: "+internalCancerStudyId); + } + + /** + * Extracts Cancer Study JDBC Results. + */ + private static CancerStudy extractCancerStudy(ResultSet rs) throws SQLException { + CancerStudy cancerStudy = new CancerStudy(rs.getString("NAME"), + rs.getString("DESCRIPTION"), + rs.getString("CANCER_STUDY_IDENTIFIER"), + rs.getString("TYPE_OF_CANCER_ID"), + rs.getBoolean("PUBLIC")); + cancerStudy.setPmid(rs.getString("PMID")); + cancerStudy.setCitation(rs.getString("CITATION")); + cancerStudy.setGroupsInUpperCase(rs.getString("GROUPS")); + cancerStudy.setShortName(rs.getString("SHORT_NAME")); + + cancerStudy.setInternalId(rs.getInt("CANCER_STUDY_ID")); + return cancerStudy; + } + + private static boolean studyNeedsRecaching(String stableId, Integer ... internalId) { + if (cacheOutOfSyncWithDb()) { + return true; + } + + try { + java.util.Date importDate = null; + java.util.Date cacheDate = null; + if (internalId.length > 0) { + importDate = getImportDate(null, internalId[0]); + cacheDate = cacheDateByInternalId.get(internalId[0]); + } else { + if (stableId.equals(org.mskcc.cbio.portal.util.AccessControl.ALL_CANCER_STUDIES_ID)) { + return false; + } + importDate = getImportDate(stableId); + cacheDate = cacheDateByStableId.get(stableId); + } + + return (importDate == null || cacheDate == null) ? false : cacheDate.before(importDate); + } catch (ParseException e) { + return false; + } + catch (DaoException e) { + return false; + } + } + + private static boolean cacheOutOfSyncWithDb() + { + try { + return getStudyCount() != byStableId.size(); + } + catch (DaoException e) {} + return false; + } +} diff --git a/DaoClinicalAttributeMeta.java b/DaoClinicalAttributeMeta.java new file mode 100644 index 0000000..a43e620 --- /dev/null +++ b/DaoClinicalAttributeMeta.java @@ -0,0 +1,272 @@ +/* + * Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS + * FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder + * is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no + * obligations to provide maintenance, support, updates, enhancements or + * modifications. In no event shall Memorial Sloan-Kettering Cancer Center be + * liable to any party for direct, indirect, special, incidental or + * consequential damages, including lost profits, arising out of the use of this + * software and its documentation, even if Memorial Sloan-Kettering Cancer + * Center has been advised of the possibility of such damage. + */ + +/* + * This file is part of cBioPortal. + * + * cBioPortal is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . +*/ + +package org.mskcc.cbio.portal.dao; + +import org.mskcc.cbio.portal.model.*; + +import com.google.inject.internal.Join; + +import edu.jhu.u01.DBProperties; + +import org.apache.commons.lang.StringUtils; + +import java.sql.*; +import java.util.*; +import org.mskcc.cbio.portal.util.InternalIdUtil; + +/** + * Data Access Object for `clinical_attribute_meta` table + * + * @author Gideon Dresdner + */ +public class DaoClinicalAttributeMeta { + + public static int addDatum(ClinicalAttribute attr) throws DaoException { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoClinicalAttributeMeta.class); + switch(DBProperties.getDBVendor()){ + case mssql: + pstmt = con.prepareStatement + ("INSERT INTO clinical_attribute_meta(" + + "[ATTR_ID]," + + "[DISPLAY_NAME]," + + "[DESCRIPTION]," + + "[DATATYPE]," + + "[PATIENT_ATTRIBUTE]," + + "[PRIORITY]," + + "[CANCER_STUDY_ID])" + + " VALUES(?,?,?,?,?,?,?)"); + break; + default: + pstmt = con.prepareStatement + ("INSERT INTO clinical_attribute_meta(" + + "`ATTR_ID`," + + "`DISPLAY_NAME`," + + "`DESCRIPTION`," + + "`DATATYPE`," + + "`PATIENT_ATTRIBUTE`," + + "`PRIORITY`," + + "`CANCER_STUDY_ID`)" + + " VALUES(?,?,?,?,?,?,?)"); + break; + }//JK-UPDATED + + pstmt.setString(1, attr.getAttrId()); + pstmt.setString(2, attr.getDisplayName()); + pstmt.setString(3, attr.getDescription()); + pstmt.setString(4, attr.getDatatype()); + pstmt.setBoolean(5, attr.isPatientAttribute()); + pstmt.setString(6, attr.getPriority()); + pstmt.setInt(7, attr.getCancerStudyId()); + return pstmt.executeUpdate(); + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoClinicalAttributeMeta.class, con, pstmt, rs); + } + } + + private static ClinicalAttribute unpack(ResultSet rs) throws SQLException { + return new ClinicalAttribute(rs.getString("ATTR_ID"), + rs.getString("DISPLAY_NAME"), + rs.getString("DESCRIPTION"), + rs.getString("DATATYPE"), + rs.getBoolean("PATIENT_ATTRIBUTE"), + rs.getString("PRIORITY"), + rs.getInt("CANCER_STUDY_ID"));//JK-UPDATED + } + + public static ClinicalAttribute getDatum(String attrId, Integer cancerStudyId) throws DaoException { + List attrs = getDatum(Arrays.asList(attrId), cancerStudyId); + if (attrs.isEmpty()) { + return null; + } + + return attrs.get(0); + } + + public static List getDatum(Collection attrIds, Integer cancerStudyId) throws DaoException { + if(attrIds == null || attrIds.isEmpty() ) { + return Collections.emptyList(); + } + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoClinicalAttributeMeta.class); + + pstmt = con.prepareStatement("SELECT * FROM clinical_attribute_meta WHERE ATTR_ID IN ('" + + StringUtils.join(attrIds,"','")+"') AND CANCER_STUDY_ID=" + String.valueOf(cancerStudyId));//JK-UPDATED + + rs = pstmt.executeQuery(); + + List list = new ArrayList(); + while (rs.next()) { + list.add(unpack(rs)); + } + + return list; + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoClinicalAttributeMeta.class, con, pstmt, rs); + } + } + + public static List getDatum(Collection attrIds) throws DaoException { + if(attrIds == null || attrIds.isEmpty() ) { + return Collections.emptyList(); + } + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoClinicalAttributeMeta.class); + + pstmt = con.prepareStatement("SELECT * FROM clinical_attribute_meta WHERE ATTR_ID IN ('" + + StringUtils.join(attrIds,"','")+"')");//JK-UPDATED + + rs = pstmt.executeQuery(); + + List list = new ArrayList(); + while (rs.next()) { + list.add(unpack(rs)); + } + + return list; + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoClinicalAttributeMeta.class, con, pstmt, rs); + } + } + + public static List getDataByStudy(int cancerStudyId) throws DaoException + { + List attrs = new ArrayList(); + attrs.addAll(getDataByCancerStudyId(cancerStudyId)); + + return attrs; + } + + /** + * Gets all the clinical attributes for a particular set of samples + * Looks in the clinical table for all records associated with any of the samples, extracts and uniques + * the attribute ids, then finally uses the attribute ids to fetch the clinical attributes from the db. + * + * @param sampleIdSet + * @return + * @throws DaoException + */ + private static List getDataByCancerStudyId(int cancerStudyId) throws DaoException { + + Connection con = null; + ResultSet rs = null; + PreparedStatement pstmt = null; + + String sql = ("SELECT DISTINCT ATTR_ID FROM clinical_attribute_meta" + + " WHERE CANCER_STUDY_ID = " + String.valueOf(cancerStudyId));//JK-UPDATED + + Set attrIds = new HashSet(); + try { + con = JdbcUtil.getDbConnection(DaoClinicalAttributeMeta.class); + pstmt = con.prepareStatement(sql); + rs = pstmt.executeQuery(); + + while(rs.next()) { + attrIds.add(rs.getString("ATTR_ID")); + } + + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoClinicalAttributeMeta.class, con, pstmt, rs); + } + + return getDatum(attrIds, cancerStudyId); + } + + private static Collection getAll() throws DaoException { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + Collection all = new ArrayList(); + + try { + con = JdbcUtil.getDbConnection(DaoClinicalAttributeMeta.class); + pstmt = con.prepareStatement("SELECT * FROM clinical_attribute_meta"); + rs = pstmt.executeQuery(); + + while (rs.next()) { + all.add(unpack(rs)); + } + + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoClinicalAttributeMeta.class, con, pstmt, rs); + } + return all; + } + + public static Map getAllMap() throws DaoException { + + HashMap toReturn = new HashMap(); + for (ClinicalAttribute clinicalAttribute : DaoClinicalAttributeMeta.getAll()) { + toReturn.put(clinicalAttribute.getAttrId(), clinicalAttribute.getDisplayName()); + } + return toReturn; + } + + /** + * Deletes all Records. + * @throws DaoException DAO Error. + */ + public static void deleteAllRecords() throws DaoException { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoClinicalAttributeMeta.class); + pstmt = con.prepareStatement("TRUNCATE TABLE clinical_attribute_meta"); + pstmt.executeUpdate(); + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoClinicalAttributeMeta.class, con, pstmt, rs); + } + } +} diff --git a/DaoClinicalData.java b/DaoClinicalData.java new file mode 100644 index 0000000..003af6e --- /dev/null +++ b/DaoClinicalData.java @@ -0,0 +1,716 @@ +/* + * Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS + * FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder + * is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no + * obligations to provide maintenance, support, updates, enhancements or + * modifications. In no event shall Memorial Sloan-Kettering Cancer Center be + * liable to any party for direct, indirect, special, incidental or + * consequential damages, including lost profits, arising out of the use of this + * software and its documentation, even if Memorial Sloan-Kettering Cancer + * Center has been advised of the possibility of such damage. + */ + +/* + * This file is part of cBioPortal. + * + * cBioPortal is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . +*/ + +package org.mskcc.cbio.portal.dao; + +import org.mskcc.cbio.portal.model.*; +import org.mskcc.cbio.portal.util.InternalIdUtil; + +import edu.jhu.u01.DBProperties; + +import org.apache.commons.lang.StringUtils; + +import java.sql.*; +import java.util.*; + +/** + * Data Access Object for `clinical` table + * + * @author Gideon Dresdner dresdnerg@cbio.mskcc.org + */ +public final class DaoClinicalData { + + public static final String SAMPLE_TABLE = "clinical_sample"; + public static final String PATIENT_TABLE = "clinical_patient"; + + private static final String SAMPLE_INSERT = "INSERT INTO " + SAMPLE_TABLE + "(INTERAL_ID,ATTR_ID,ATTR_VALUE VALUES(?,?,?)";//JK-UPDATED + private static final String PATIENT_INSERT = "INSERT INTO " + PATIENT_TABLE + "(INTERNAL_ID,ATTR_ID,ATTR_VALUE VALUES(?,?,?)";//JK-UPDATED + + private static final Map sampleAttributes = new HashMap(); + private static final Map patientAttributes = new HashMap(); + + private DaoClinicalData() {} + + public static synchronized void reCache() + { + clearCache(); + cacheAttributes(SAMPLE_TABLE, sampleAttributes); + cacheAttributes(PATIENT_TABLE, patientAttributes); + } + + private static void clearCache() + { + sampleAttributes.clear(); + patientAttributes.clear(); + } + + private static void cacheAttributes(String table, Map cache) + { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoClinicalData.class); + pstmt = con.prepareStatement("SELECT * FROM " + table); + rs = pstmt.executeQuery(); + while (rs.next()) { + cache.put(rs.getString("ATTR_ID"), rs.getString("ATTR_ID")); + } + } + catch (SQLException e) { + e.printStackTrace(); + } + finally { + JdbcUtil.closeAll(DaoClinicalData.class, con, pstmt, rs); + } + } + + public static int addSampleDatum(int internalSampleId, String attrId, String attrVal) throws DaoException + { + sampleAttributes.put(attrId, attrId); + return addDatum(SAMPLE_INSERT, SAMPLE_TABLE, internalSampleId, attrId, attrVal); + } + + public static int addPatientDatum(int internalPatientId, String attrId, String attrVal) throws DaoException + { + patientAttributes.put(attrId, attrId); + return addDatum(PATIENT_INSERT, PATIENT_TABLE, internalPatientId, attrId, attrVal); + } + + public static int addDatum(String query, String tableName, + int internalId, String attrId, String attrVal) throws DaoException + { + if (MySQLbulkLoader.isBulkLoad()) { + MySQLbulkLoader.getMySQLbulkLoader(tableName).insertRecord(Integer.toString(internalId), + attrId, + attrVal); + return 1; + } + + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoClinicalData.class); + + pstmt = con.prepareStatement(query); + pstmt.setInt(1, internalId); + pstmt.setString(2, attrId); + pstmt.setString(3, attrVal); + int toReturn = pstmt.executeUpdate(); + + if (tableName.equals(PATIENT_TABLE)) { + patientAttributes.put(attrId, attrId); + } + else { + sampleAttributes.put(attrId, attrId); + } + + return toReturn; + } + catch (SQLException e) { + throw new DaoException(e); + } + finally { + JdbcUtil.closeAll(DaoClinicalData.class, con, pstmt, rs); + } + } + + public static ClinicalData getDatum(String cancerStudyId, String patientId, String attrId) throws DaoException + { + int internalCancerStudyId = getInternalCancerStudyId(cancerStudyId); + String table = getAttributeTable(attrId); + if (table==null) { + return null; + } + return getDatum(internalCancerStudyId, + table, + DaoPatient.getPatientByCancerStudyAndPatientId(internalCancerStudyId, patientId).getInternalId(), + attrId); + } + + private static int getInternalCancerStudyId(String cancerStudyId) throws DaoException + { + return DaoCancerStudy.getCancerStudyByStableId(cancerStudyId).getInternalId(); + } + + + private static String getAttributeTable(String attrId) throws DaoException + { + if (sampleAttributes.containsKey(attrId)) { + return SAMPLE_TABLE; + } + else if (patientAttributes.containsKey(attrId)) { + return (PATIENT_TABLE); + } + else { + return null; + } + } + + private static ClinicalData getDatum(int internalCancerStudyId, String table, int internalId, String attrId) throws DaoException + { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + + try { + con = JdbcUtil.getDbConnection(DaoClinicalData.class); + + pstmt = con.prepareStatement("SELECT * FROM " + table + + " WHERE INTERNAL_ID=? AND ATTR_ID=?"); + pstmt.setInt(1, internalId); + pstmt.setString(2, attrId); + + rs = pstmt.executeQuery(); + if (rs.next()) { + return extract(table, internalCancerStudyId, rs); + } + else { + return null; + } + } + catch (SQLException e) { + throw new DaoException(e); + } + finally { + JdbcUtil.closeAll(DaoClinicalData.class, con, pstmt, rs); + } + } + + public static List getDataByPatientId(int cancerStudyId, String patientId) throws DaoException + { + List internalIds = new ArrayList(); + internalIds.add(DaoPatient.getPatientByCancerStudyAndPatientId(cancerStudyId, patientId).getInternalId()); + return getDataByInternalIds(cancerStudyId, PATIENT_TABLE, internalIds); + } + + private static List getDataByInternalIds(int internalCancerStudyId, String table, List internalIds) throws DaoException + { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + + List clinicals = new ArrayList(); + String sql= null; + switch(DBProperties.getDBVendor()){ + case mssql: + sql = ("SELECT * FROM " + table + " WHERE INTERNAL_ID IN " + + "(" + generateIdsSql(internalIds) + ")"); + + break; + default: + sql = ("SELECT * FROM " + table + " WHERE `INTERNAL_ID` IN " + + "(" + generateIdsSql(internalIds) + ")"); + + break; + }//JK-UPDATED + + + + try { + con = JdbcUtil.getDbConnection(DaoClinicalData.class); + pstmt = con.prepareStatement(sql); + rs = pstmt.executeQuery(); + while (rs.next()) { + clinicals.add(extract(table, internalCancerStudyId, rs)); + } + } + catch (SQLException e) { + throw new DaoException(e); + } + finally { + JdbcUtil.closeAll(DaoClinicalData.class, con, pstmt, rs); + } + + return clinicals; + } + + public static List getData(String cancerStudyId) throws DaoException + { + return getData(getInternalCancerStudyId(cancerStudyId)); + } + public static List getData(int cancerStudyId) throws DaoException + { + + return getDataByInternalIds(cancerStudyId, PATIENT_TABLE, getPatientIdsByCancerStudy(cancerStudyId)); + } + + private static List getPatientIdsByCancerStudy(int cancerStudyId) + { + List patientIds = new ArrayList(); + for (Patient patient : DaoPatient.getPatientsByCancerStudyId(cancerStudyId)) { + patientIds.add(patient.getInternalId()); + } + return patientIds; + } + + private static List getSampleIdsByCancerStudy(int cancerStudyId) + { + List sampleIds = new ArrayList(); + for (Patient patient : DaoPatient.getPatientsByCancerStudyId(cancerStudyId)) { + for (Sample s : DaoSample.getSamplesByPatientId(patient.getInternalId())) { + sampleIds.add(s.getInternalId()); + } + } + return sampleIds; + } + + public static List getData(String cancerStudyId, Collection patientIds) throws DaoException + { + return getData(getInternalCancerStudyId(cancerStudyId), patientIds); + } + public static List getData(int cancerStudyId, Collection patientIds) throws DaoException + { + List patientIdsInt = new ArrayList(); + for (String patientId : patientIds) { + patientIdsInt.add(DaoPatient.getPatientByCancerStudyAndPatientId(cancerStudyId, patientId).getInternalId()); + } + + return getDataByInternalIds(cancerStudyId, PATIENT_TABLE, patientIdsInt); + } + + public static List getSampleAndPatientData(int cancerStudyId, Collection sampleIds) throws DaoException + { + List sampleIdsInt = new ArrayList(); + List patientIdsInt = new ArrayList(); + Map> mapPatientIdSampleIds = new HashMap>(); + for (String sampleId : sampleIds) { + Sample sample = DaoSample.getSampleByCancerStudyAndSampleId(cancerStudyId, sampleId); + sampleIdsInt.add(sample.getInternalId()); + int patientIdInt = sample.getInternalPatientId(); + String patientIdStable = DaoPatient.getPatientById(patientIdInt).getStableId(); + patientIdsInt.add(patientIdInt); + Set sampleIdsForPatient = mapPatientIdSampleIds.get(patientIdStable); + if (sampleIdsForPatient==null) { + sampleIdsForPatient = new HashSet(); + mapPatientIdSampleIds.put(patientIdStable, sampleIdsForPatient); + } + sampleIdsForPatient.add(sampleId); + } + List sampleClinicalData = getDataByInternalIds(cancerStudyId, SAMPLE_TABLE, sampleIdsInt); + + List patientClinicalData = getDataByInternalIds(cancerStudyId, PATIENT_TABLE, patientIdsInt); + for (ClinicalData cd : patientClinicalData) { + String stablePatientId = cd.getStableId(); + Set sampleIdsForPatient = mapPatientIdSampleIds.get(stablePatientId); + for (String sampleId : sampleIdsForPatient) { + ClinicalData cdSample = new ClinicalData(cd); + cdSample.setStableId(sampleId); + sampleClinicalData.add(cdSample); + } + } + + return sampleClinicalData; + } + + public static List getSampleAndPatientData(int cancerStudyId, Collection sampleIds, ClinicalAttribute attr) throws DaoException + { + List sampleIdsInt = new ArrayList(); + List patientIdsInt = new ArrayList(); + Map> mapPatientIdSampleIds = new HashMap>(); + for (String sampleId : sampleIds) { + Sample sample = DaoSample.getSampleByCancerStudyAndSampleId(cancerStudyId, sampleId); + sampleIdsInt.add(sample.getInternalId()); + int patientIdInt = sample.getInternalPatientId(); + String patientIdStable = DaoPatient.getPatientById(patientIdInt).getStableId(); + patientIdsInt.add(patientIdInt); + Set sampleIdsForPatient = mapPatientIdSampleIds.get(patientIdStable); + if (sampleIdsForPatient==null) { + sampleIdsForPatient = new HashSet(); + mapPatientIdSampleIds.put(patientIdStable, sampleIdsForPatient); + } + sampleIdsForPatient.add(sampleId); + } + List sampleClinicalData = getDataByInternalIds(cancerStudyId, SAMPLE_TABLE, sampleIdsInt, Collections.singletonList(attr.getAttrId())); + + List patientClinicalData = getDataByInternalIds(cancerStudyId, PATIENT_TABLE, patientIdsInt, Collections.singletonList(attr.getAttrId())); + for (ClinicalData cd : patientClinicalData) { + String stablePatientId = cd.getStableId(); + Set sampleIdsForPatient = mapPatientIdSampleIds.get(stablePatientId); + for (String sampleId : sampleIdsForPatient) { + ClinicalData cdSample = new ClinicalData(cd); + cdSample.setStableId(sampleId); + sampleClinicalData.add(cdSample); + } + } + + return sampleClinicalData; + } + + public static List getSampleData(int cancerStudyId, Collection sampleIds, ClinicalAttribute attr) throws DaoException + { + List sampleIdsInt = new ArrayList(); + for (String sampleId : sampleIds) { + sampleIdsInt.add(DaoSample.getSampleByCancerStudyAndSampleId(cancerStudyId, sampleId).getInternalId()); + } + return getDataByInternalIds(cancerStudyId, SAMPLE_TABLE, sampleIdsInt, Collections.singletonList(attr.getAttrId())); + } + + public static List getSampleData(int cancerStudyId, Collection sampleIds) throws DaoException + { + List sampleIdsInt = new ArrayList(); + for (String sampleId : sampleIds) { + sampleIdsInt.add(DaoSample.getSampleByCancerStudyAndSampleId(cancerStudyId, sampleId).getInternalId()); + } + return getDataByInternalIds(cancerStudyId, SAMPLE_TABLE, sampleIdsInt); + } + + public static List getData(String cancerStudyId, Collection patientIds, ClinicalAttribute attr) throws DaoException + { + int internalCancerStudyId = getInternalCancerStudyId(cancerStudyId); + List patientIdsInt = new ArrayList(); + for (String patientId : patientIds) { + patientIdsInt.add(DaoPatient.getPatientByCancerStudyAndPatientId(internalCancerStudyId, patientId).getInternalId()); + } + + return getDataByInternalIds(internalCancerStudyId, PATIENT_TABLE, patientIdsInt, Collections.singletonList(attr.getAttrId())); + } + + private static List getDataByInternalIds(int internalCancerStudyId, String table, List internalIds, Collection attributeIds) throws DaoException + { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + + List clinicals = new ArrayList(); + + String sql = null; + switch(DBProperties.getDBVendor()){ + case mssql: + sql = ("SELECT * FROM " + table + " WHERE INTERNAL_ID IN " + + "(" + generateIdsSql(internalIds) + ") " + + " AND ATTR_ID IN ('"+ StringUtils.join(attributeIds, "','")+"') "); + break; + default: + sql = ("SELECT * FROM " + table + " WHERE `INTERNAL_ID` IN " + + "(" + generateIdsSql(internalIds) + ") " + + " AND ATTR_ID IN ('"+ StringUtils.join(attributeIds, "','")+"') "); + break; + }//JK-UPDATED + + + try { + con = JdbcUtil.getDbConnection(DaoClinicalData.class); + pstmt = con.prepareStatement(sql); + rs = pstmt.executeQuery(); + while (rs.next()) { + clinicals.add(extract(table, internalCancerStudyId, rs)); + } + } catch (SQLException e) { + throw new DaoException(e); + } + finally { + JdbcUtil.closeAll(DaoClinicalData.class, con, pstmt, rs); + } + return clinicals; + } + + public static List getDataByAttributeIds(int internalCancerStudyId, Collection attributeIds) throws DaoException { + + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + + List clinicals = new ArrayList(); + + try { + con = JdbcUtil.getDbConnection(DaoClinicalData.class); + + pstmt = con.prepareStatement("SELECT * FROM clinical_patient WHERE" + + " ATTR_ID IN ('" + StringUtils.join(attributeIds, "','") +"') "); + + List patients = getPatientIdsByCancerStudy(internalCancerStudyId); + + rs = pstmt.executeQuery(); + while(rs.next()) { + Integer patientId = rs.getInt("INTERNAL_ID"); + if (patients.contains(patientId)) { + clinicals.add(extract(PATIENT_TABLE, internalCancerStudyId, rs)); + } + } + } + catch (SQLException e) { + throw new DaoException(e); + } + finally { + JdbcUtil.closeAll(DaoClinicalData.class, con, pstmt, rs); + } + + return clinicals; + } + + private static ClinicalData extract(String table, int internalCancerStudyId, ResultSet rs) throws SQLException { + // get + String stableId = getStableIdFromInternalId(table, rs.getInt("INTERNAL_ID")); + return new ClinicalData(internalCancerStudyId, + stableId, + rs.getString("ATTR_ID"), + rs.getString("ATTR_VALUE")); + } + + private static String getStableIdFromInternalId(String table, int internalId) + { + if (table.equals(SAMPLE_TABLE)) { + return DaoSample.getSampleById(internalId).getStableId(); + } + else { + return DaoPatient.getPatientById(internalId).getStableId(); + } + } + + private static String generateIdsSql(Collection ids) { + return "'" + StringUtils.join(ids, "','") + "'"; + } + + public static void deleteAllRecords() throws DaoException { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoClinicalData.class); + pstmt = con.prepareStatement("TRUNCATE TABLE clinical_patient"); + pstmt.executeUpdate(); + pstmt = con.prepareStatement("TRUNCATE TABLE clinical_sample"); + pstmt.executeUpdate(); + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoClinicalData.class, con, pstmt, rs); + } + reCache(); + } + + /********************************************************* + * Previous DaoClinicalData class methods (accessors only) + *********************************************************/ + + /** + * Returns the survival data for the given patientSet, NOT necessarily in the + * same order as the patientSet. + * + * @param cancerStudyId: the cancerstudy internal id + * @param patientSet: set of patient ids + * @return + * @throws DaoException + */ + public static List getSurvivalData(int cancerStudyId, Collection patientSet) throws DaoException { + CancerStudy cancerStudy = DaoCancerStudy.getCancerStudyByInternalId(cancerStudyId); + List data = getData(cancerStudyId, patientSet); + Map> clinicalData = new LinkedHashMap>(); + for (ClinicalData cd : data) { + String patientId = cd.getStableId(); + Map msc = clinicalData.get(cd.getStableId()); + if (msc==null) { + msc = new HashMap(); + clinicalData.put(patientId, msc); + } + msc.put(cd.getAttrId(), cd); + } + + ArrayList toReturn = new ArrayList(); + for (Map.Entry> entry : clinicalData.entrySet()) { + Patient patient = DaoPatient.getPatientByCancerStudyAndPatientId(cancerStudyId, entry.getKey()); + toReturn.add(new Patient(cancerStudy, patient.getStableId(), patient.getInternalId(), entry.getValue())); + } + return toReturn; + } + + /************************************************************** + * Previous DaoClinicalFreeForm class methods (accessors only) + *************************************************************/ + + public static List getDataSlice(int cancerStudyId, Collection attributeIds) throws DaoException { + + Map> mapAttrStableIdValue = new HashMap>(); + for (ClinicalData cd : getDataByAttributeIds(cancerStudyId, attributeIds)) { + + String attrId = cd.getAttrId(); + String value = cd.getAttrVal(); + String stableId = cd.getStableId(); + + if (value.isEmpty() || value.equals(ClinicalAttribute.NA)) { + continue; + } + + Map mapStableIdValue = mapAttrStableIdValue.get(attrId); + if (mapStableIdValue == null) { + mapStableIdValue = new HashMap(); + mapAttrStableIdValue.put(attrId, mapStableIdValue); + } + mapStableIdValue.put(stableId, value); + } + + List maps = new ArrayList(); + for (Map.Entry> entry : mapAttrStableIdValue.entrySet()) { + maps.add(new ClinicalParameterMap(entry.getKey(), entry.getValue())); + } + + return maps; + } + + public static HashSet getDistinctParameters(int cancerStudyId) throws DaoException { + + HashSet toReturn = new HashSet(); + for (ClinicalData clinicalData : DaoClinicalData.getData(cancerStudyId)) { + toReturn.add(clinicalData.getAttrId()); + } + + return toReturn; + } + public static HashSet getAllPatients(int cancerStudyId) throws DaoException { + + HashSet toReturn = new HashSet(); + for (ClinicalData clinicalData : getData(cancerStudyId)) { + toReturn.add(clinicalData.getStableId()); + } + + return toReturn; + } + public static List getDataByCancerStudy(int cancerStudyId) throws DaoException { + + return DaoClinicalData.getData(cancerStudyId); + } + + public static List getDataByPatientIds(int cancerStudyId, List patientIds) throws DaoException { + + return DaoClinicalData.getData(cancerStudyId, patientIds); + } + + public static List getPatientsByAttribute(int cancerStudy, String paramName, String paramValue) throws DaoException + { + List ids = getIdsByAttribute(cancerStudy, paramName, paramValue, PATIENT_TABLE); + return InternalIdUtil.getPatientsById(ids); + } + + public static List getSamplesByAttribute(int cancerStudy, String paramName, String paramValue) throws DaoException + { + List ids = getIdsByAttribute(cancerStudy, paramName, paramValue, SAMPLE_TABLE); + return InternalIdUtil.getSamplesById(ids); + } + + + private static List getIdsByAttribute(int cancerStudyId, String paramName, String paramValue, String tableName) throws DaoException + { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + + try{ + con = JdbcUtil.getDbConnection(DaoClinicalData.class); + switch(DBProperties.getDBVendor()){ + case mssql: + pstmt = con.prepareStatement ("SELECT INTERNAL_ID FROM " + tableName + "" + + " WHERE ATTR_ID=? AND ATTR_VALUE=?"); + + break; + default: + pstmt = con.prepareStatement ("SELECT INTERNAL_ID FROM `" + tableName + "`" + + " WHERE ATTR_ID=? AND ATTR_VALUE=?"); + + break; + }//JK-UPDATED + + + pstmt.setString(1, paramName); + pstmt.setString(2, paramValue); + rs = pstmt.executeQuery(); + + List ids = new ArrayList(); + + while (rs.next()) + { + ids.add(rs.getInt("INTERNAL_ID")); + } + + return ids; + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoClinicalData.class, con, pstmt, rs); + } + } + + // get cancerType from the clinical_sample table to determine whether we have multiple cancer types + // in one study + public static Map> getCancerTypeInfo(int studyID) throws DaoException { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + + try{ + con = JdbcUtil.getDbConnection(DaoClinicalData.class); + pstmt = con.prepareStatement("select " + + "distinct attr_value as attributeValue, " + + "attr_id as attributeID " + + "from clinical_sample " + + "where attr_id in (?, ?) " + + "and INTERNAL_ID in ( " + + " select INTERNAL_ID " + + " from sample " + + " where PATIENT_ID in ( " + + " select INTERNAL_ID " + + " from patient " + + " where CANCER_STUDY_ID = ? " + + " )" + + " )"); + pstmt.setString(1, ClinicalAttribute.CANCER_TYPE); + pstmt.setString(2, ClinicalAttribute.CANCER_TYPE_DETAILED); + pstmt.setInt(3, studyID); + rs = pstmt.executeQuery(); + + // create a map for the results + Map> result = new LinkedHashMap>(); + String attributeValue, attributeID; + List attributeValues; + while (rs.next()) + { + attributeValue = rs.getString("attributeValue"); + attributeID = rs.getString("attributeID"); + attributeValues = result.get(attributeID); + // if no attributeValues exists for the attributeID, add a new list + if(attributeValues==null){ + attributeValues = new ArrayList(); + result.put(attributeID, attributeValues); + } + // add the attributeValue to the list + attributeValues.add(attributeValue); + } + + return result; + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoClinicalData.class, con, pstmt, rs); + } + } +} diff --git a/DaoClinicalEvent.java b/DaoClinicalEvent.java new file mode 100644 index 0000000..e493f59 --- /dev/null +++ b/DaoClinicalEvent.java @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS + * FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder + * is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no + * obligations to provide maintenance, support, updates, enhancements or + * modifications. In no event shall Memorial Sloan-Kettering Cancer Center be + * liable to any party for direct, indirect, special, incidental or + * consequential damages, including lost profits, arising out of the use of this + * software and its documentation, even if Memorial Sloan-Kettering Cancer + * Center has been advised of the possibility of such damage. + */ + +/* + * This file is part of cBioPortal. + * + * cBioPortal is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . +*/ + +package org.mskcc.cbio.portal.dao; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.apache.commons.lang.StringUtils; +import org.mskcc.cbio.portal.model.ClinicalEvent; + +import edu.jhu.u01.DBProperties; + +/** + * + * @author gaoj + */ +public final class DaoClinicalEvent { + private DaoClinicalEvent() {} + + public static int addClinicalEvent(ClinicalEvent clinicalEvent) { + if (!MySQLbulkLoader.isBulkLoad()) { + throw new IllegalStateException("Only buld load mode is allowed for importing clinical events"); + } + + MySQLbulkLoader.getMySQLbulkLoader("clinical_event").insertRecord( + Long.toString(clinicalEvent.getClinicalEventId()), + Integer.toString(clinicalEvent.getPatientId()), + clinicalEvent.getStartDate().toString(), + clinicalEvent.getStopDate()==null?null:clinicalEvent.getStopDate().toString(), + clinicalEvent.getEventType() + ); + return 1+addClinicalEventData(clinicalEvent); + } + + private static int addClinicalEventData(ClinicalEvent clinicalEvent) { + long eventId = clinicalEvent.getClinicalEventId(); + for (Map.Entry entry : clinicalEvent.getEventData().entrySet()) { + MySQLbulkLoader.getMySQLbulkLoader("clinical_event_data").insertRecord( + Long.toString(eventId), + entry.getKey(), + entry.getValue() + ); + } + return 1; + + } + + public static List getClinicalEvent(int patientId) throws DaoException { + return getClinicalEvent(patientId, null); + } + + public static List getClinicalEvent(int patientId, String eventType) throws DaoException { + + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoClinicalEvent.class); + + // get events first + if (eventType==null) { + pstmt = con.prepareStatement("SELECT * FROM clinical_event WHERE PATIENT_ID=?"); + } else { + pstmt = con.prepareStatement("SELECT * FROM clinical_event WHERE PATIENT_ID=? AND EVENT_TYPE=?"); + } + pstmt.setInt(1, patientId); + if (eventType!=null) { + pstmt.setString(2, eventType); + } + + rs = pstmt.executeQuery(); + Map clinicalEvents = new HashMap(); + while (rs.next()) { + ClinicalEvent clinicalEvent = extractClinicalEvent(rs); + clinicalEvents.put(clinicalEvent.getClinicalEventId(), clinicalEvent); + } + + rs.close(); + + // get data then + if (!clinicalEvents.isEmpty()) { + pstmt = con.prepareStatement("SELECT * FROM clinical_event_data WHERE CLINICAL_EVENT_ID IN (" + + StringUtils.join(clinicalEvents.keySet(), ",") + ")"); + + rs = pstmt.executeQuery(); + while (rs.next()) { + long eventId = rs.getLong("CLINICAL_EVENT_ID"); + clinicalEvents.get(eventId).addEventDatum(rs.getString("KEY"), rs.getString("VALUE")); + } + } + + return new ArrayList(clinicalEvents.values()); + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoClinicalEvent.class, con, pstmt, rs); + } + } + + private static ClinicalEvent extractClinicalEvent(ResultSet rs) throws SQLException { + ClinicalEvent clinicalEvent = new ClinicalEvent(); + clinicalEvent.setClinicalEventId(rs.getLong("CLINICAL_EVENT_ID")); + clinicalEvent.setPatientId(rs.getInt("PATIENT_ID")); + clinicalEvent.setStartDate(JdbcUtil.readLongFromResultSet(rs, "START_DATE")); + clinicalEvent.setStopDate(JdbcUtil.readLongFromResultSet(rs, "STOP_DATE")); + clinicalEvent.setEventType(rs.getString("EVENT_TYPE")); + return clinicalEvent; + } + + public static long getLargestClinicalEventId() throws DaoException { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoClinicalEvent.class); + switch(DBProperties.getDBVendor()){ + case mssql: + pstmt = con.prepareStatement + ("SELECT MAX(CLINICAL_EVENT_ID) FROM clinical_event"); + break; + default: + pstmt = con.prepareStatement + ("SELECT MAX(`CLINICAL_EVENT_ID`) FROM `clinical_event`"); + break; + }//JK-UPDATED + + + rs = pstmt.executeQuery(); + return rs.next() ? rs.getLong(1) : 0; + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoClinicalEvent.class, con, pstmt, rs); + } + } + + /** + * + * @param cancerStudyId + * @param caseId + * @return true if timeline data exist for the case + * @throws DaoException + */ + public static boolean timeEventsExistForPatient(int patientId) throws DaoException { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoCopyNumberSegment.class); + switch(DBProperties.getDBVendor()){ + case mssql: + //pstmt = con.prepareStatement("SELECT CAST (CASE WHEN COUNT (*) = 1 THEN 1 ELSE 0 END AS BIT) FROM (" + // + "SELECT TOP 1 1 AS B FROM clinical_event WHERE PATIENT_ID=?) AS A"); + pstmt = con.prepareStatement("SELECT TOP 1 1 AS B FROM clinical_event WHERE PATIENT_ID=?"); + break; + default: + pstmt = con.prepareStatement("SELECT EXISTS(SELECT 1 FROM `clinical_event` WHERE `PATIENT_ID`=?)"); + break; + }//JK-UPDATED + + + pstmt.setInt(1, patientId); + rs = pstmt.executeQuery(); + return rs.next() && rs.getInt(1)==1; + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoCopyNumberSegment.class, con, pstmt, rs); + } + } + + public static void deleteByCancerStudyId(int cancerStudyId) throws DaoException { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoClinicalEvent.class); + + pstmt = con.prepareStatement("DELETE FROM clinical_event_data WHERE CLINICAL_EVENT_ID IN " + + "(SELECT CLINICAL_EVENT_ID FROM clinical_event WHERE PATIENT_ID in (SELECT INTERNAL_ID FROM patient where CANCER_STUDY_ID=?))"); + pstmt.setInt(1, cancerStudyId); + pstmt.executeUpdate(); + + pstmt = con.prepareStatement("DELETE FROM clinical_event WHERE PATIENT_ID in (SELECT INTERNAL_ID FROM patient where CANCER_STUDY_ID=?)"); + pstmt.setInt(1, cancerStudyId); + pstmt.executeUpdate(); + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoClinicalEvent.class, con, pstmt, rs); + } + } + + public static void deleteAllRecords() throws DaoException { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoClinicalData.class); + JdbcUtil.disableForeignKeyCheck(con); + pstmt = con.prepareStatement("TRUNCATE TABLE clinical_event_data"); + pstmt.executeUpdate(); + pstmt = con.prepareStatement("TRUNCATE TABLE clinical_event"); + pstmt.executeUpdate(); + JdbcUtil.enableForeignKeyCheck(con); + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoClinicalData.class, con, pstmt, rs); + } + } +} diff --git a/DaoCnaEvent.java b/DaoCnaEvent.java new file mode 100644 index 0000000..ad5ae03 --- /dev/null +++ b/DaoCnaEvent.java @@ -0,0 +1,378 @@ +/* + * Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS + * FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder + * is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no + * obligations to provide maintenance, support, updates, enhancements or + * modifications. In no event shall Memorial Sloan-Kettering Cancer Center be + * liable to any party for direct, indirect, special, incidental or + * consequential damages, including lost profits, arising out of the use of this + * software and its documentation, even if Memorial Sloan-Kettering Cancer + * Center has been advised of the possibility of such damage. + */ + +/* + * This file is part of cBioPortal. + * + * cBioPortal is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . +*/ + +package org.mskcc.cbio.portal.dao; + +import org.apache.commons.lang.StringUtils; +import org.mskcc.cbio.portal.model.CnaEvent; +import org.mskcc.cbio.portal.model.Sample; + +import edu.jhu.u01.DBProperties; + +import java.sql.*; +import java.util.*; + +/** + * + * @author jgao + */ +public final class DaoCnaEvent { + private DaoCnaEvent() {} + + public static void addCaseCnaEvent(CnaEvent cnaEvent, boolean newCnaEvent) throws DaoException { + if (!MySQLbulkLoader.isBulkLoad()) {//JK-FUTURE-TODO + throw new DaoException("You have to turn on MySQLbulkLoader in order to insert sample_cna_event"); + } + else { + long eventId = cnaEvent.getEventId(); + if (newCnaEvent) { + eventId = addCnaEventDirectly(cnaEvent); + // update object based on new DB id (since this object is locally cached after this): + cnaEvent.setEventId(eventId); + } + + MySQLbulkLoader.getMySQLbulkLoader("sample_cna_event").insertRecord( + Long.toString(eventId), + Integer.toString(cnaEvent.getSampleId()), + Integer.toString(cnaEvent.getCnaProfileId()) + ); + } + } + + /** + * Add new event directly and return the auto increment value. + * + * @param cnaEvent + * @return + * @throws DaoException + */ + private static long addCnaEventDirectly(CnaEvent cnaEvent) throws DaoException { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoCnaEvent.class); + switch(DBProperties.getDBVendor()){ + case mssql: + pstmt = con.prepareStatement + ("INSERT INTO cna_event (" + + "[ENTREZ_GENE_ID]," + + "[ALTERATION] )" + + " VALUES(?,?)", Statement.RETURN_GENERATED_KEYS); + break; + default: + pstmt = con.prepareStatement + ("INSERT INTO cna_event (" + + "`ENTREZ_GENE_ID`," + + "`ALTERATION` )" + + " VALUES(?,?)", Statement.RETURN_GENERATED_KEYS); + break; + }//JK-UPDATED + + + pstmt.setLong(1, cnaEvent.getEntrezGeneId()); + pstmt.setShort(2, cnaEvent.getAlteration().getCode()); + pstmt.executeUpdate(); + rs = pstmt.getGeneratedKeys(); + rs.next(); + long newId = rs.getLong(1); + return newId; + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoCnaEvent.class, con, pstmt, rs); + } + } + + public static Map> getSamplesWithAlterations( + Collection eventIds) throws DaoException { + return getSamplesWithAlterations(StringUtils.join(eventIds, ",")); + } + + public static Map> getSamplesWithAlterations(String concatEventIds) + throws DaoException { + if (concatEventIds.isEmpty()) { + return Collections.emptyMap(); + } + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoCnaEvent.class); + String sql = null; + switch(DBProperties.getDBVendor()){ + case mssql: + sql = "SELECT * FROM sample_cna_event" + + " WHERE [CNA_EVENT_ID] IN (" + + concatEventIds + ")"; + break; + default: + sql = "SELECT * FROM sample_cna_event" + + " WHERE `CNA_EVENT_ID` IN (" + + concatEventIds + ")"; + break; + }//JK-UPDATED + + + pstmt = con.prepareStatement(sql); + + Map> map = new HashMap> (); + rs = pstmt.executeQuery(); + while (rs.next()) { + Sample sample = DaoSample.getSampleById(rs.getInt("SAMPLE_ID")); + long eventId = rs.getLong("CNA_EVENT_ID"); + Set events = map.get(sample); + if (events == null) { + events = new HashSet(); + map.put(sample, events); + } + events.add(eventId); + } + return map; + } catch (NullPointerException e) { + throw new DaoException(e); + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoCnaEvent.class, con, pstmt, rs); + } + } + + public static List getCnaEvents(List sampleIds, Collection entrezGeneIds , int profileId, Collection cnaLevels) throws DaoException { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoCnaEvent.class); + // GL added test on entrezGeneIds.size()==0, as in that case incorrect SQL is generated + String sql="SELECT sample_cna_event.CNA_EVENT_ID, SAMPLE_ID, GENETIC_PROFILE_ID," + + " ENTREZ_GENE_ID, ALTERATION FROM sample_cna_event, cna_event" + + " WHERE GENETIC_PROFILE_ID=?" + + " AND sample_cna_event.CNA_EVENT_ID=cna_event.CNA_EVENT_ID" + + (entrezGeneIds==null||entrezGeneIds.size() == 0?"":" AND ENTREZ_GENE_ID IN(" + StringUtils.join(entrezGeneIds,",") + ")") + + " AND ALTERATION IN (" + StringUtils.join(cnaLevels,",") + ")" + + " AND SAMPLE_ID in ('"+StringUtils.join(sampleIds, "','")+"')";//JK-UPDATED + + pstmt = con.prepareStatement(sql); + pstmt.setInt(1, profileId); + rs = pstmt.executeQuery(); + List events = new ArrayList(); + while (rs.next()) { + try { + Sample sample = DaoSample.getSampleById(rs.getInt("SAMPLE_ID")); + CnaEvent event = new CnaEvent(sample.getInternalId(), + rs.getInt("GENETIC_PROFILE_ID"), + rs.getLong("ENTREZ_GENE_ID"), rs.getShort("ALTERATION")); + event.setEventId(rs.getLong("CNA_EVENT_ID")); + events.add(event); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } + } + return events; + } catch (NullPointerException e) { + throw new DaoException(e); + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoCnaEvent.class, con, pstmt, rs); + } + } + + public static List getAllCnaEvents() throws DaoException { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoCnaEvent.class); + pstmt = con.prepareStatement + ("SELECT * FROM cna_event"); + rs = pstmt.executeQuery(); + List events = new ArrayList(); + while (rs.next()) { + try { + CnaEvent.Event event = new CnaEvent.Event(); + event.setEventId(rs.getLong("CNA_EVENT_ID")); + event.setEntrezGeneId(rs.getLong("ENTREZ_GENE_ID")); + event.setAlteration(rs.getShort("ALTERATION")); + events.add(event); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } + } + return events; + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoCnaEvent.class, con, pstmt, rs); + } + } + + public static Map> countSamplesWithCNAGenes( + Collection entrezGeneIds, int profileId) throws DaoException { + return countSamplesWithCNAGenes(StringUtils.join(entrezGeneIds, ","), profileId); + } + + public static Map> countSamplesWithCNAGenes( + String concatEntrezGeneIds, int profileId) throws DaoException { + if (concatEntrezGeneIds.isEmpty()) { + return Collections.emptyMap(); + } + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoCnaEvent.class); + String sql = null; + switch(DBProperties.getDBVendor()){ + case mssql: + sql = "SELECT [ENTREZ_GENE_ID], [ALTERATION], count(*)" + + " FROM sample_cna_event, cna_event" + + " WHERE [GENETIC_PROFILE_ID]=" + profileId + + " and sample_cna_event.[CNA_EVENT_ID]=cna_event.[CNA_EVENT_ID]" + + " and [ENTREZ_GENE_ID] IN (" + + concatEntrezGeneIds + + ") GROUP BY [ENTREZ_GENE_ID], [ALTERATION]"; + break; + default: + sql = "SELECT `ENTREZ_GENE_ID`, `ALTERATION`, count(*)" + + " FROM sample_cna_event, cna_event" + + " WHERE `GENETIC_PROFILE_ID`=" + profileId + + " and sample_cna_event.`CNA_EVENT_ID`=cna_event.`CNA_EVENT_ID`" + + " and `ENTREZ_GENE_ID` IN (" + + concatEntrezGeneIds + + ") GROUP BY `ENTREZ_GENE_ID`, `ALTERATION`"; + break; + }//JK-UPDATED + + + pstmt = con.prepareStatement(sql); + + Map> map = new HashMap>(); + rs = pstmt.executeQuery(); + while (rs.next()) { + Long entrez = rs.getLong(1); + Integer alt = rs.getInt(2); + Integer count = rs.getInt(3); + Map mapII = map.get(entrez); + if (mapII==null) { + mapII = new HashMap(); + map.put(entrez, mapII); + } + mapII.put(alt, count); + } + return map; + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoCnaEvent.class, con, pstmt, rs); + } + } + + public static Map countSamplesWithCnaEvents(Collection eventIds, + int profileId) throws DaoException { + return countSamplesWithCnaEvents(StringUtils.join(eventIds, ","), profileId); + } + + public static Map countSamplesWithCnaEvents(String concatEventIds, + int profileId) throws DaoException { + if (concatEventIds.isEmpty()) { + return Collections.emptyMap(); + } + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoCnaEvent.class); + String sql = null; + switch(DBProperties.getDBVendor()){ + case mssql: + sql = "SELECT [CNA_EVENT_ID], count(*) FROM sample_cna_event" + + " WHERE [GENETIC_PROFILE_ID]=" + profileId + + " and [CNA_EVENT_ID] IN (" + + concatEventIds + + ") GROUP BY [CNA_EVENT_ID]"; + break; + default: + sql = "SELECT `CNA_EVENT_ID`, count(*) FROM sample_cna_event" + + " WHERE `GENETIC_PROFILE_ID`=" + profileId + + " and `CNA_EVENT_ID` IN (" + + concatEventIds + + ") GROUP BY `CNA_EVENT_ID`"; + break; + }//JK-UPDATED + + + pstmt = con.prepareStatement(sql); + + Map map = new HashMap(); + rs = pstmt.executeQuery(); + while (rs.next()) { + map.put(rs.getLong(1), rs.getInt(2)); + } + return map; + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoCnaEvent.class, con, pstmt, rs); + } + } + + public static Set getAlteredGenes(String concatEventIds) + throws DaoException { + if (concatEventIds.isEmpty()) { + return Collections.emptySet(); + } + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoCnaEvent.class); + String sql = "SELECT DISTINCT ENTREZ_GENE_ID FROM cna_event " + + "WHERE CNA_EVENT_ID in (" + + concatEventIds + + ")"; + pstmt = con.prepareStatement(sql); + + Set set = new HashSet(); + rs = pstmt.executeQuery(); + while (rs.next()) { + set.add(rs.getLong(1)); + } + return set; + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoCnaEvent.class, con, pstmt, rs); + } + } +} diff --git a/DaoCoexpression.java b/DaoCoexpression.java new file mode 100644 index 0000000..646a37d --- /dev/null +++ b/DaoCoexpression.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS + * FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder + * is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no + * obligations to provide maintenance, support, updates, enhancements or + * modifications. In no event shall Memorial Sloan-Kettering Cancer Center be + * liable to any party for direct, indirect, special, incidental or + * consequential damages, including lost profits, arising out of the use of this + * software and its documentation, even if Memorial Sloan-Kettering Cancer + * Center has been advised of the possibility of such damage. + */ + +/* + * This file is part of cBioPortal. + * + * cBioPortal is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . +*/ + +package org.mskcc.cbio.portal.dao; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; + +import org.apache.commons.lang.StringUtils; +import org.mskcc.cbio.portal.model.Coexpression; + +/** + * + * @author jgao + */ +public class DaoCoexpression { + public static int addCoexpression(Coexpression coexpression) throws DaoException { + if (!MySQLbulkLoader.isBulkLoad()) {//JK-FUTURE-TODO + throw new DaoException("You have to turn on MySQLbulkLoader in order to insert Coexpression data"); + } else { + // use this code if bulk loading + // write to the temp file maintained by the MySQLbulkLoader + MySQLbulkLoader.getMySQLbulkLoader("coexpression").insertRecord( + Long.toString(coexpression.getGene1()), + Long.toString(coexpression.getGene2()), + Integer.toString(coexpression.getProfileId()), + Double.toString(coexpression.getPearson()), + Double.toString(coexpression.getSpearman())); + return 1; + } + } + + public static ArrayList getCoexpression(Collection queryGenes, int geneticProfileId) throws DaoException { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoCoexpression.class); + ArrayList result = new ArrayList(); + pstmt = con.prepareStatement("SELECT * FROM coexpression WHERE " + + "GENETIC_PROFILE_ID='" + geneticProfileId + "' AND " + + "(GENE_1 in ('" + StringUtils.join(queryGenes, "','") + "')" + " OR " + + " GENE_2 in ('" + StringUtils.join(queryGenes, "','") + "'));"); + rs = pstmt.executeQuery(); + while (rs.next()) { + int gene1Id = Integer.parseInt(rs.getString("GENE_1")); + int gene2Id = Integer.parseInt(rs.getString("GENE_2")); + //int geneticProfileId = Integer.parseInt(rs.getString("GENETIC_PROFILE_ID")); + float pearson = Float.parseFloat(rs.getString("PEARSON")); + float spearman = Float.parseFloat(rs.getString("SPEARMAN")); + result.add(new Coexpression(gene1Id, gene2Id, geneticProfileId, pearson, spearman)); + } + return result; + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoCoexpression.class, con, pstmt, rs); + } + } + +} diff --git a/DaoCopyNumberSegment.java b/DaoCopyNumberSegment.java new file mode 100644 index 0000000..9401b8e --- /dev/null +++ b/DaoCopyNumberSegment.java @@ -0,0 +1,289 @@ +/* + * Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS + * FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder + * is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no + * obligations to provide maintenance, support, updates, enhancements or + * modifications. In no event shall Memorial Sloan-Kettering Cancer Center be + * liable to any party for direct, indirect, special, incidental or + * consequential damages, including lost profits, arising out of the use of this + * software and its documentation, even if Memorial Sloan-Kettering Cancer + * Center has been advised of the possibility of such damage. + */ + +/* + * This file is part of cBioPortal. + * + * cBioPortal is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . +*/ + +package org.mskcc.cbio.portal.dao; + +import org.mskcc.cbio.portal.model.*; + +import edu.jhu.u01.DBProperties; + +import org.apache.commons.lang.StringUtils; + +import java.sql.*; +import java.util.*; + +/** + * + * @author jgao + */ +public final class DaoCopyNumberSegment { + private DaoCopyNumberSegment() {} + + public static int addCopyNumberSegment(CopyNumberSegment seg) throws DaoException { + if (!MySQLbulkLoader.isBulkLoad()) { + throw new DaoException("You have to turn on MySQLbulkLoader in order to insert mutations"); + } else { + MySQLbulkLoader.getMySQLbulkLoader("copy_number_seg").insertRecord( + Long.toString(seg.getSegId()), + Integer.toString(seg.getCancerStudyId()), + Integer.toString(seg.getSampleId()), + seg.getChr(), + Long.toString(seg.getStart()), + Long.toString(seg.getEnd()), + Integer.toString(seg.getNumProbes()), + Double.toString(seg.getSegMean()) + ); + return 1; + } + } + + public static long getLargestId() throws DaoException { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoMutation.class); + pstmt = con.prepareStatement + ("SELECT MAX(SEG_ID) FROM copy_number_seg");//JK-UPDATED + rs = pstmt.executeQuery(); + return rs.next() ? rs.getLong(1) : 0; + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoMutation.class, con, pstmt, rs); + } + } + + public static List getSegmentForASample( + int sampleId, int cancerStudyId) throws DaoException { + return getSegmentForSamples(Collections.singleton(sampleId),cancerStudyId); + } + + public static List getSegmentForSamples( + Collection sampleIds, int cancerStudyId) throws DaoException { + if (sampleIds.isEmpty()) { + return Collections.emptyList(); + } + String concatSampleIds = "('"+StringUtils.join(sampleIds, "','")+"')"; + + List segs = new ArrayList(); + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoCopyNumberSegment.class); + pstmt = con.prepareStatement + ("SELECT * FROM copy_number_seg" + + " WHERE SAMPLE_ID IN "+ concatSampleIds + + " AND CANCER_STUDY_ID="+cancerStudyId);//JK-UPDATED + rs = pstmt.executeQuery(); + while (rs.next()) { + CopyNumberSegment seg = new CopyNumberSegment( + rs.getInt("CANCER_STUDY_ID"), + rs.getInt("SAMPLE_ID"), + rs.getString("CHR"), + rs.getLong("START"), + rs.getLong("END"), + rs.getInt("NUM_PROBES"), + rs.getDouble("SEGMENT_MEAN")); + seg.setSegId(rs.getLong("SEG_ID")); + segs.add(seg); + } + return segs; + } catch (NullPointerException e) { + throw new DaoException(e); + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoCopyNumberSegment.class, con, pstmt, rs); + } + } + + public static double getCopyNumberActeredFraction(int sampleId, + int cancerStudyId, double cutoff) throws DaoException { + Double d = getCopyNumberActeredFraction(Collections.singleton(sampleId), cancerStudyId, cutoff) + .get(sampleId); + return d==null ? Double.NaN : d; + } + + public static Map getCopyNumberActeredFraction(Collection sampleIds, + int cancerStudyId, double cutoff) throws DaoException { + Map alteredLength = getCopyNumberAlteredLength(sampleIds, cancerStudyId, cutoff); + Map measuredLength = getCopyNumberAlteredLength(sampleIds, cancerStudyId, 0); + Map fraction = new HashMap(alteredLength.size()); + for (Integer sampleId : sampleIds) { + Long ml = measuredLength.get(sampleId); + if (ml==null || ml==0) { + continue; + } + Long al = alteredLength.get(sampleId); + if (al==null) { + al = (long) 0; + } + fraction.put(sampleId, 1.0*al/ml); + } + return fraction; + } + + private static Map getCopyNumberAlteredLength(Collection sampleIds, + int cancerStudyId, double cutoff) throws DaoException { + Map map = new HashMap(); + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + String sql; + try { + con = JdbcUtil.getDbConnection(DaoCopyNumberSegment.class); + switch(DBProperties.getDBVendor()){ + case mssql://JK-FUTURE-TODO + if (cutoff>0) { + sql = "SELECT SAMPLE_ID, SUM([END]-[START])" + + " FROM copy_number_seg" + + " WHERE CANCER_STUDY_ID="+cancerStudyId + + " AND ABS(SEGMENT_MEAN)>=" + cutoff + + " AND SAMPLE_ID IN ('" + StringUtils.join(sampleIds,"','") +"')" + + " GROUP BY SAMPLE_ID"; + } else { + sql = "SELECT SAMPLE_ID, SUM([END]-[START])" + + " FROM copy_number_seg" + + " WHERE CANCER_STUDY_ID="+cancerStudyId + + " AND SAMPLE_ID IN ('" + StringUtils.join(sampleIds,"','") +"')" + + " GROUP BY SAMPLE_ID"; + } + break; + default: + if (cutoff>0) { + sql = "SELECT `SAMPLE_ID`, SUM(`END`-`START`)" + + " FROM `copy_number_seg`" + + " WHERE `CANCER_STUDY_ID`="+cancerStudyId + + " AND ABS(`SEGMENT_MEAN`)>=" + cutoff + + " AND `SAMPLE_ID` IN ('" + StringUtils.join(sampleIds,"','") +"')" + + " GROUP BY `SAMPLE_ID`"; + } else { + sql = "SELECT `SAMPLE_ID`, SUM(`END`-`START`)" + + " FROM `copy_number_seg`" + + " WHERE `CANCER_STUDY_ID`="+cancerStudyId + + " AND `SAMPLE_ID` IN ('" + StringUtils.join(sampleIds,"','") +"')" + + " GROUP BY `SAMPLE_ID`"; + } + break; + }//JK-UPDATED + + + pstmt = con.prepareStatement(sql); + rs = pstmt.executeQuery(); + while (rs.next()) { + map.put(rs.getInt(1), rs.getLong(2)); + } + + return map; + } catch (NullPointerException e) { + throw new DaoException(e); + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoCopyNumberSegment.class, con, pstmt, rs); + } + } + + /** + * + * @param cancerStudyId + * @return true if segment data exist for the cancer study + * @throws DaoException + */ + public static boolean segmentDataExistForCancerStudy(int cancerStudyId) throws DaoException { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoCopyNumberSegment.class); + switch(DBProperties.getDBVendor()){ + case mssql: + //pstmt = con.prepareStatement("SELECT CAST (CASE WHEN COUNT (*) = 1 THEN 1 ELSE 0 END AS BIT) FROM (" + // + "SELECT TOP 1 1 AS B FROM copy_number_seg WHERE CANCER_STUDY_ID=?) as A"); + pstmt = con.prepareStatement("SELECT TOP 1 1 AS B FROM copy_number_seg WHERE CANCER_STUDY_ID=?"); + break; + default: + pstmt = con.prepareStatement("SELECT EXISTS(SELECT 1 FROM `copy_number_seg`" + + " WHERE `CANCER_STUDY_ID`=?)"); + break; + }//JK-UPDATED + + pstmt.setInt(1, cancerStudyId); + rs = pstmt.executeQuery(); + return rs.next() && rs.getInt(1)==1; + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoCopyNumberSegment.class, con, pstmt, rs); + } + } + + /** + * + * @param cancerStudyId + * @param sampleId + * @return true if segment data exist for the case + * @throws DaoException + */ + public static boolean segmentDataExistForSample(int cancerStudyId, int sampleId) throws DaoException { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoCopyNumberSegment.class); + switch(DBProperties.getDBVendor()){ + case mssql: + //pstmt = con.prepareStatement("SELECT CAST (CASE WHEN COUNT (*) = 1 THEN 1 ELSE 0 END AS BIT) FROM (" + // + "SELECT TOP 1 1 AS B FROM copy_number_seg WHERE CANCER_STUDY_ID=? AND SAMPLE_ID=?) AS A"); + pstmt = con.prepareStatement("SELECT TOP 1 1 AS B FROM copy_number_seg WHERE CANCER_STUDY_ID=? AND SAMPLE_ID=?"); + + break; + default: + pstmt = con.prepareStatement("SELECT EXISTS(SELECT 1 FROM `copy_number_seg`" + + " WHERE `CANCER_STUDY_ID`=? AND `SAMPLE_ID`=?)"); + break; + }//JK-UPDATED + pstmt.setInt(1, cancerStudyId); + pstmt.setInt(2, sampleId); + rs = pstmt.executeQuery(); + return rs.next() && rs.getInt(1)==1; + } catch (NullPointerException e) { + throw new DaoException(e); + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoCopyNumberSegment.class, con, pstmt, rs); + } + } +} diff --git a/DaoCopyNumberSegmentFile.java b/DaoCopyNumberSegmentFile.java new file mode 100644 index 0000000..b84859b --- /dev/null +++ b/DaoCopyNumberSegmentFile.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS + * FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder + * is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no + * obligations to provide maintenance, support, updates, enhancements or + * modifications. In no event shall Memorial Sloan-Kettering Cancer Center be + * liable to any party for direct, indirect, special, incidental or + * consequential damages, including lost profits, arising out of the use of this + * software and its documentation, even if Memorial Sloan-Kettering Cancer + * Center has been advised of the possibility of such damage. + */ + +/* + * This file is part of cBioPortal. + * + * cBioPortal is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . +*/ + +package org.mskcc.cbio.portal.dao; + +import org.mskcc.cbio.portal.model.CopyNumberSegmentFile; + +import edu.jhu.u01.DBProperties; + +import org.apache.commons.lang.StringUtils; + +import java.sql.*; +import java.util.*; + +public final class DaoCopyNumberSegmentFile { + private DaoCopyNumberSegmentFile() {} + + public static int addCopyNumberSegmentFile(CopyNumberSegmentFile copySegFile) throws DaoException + { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoCopyNumberSegmentFile.class); + switch(DBProperties.getDBVendor()){ + case mssql: + pstmt = con.prepareStatement + ("INSERT INTO copy_number_seg_file ([CANCER_STUDY_ID], [REFERENCE_GENOME_ID], [DESCRIPTION],[FILENAME])" + + " VALUES (?,?,?,?)", Statement.RETURN_GENERATED_KEYS); + break; + default: + pstmt = con.prepareStatement + ("INSERT INTO copy_number_seg_file (`CANCER_STUDY_ID`, `REFERENCE_GENOME_ID`, `DESCRIPTION`,`FILENAME`)" + + " VALUES (?,?,?,?)", Statement.RETURN_GENERATED_KEYS); + break; + }//JK-UPDATED + + + pstmt.setInt(1, copySegFile.cancerStudyId); + pstmt.setString(2, copySegFile.referenceGenomeId.toString()); + pstmt.setString(3, copySegFile.description); + pstmt.setString(4, copySegFile.filename); + pstmt.executeUpdate(); + rs = pstmt.getGeneratedKeys(); + if (rs.next()) { + return rs.getInt(1); + } + return -1; + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoCopyNumberSegment.class, con, pstmt, rs); + } + } + + public static CopyNumberSegmentFile getCopyNumberSegmentFile(int cancerStudyId) throws DaoException + { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoCopyNumberSegmentFile.class); + pstmt = con.prepareStatement("SELECT * from copy_number_seg_file WHERE CANCER_STUDY_ID = ?");//JK-UPDATED + pstmt.setInt(1, cancerStudyId); + rs = pstmt.executeQuery(); + if (rs.next()) { + CopyNumberSegmentFile cnsf = new CopyNumberSegmentFile(); + cnsf.segFileId = rs.getInt("SEG_FILE_ID"); + cnsf.cancerStudyId = cancerStudyId; + cnsf.referenceGenomeId = CopyNumberSegmentFile.ReferenceGenomeId.valueOf(rs.getString("REFERENCE_GENOME_ID")); + cnsf.description = rs.getString("DESCRIPTION"); + cnsf.filename = rs.getString("FILENAME"); + return cnsf; + } + return null; + } + catch(SQLException e) { + throw new DaoException(e); + } + finally { + JdbcUtil.closeAll(DaoCopyNumberSegmentFile.class, con, pstmt, rs); + } + } + + public static void deleteAllRecords() throws DaoException + { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoCopyNumberSegmentFile.class); + pstmt = con.prepareStatement("TRUNCATE TABLE copy_number_seg_file"); + pstmt.executeUpdate(); + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoCopyNumberSegmentFile.class, con, pstmt, rs); + } + } +} diff --git a/DaoCosmicData.java b/DaoCosmicData.java new file mode 100644 index 0000000..967ffe4 --- /dev/null +++ b/DaoCosmicData.java @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS + * FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder + * is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no + * obligations to provide maintenance, support, updates, enhancements or + * modifications. In no event shall Memorial Sloan-Kettering Cancer Center be + * liable to any party for direct, indirect, special, incidental or + * consequential damages, including lost profits, arising out of the use of this + * software and its documentation, even if Memorial Sloan-Kettering Cancer + * Center has been advised of the possibility of such damage. + */ + +/* + * This file is part of cBioPortal. + * + * cBioPortal is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . +*/ + +package org.mskcc.cbio.portal.dao; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.apache.commons.lang.StringUtils; +import org.mskcc.cbio.portal.model.CosmicMutationFrequency; +import org.mskcc.cbio.portal.model.ExtendedMutation; + +/** + * + * @author jgao + */ +public class DaoCosmicData { + public static int addCosmic(CosmicMutationFrequency cosmic) throws DaoException { + if (!MySQLbulkLoader.isBulkLoad()) {//JK-FUTURE-TODO + throw new DaoException("You have to turn on MySQLbulkLoader in order to insert mutations"); + } else { + + // use this code if bulk loading + // write to the temp file maintained by the MySQLbulkLoader + MySQLbulkLoader.getMySQLbulkLoader("cosmic_mutation").insertRecord( + cosmic.getId(), + cosmic.getChr(), + Long.toString(cosmic.getStartPosition()), + cosmic.getReferenceAllele(), + cosmic.getTumorSeqAllele(), + cosmic.getStrand(), + cosmic.getCds(), + Long.toString(cosmic.getEntrezGeneId()), + cosmic.getAminoAcidChange(), + Integer.toString(cosmic.getFrequency()), + cosmic.getKeyword()); + + return 1; + } + } + + /** + * + * @param mutations + * @return Map of event id to map of aa change to count + * @throws DaoException + */ + public static Map> getCosmicForMutationEvents( + List mutations) throws DaoException { + Set mutKeywords = new HashSet(); + for (ExtendedMutation mut : mutations) { + mutKeywords.add(mut.getKeyword()); + } + + Map> map = + DaoCosmicData.getCosmicDataByKeyword(mutKeywords); + Map> ret + = new HashMap>(map.size()); + for (ExtendedMutation mut : mutations) { + String keyword = mut.getKeyword(); + Set cmfs = filterTruncatingCosmicByPosition(mut, map.get(keyword)); + + if (cmfs==null || cmfs.isEmpty()) { + continue; + } + + ret.put(mut.getMutationEventId(), cmfs); + } + return ret; + } + + private static Set filterTruncatingCosmicByPosition( + ExtendedMutation mut, Set cmfs) { + if (mut.getKeyword()==null || !mut.getKeyword().endsWith("truncating") || cmfs==null) { + return cmfs; + } + + Set ret = new HashSet(); + Pattern p = Pattern.compile("[0-9]+"); + int mutPos = mut.getOncotatorProteinPosStart(); + for (CosmicMutationFrequency cmf : cmfs) { + String aa = cmf.getAminoAcidChange(); + Matcher m = p.matcher(aa); + if (m.find()) { + int cmfPos = Integer.parseInt(m.group()); + if (mutPos==cmfPos) { + ret.add(cmf); + } + } + } + return ret; + } + + /** + * + * @param keywordS + * @return Map> + * @throws DaoException + */ + public static Map> getCosmicDataByKeyword(Collection keywordS) throws DaoException { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoCosmicData.class); + pstmt = con.prepareStatement("SELECT * FROM cosmic_mutation " + + " WHERE KEYWORD in ('" + StringUtils.join(keywordS, "','") + "')"); + rs = pstmt.executeQuery(); + Map> ret = new HashMap>(); + while (rs.next()) { + CosmicMutationFrequency cmf = extractCosmic(rs); + Set cmfs = ret.get(cmf.getKeyword()); + if (cmfs==null) { + cmfs = new HashSet(); + ret.put(cmf.getKeyword(), cmfs); + } + cmfs.add(cmf); + } + return ret; + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoCosmicData.class, con, pstmt, rs); + } + } + + private static CosmicMutationFrequency extractCosmic(ResultSet rs) throws SQLException { + String id = rs.getString("COSMIC_MUTATION_ID"); + long entrez = rs.getLong("ENTREZ_GENE_ID"); + String aa = rs.getString("PROTEIN_CHANGE"); + String keyword = rs.getString("KEYWORD"); + int count = rs.getInt("COUNT"); + return new CosmicMutationFrequency(id, entrez, aa, keyword, count); + } + + public static void deleteAllRecords() throws DaoException { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoCosmicData.class); + pstmt = con.prepareStatement("TRUNCATE TABLE cosmic_mutation"); + pstmt.executeUpdate(); + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoCosmicData.class, con, pstmt, rs); + } + } +} diff --git a/DaoDrug.java b/DaoDrug.java new file mode 100644 index 0000000..3652b25 --- /dev/null +++ b/DaoDrug.java @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS + * FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder + * is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no + * obligations to provide maintenance, support, updates, enhancements or + * modifications. In no event shall Memorial Sloan-Kettering Cancer Center be + * liable to any party for direct, indirect, special, incidental or + * consequential damages, including lost profits, arising out of the use of this + * software and its documentation, even if Memorial Sloan-Kettering Cancer + * Center has been advised of the possibility of such damage. + */ + +/* + * This file is part of cBioPortal. + * + * cBioPortal is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . +*/ + +package org.mskcc.cbio.portal.dao; + + +import java.io.IOException; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collection; +import org.apache.commons.lang.StringUtils; +import org.mskcc.cbio.portal.model.Drug; + +import edu.jhu.u01.DBProperties; + +/** + * Data access object for Drug table + */ +public class DaoDrug { + private static DaoDrug daoDrug; + + private DaoDrug() { + } + + /** + * Gets Global Singleton Instance. + * + * @return DaoGeneOptimized Singleton. + * @throws DaoException Database Error. + */ + public static DaoDrug getInstance() throws DaoException { + if (daoDrug == null) { + daoDrug = new DaoDrug(); + } + + return daoDrug; + } + + public int addDrug(Drug drug) throws DaoException { + if (MySQLbulkLoader.isBulkLoad()) {//JK-FUTURE-TODO + MySQLbulkLoader.getMySQLbulkLoader("drug").insertRecord( + drug.getId(), + drug.getResource(), + drug.getName(), + drug.getSynonyms(), + drug.getDescription(), + drug.getExternalReference(), + drug.getATCCode(), + drug.isApprovedFDA() ? "1" : "0", + drug.isCancerDrug() ? "1" : "0", + drug.isNutraceuitical() ? "1" : "0", + drug.getNumberOfClinicalTrials().toString() + ); + return 1; + } + + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + Drug existingDrug = getDrug(drug.getId()); + if (existingDrug == null) { + con = JdbcUtil.getDbConnection(DaoDrug.class); + switch(DBProperties.getDBVendor()){ + case mssql: + pstmt = con.prepareStatement( + "INSERT INTO drug " + + "([DRUG_ID], [DRUG_RESOURCE], [DRUG_NAME], " + + "[DRUG_SYNONYMS], [DRUG_DESCRIPTION], [DRUG_XREF], " + + "[DRUG_ATC_CODE], [DRUG_APPROVED], [DRUG_CANCERDRUG], " + + "[DRUG_NUTRACEUTICAL], [DRUG_NUMOFTRIALS]) " + + "VALUES (?,?,?,?,?,?,?,?,?,?,?)" + ); + break; + default: + pstmt = con.prepareStatement( + "INSERT INTO drug " + + "(`DRUG_ID`, `DRUG_RESOURCE`, `DRUG_NAME`, " + + "`DRUG_SYNONYMS`, `DRUG_DESCRIPTION`, `DRUG_XREF`, " + + "`DRUG_ATC_CODE`, `DRUG_APPROVED`, `DRUG_CANCERDRUG`, " + + "`DRUG_NUTRACEUTICAL`, `DRUG_NUMOFTRIALS`) " + + "VALUES (?,?,?,?,?,?,?,?,?,?,?)" + ); + break; + }//JK-UPDATED + + + pstmt.setString(1, drug.getId()); + pstmt.setString(2, drug.getResource()); + pstmt.setString(3, drug.getName()); + pstmt.setString(4, drug.getSynonyms()); + pstmt.setString(5, drug.getDescription()); + pstmt.setString(6, drug.getExternalReference()); + pstmt.setString(7, drug.getATCCode()); + pstmt.setInt(8, drug.isApprovedFDA() ? 1 : 0); + pstmt.setInt(9, drug.isCancerDrug() ? 1 : 0); + pstmt.setInt(10, drug.isNutraceuitical() ? 1 : 0); + pstmt.setInt(11, drug.getNumberOfClinicalTrials()); + + return pstmt.executeUpdate(); + } else { + return 0; + } + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoDrug.class, con, pstmt, rs); + } + } + + public Drug getDrug(String drugID) throws DaoException { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoDrug.class); + pstmt = con.prepareStatement + ("SELECT * FROM drug WHERE DRUG_ID = ?"); + pstmt.setString(1, drugID); + rs = pstmt.executeQuery(); + if (rs.next()) { + return extractDrug(rs); + } else { + return null; + } + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoDrug.class, con, pstmt, rs); + } + } + + public ArrayList getDrugs(Collection drugIds) throws DaoException { + ArrayList drugList = new ArrayList(); + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoDrug.class); + pstmt = con.prepareStatement + ("SELECT * FROM drug WHERE DRUG_ID in ('" + + StringUtils.join(drugIds, "','")+"')"); + rs = pstmt.executeQuery(); + while (rs.next()) { + drugList.add(extractDrug(rs)); + } + return drugList; + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoDrug.class, con, pstmt, rs); + } + } + + public ArrayList getAllDrugs() throws DaoException { + ArrayList drugList = new ArrayList(); + + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoDrug.class); + pstmt = con.prepareStatement + ("SELECT * FROM drug"); + rs = pstmt.executeQuery(); + while (rs.next()) { + drugList.add(extractDrug(rs)); + } + return drugList; + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoDrug.class, con, pstmt, rs); + } + } + + private Drug extractDrug(ResultSet rs) throws SQLException { + Drug drug = new Drug(); + drug.setId(rs.getString("DRUG_ID")); + drug.setResource(rs.getString("DRUG_RESOURCE")); + drug.setName(rs.getString("DRUG_NAME")); + drug.setSynonyms(rs.getString("DRUG_SYNONYMS")); + drug.setDescription(rs.getString("DRUG_DESCRIPTION")); + drug.setExternalReference(rs.getString("DRUG_XREF")); + drug.setATCCode(rs.getString("DRUG_ATC_CODE")); + drug.setApprovedFDA(rs.getInt("DRUG_APPROVED") == 1); + drug.setCancerDrug(rs.getInt("DRUG_CANCERDRUG") == 1); + drug.setNutraceuitical(rs.getInt("DRUG_NUTRACEUTICAL") == 1); + drug.setNumberOfClinicalTrials(rs.getInt("DRUG_NUMOFTRIALS")); + return drug; + } + + public int getCount() throws DaoException { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + + try { + con = JdbcUtil.getDbConnection(DaoDrug.class); + pstmt = con.prepareStatement + ("SELECT COUNT(*) FROM drug"); + rs = pstmt.executeQuery(); + if (rs.next()) { + return rs.getInt(1); + } + return 0; + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoDrug.class, con, pstmt, rs); + } + } + + public void deleteAllRecords() throws DaoException { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoDrug.class); + JdbcUtil.disableForeignKeyCheck(con); + pstmt = con.prepareStatement("TRUNCATE TABLE drug"); + pstmt.executeUpdate(); + JdbcUtil.enableForeignKeyCheck(con); + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoDrug.class, con, pstmt, rs); + } + } +} + diff --git a/DaoDrugInteraction.java b/DaoDrugInteraction.java new file mode 100644 index 0000000..a60e385 --- /dev/null +++ b/DaoDrugInteraction.java @@ -0,0 +1,423 @@ +/* + * Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS + * FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder + * is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no + * obligations to provide maintenance, support, updates, enhancements or + * modifications. In no event shall Memorial Sloan-Kettering Cancer Center be + * liable to any party for direct, indirect, special, incidental or + * consequential damages, including lost profits, arising out of the use of this + * software and its documentation, even if Memorial Sloan-Kettering Cancer + * Center has been advised of the possibility of such damage. + */ + +/* + * This file is part of cBioPortal. + * + * cBioPortal is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . +*/ + +package org.mskcc.cbio.portal.dao; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.mskcc.cbio.portal.model.CanonicalGene; +import org.mskcc.cbio.portal.model.Drug; +import org.mskcc.cbio.portal.model.DrugInteraction; + +import edu.jhu.u01.DBProperties; + +public class DaoDrugInteraction { + private static DaoDrugInteraction daoDrugInteraction; + private static final String NA = "NA"; + + private static final Log log = LogFactory.getLog(DaoDrugInteraction.class); + + private DaoDrugInteraction() { + } + + public static DaoDrugInteraction getInstance() throws DaoException { + if (daoDrugInteraction == null) { + daoDrugInteraction = new DaoDrugInteraction(); + } + + return daoDrugInteraction; + } + + public int addDrugInteraction(Drug drug, + CanonicalGene targetGene, + String interactionType, + String dataSource, + String experimentTypes, + String pmids) throws DaoException { + if (interactionType == null) { + throw new IllegalArgumentException ("Drug interaction type cannot be null"); + } + if (dataSource == null) { + throw new IllegalArgumentException ("Data Source cannot be null"); + } + if (experimentTypes == null) { + experimentTypes = NA; + } + if (pmids == null) { + pmids = NA; + } + + if (MySQLbulkLoader.isBulkLoad()) {//JK-FUTURE-TODO + MySQLbulkLoader.getMySQLbulkLoader("drug_interaction").insertRecord( + drug.getId(), + Long.toString(targetGene.getEntrezGeneId()), + interactionType, + dataSource, + experimentTypes, + pmids); + + return 1; + } + + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + + try { + con = JdbcUtil.getDbConnection(DaoDrugInteraction.class); + switch(DBProperties.getDBVendor()){ + case mssql: + pstmt = con.prepareStatement + ("INSERT INTO drug_interaction ([DRUG],[TARGET], [INTERACTION_TYPE]," + + "[DATA_SOURCE], [EXPERIMENT_TYPES], [PMIDS])" + + "VALUES (?,?,?,?,?,?)"); + + break; + default: + pstmt = con.prepareStatement + ("INSERT INTO drug_interaction (`DRUG`,`TARGET`, `INTERACTION_TYPE`," + + "`DATA_SOURCE`, `EXPERIMENT_TYPES`, `PMIDS`)" + + "VALUES (?,?,?,?,?,?)"); + + break; + }//JK-UPDATED + + + pstmt.setString(1, drug.getId()); + pstmt.setLong(2, targetGene.getEntrezGeneId()); + pstmt.setString(3, interactionType); + pstmt.setString(4, dataSource); + pstmt.setString(5, experimentTypes); + pstmt.setString(6, pmids); + + return pstmt.executeUpdate(); + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoDrugInteraction.class, con, pstmt, rs); + } + } + + public ArrayList getInteractions(long entrezGeneId) throws DaoException { + return getInteractions(Collections.singleton(entrezGeneId)); + } + + public ArrayList getInteractions(CanonicalGene gene) throws DaoException { + return getInteractions(Collections.singleton(gene)); + } + + public ArrayList getInteractions(Collection genes) throws DaoException { + ArrayList interactionList = new ArrayList(); + if (genes.isEmpty()) + return interactionList; + + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + + try { + con = JdbcUtil.getDbConnection(DaoDrugInteraction.class); + Set entrezGeneIds = new HashSet(); + + for (Object gene : genes) { + if(gene instanceof CanonicalGene) + entrezGeneIds.add(((CanonicalGene) gene).getEntrezGeneId()); + else if(gene instanceof Long) + entrezGeneIds.add((Long) gene); + else + entrezGeneIds.add(Long.parseLong(gene.toString())); + } + + String idStr = "(" + StringUtils.join(entrezGeneIds, ",") + ")"; + + pstmt = con.prepareStatement("SELECT * FROM drug_interaction WHERE TARGET IN " + idStr); + rs = pstmt.executeQuery(); + + while (rs.next()) { + DrugInteraction interaction = extractInteraction(rs); + interactionList.add(interaction); + } + + return interactionList; + + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoDrugInteraction.class, con, pstmt, rs); + } + } + + public Map> getDrugs(Set entrezGeneIds, boolean fdaOnly, boolean cancerSpecific) throws DaoException { + if (entrezGeneIds.isEmpty()) { + return Collections.emptyMap(); + } + + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + + try { + con = JdbcUtil.getDbConnection(DaoDrugInteraction.class); + + String sql; + if (fdaOnly || cancerSpecific) { + sql = "SELECT DRUG,TARGET FROM drug_interaction, drug" + + " WHERE TARGET IN (" + StringUtils.join(entrezGeneIds, ",") + ")" + + " AND drug_interaction.DRUG=drug.DRUG_ID"; + if (fdaOnly) { + sql += " AND DRUG_APPROVED=1"; + } + + if (cancerSpecific) { + sql += " AND DRUG_CANCERDRUG=1"; + } + } else { + sql = "SELECT DRUG,TARGET FROM drug_interaction" + + " WHERE TARGET IN (" + + StringUtils.join(entrezGeneIds, ",") + ")"; + } + + pstmt = con.prepareStatement(sql); + rs = pstmt.executeQuery(); + + Map> map = new HashMap>(); + while (rs.next()) { + long entrez = rs.getLong("TARGET"); + List drugs = map.get(entrez); + if (drugs==null) { + drugs = new ArrayList(); + map.put(entrez, drugs); + } + + drugs.add(rs.getString("DRUG")); + } + + return map; + + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoDrugInteraction.class, con, pstmt, rs); + } + } + + public ArrayList getTargets(Drug drug) throws DaoException { + return getTargets(Collections.singleton(drug)); + } + + public ArrayList getTargets(Collection drugs) throws DaoException { + ArrayList interactionList = new ArrayList(); + if (drugs.isEmpty()) + return interactionList; + + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + + try { + con = JdbcUtil.getDbConnection(DaoDrugInteraction.class); + Set drugIDs = new HashSet(); + for (Drug drug : drugs) + drugIDs.add("'" + drug.getId() + "'"); + + String idStr = "(" + StringUtils.join(drugIDs, ",") + ")"; + + pstmt = con.prepareStatement("SELECT * FROM drug_interaction WHERE DRUG IN " + idStr); + rs = pstmt.executeQuery(); + + while (rs.next()) { + DrugInteraction interaction = extractInteraction(rs); + interactionList.add(interaction); + } + + return interactionList; + + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoDrugInteraction.class, con, pstmt, rs); + } + } + + + public ArrayList getAllInteractions() throws DaoException { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + ArrayList interactionList = new ArrayList (); + + try { + con = JdbcUtil.getDbConnection(DaoDrugInteraction.class); + pstmt = con.prepareStatement + ("SELECT * FROM drug_interaction"); + rs = pstmt.executeQuery(); + + while (rs.next()) { + DrugInteraction interaction = extractInteraction(rs); + interactionList.add(interaction); + } + + return interactionList; + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoDrugInteraction.class, con, pstmt, rs); + } + } + + private DrugInteraction extractInteraction(ResultSet rs) throws SQLException { + DrugInteraction interaction = new DrugInteraction(); + interaction.setDrug(rs.getString("DRUG")); + interaction.setTargetGene(rs.getLong("TARGET")); + interaction.setInteractionType(rs.getString("INTERACTION_TYPE")); + interaction.setDataSource(rs.getString("DATA_SOURCE")); + interaction.setExperimentTypes(rs.getString("EXPERIMENT_TYPES")); + interaction.setPubMedIDs(rs.getString("PMIDS")); + return interaction; + } + + /** + * Gets the Number of Interaction Records in the Database. + * + * @return number of gene records. + */ + public int getCount() throws DaoException { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoDrugInteraction.class); + pstmt = con.prepareStatement + ("SELECT COUNT(*) FROM drug_interaction"); + rs = pstmt.executeQuery(); + if (rs.next()) { + return rs.getInt(1); + } + return 0; + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoDrugInteraction.class, con, pstmt, rs); + } + } + + public void deleteAllRecords() throws DaoException { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoDrugInteraction.class); + pstmt = con.prepareStatement("TRUNCATE TABLE drug_interaction"); + pstmt.executeUpdate(); + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoDrugInteraction.class, con, pstmt, rs); + } + } + + // Temporary way of handling cases such as akt inhibitor for pten loss + private static final String DRUG_TARGET_FILE = "/drug_target_annotation.txt"; + private static Map>> drugTargetAnnotation = null; // map > + + private static synchronized Map>> getDrugTargetAnnotation() { + if (drugTargetAnnotation==null) { + drugTargetAnnotation = new HashMap>>(); + try { + DaoGeneOptimized daoGeneOptimized = DaoGeneOptimized.getInstance(); + BufferedReader in = new BufferedReader( + new InputStreamReader(DaoDrugInteraction.class.getResourceAsStream(DRUG_TARGET_FILE))); + for (String line=in.readLine(); line!=null; line=in.readLine()) { + if (line.startsWith("#")) { + continue; + } + + String[] parts = line.split("\t"); + String[] genesOfEvents = parts[0].split(","); + String[] events = parts[1].split(","); + String[] targetGenes = parts[2].split(","); + Set targetEntrez = new HashSet(targetGenes.length); + for (String target : targetGenes) { + CanonicalGene gene = daoGeneOptimized.getGene(target); + if(gene == null) + log.warn("Could not find gene: " + target); + else + targetEntrez.add(gene.getEntrezGeneId()); + } + + for (String gene : genesOfEvents) { + long entrez = daoGeneOptimized.getGene(gene).getEntrezGeneId(); + Map> mapEventTargets = drugTargetAnnotation.get(entrez); + if (mapEventTargets==null) { + mapEventTargets = new HashMap>(); + drugTargetAnnotation.put(entrez, mapEventTargets); + } + + for (String event : events) { + mapEventTargets.put(event, targetEntrez); + } + } + } + in.close(); + } catch(Exception e) { + e.printStackTrace(); + } + } + + return drugTargetAnnotation; + } + + public Set getMoreTargets(long geneOfEvent, String event) { + Map> mapEventTargets = getDrugTargetAnnotation().get(geneOfEvent); + if (mapEventTargets==null) { + return Collections.emptySet(); + } + + Set set = mapEventTargets.get(event); + if (set==null) { + return Collections.emptySet(); + } + + return set; + } + // end of Temporary way of handling cases such as akt inhibitor for pten loss + +} diff --git a/DaoException.java b/DaoException.java new file mode 100644 index 0000000..c26c78a --- /dev/null +++ b/DaoException.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS + * FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder + * is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no + * obligations to provide maintenance, support, updates, enhancements or + * modifications. In no event shall Memorial Sloan-Kettering Cancer Center be + * liable to any party for direct, indirect, special, incidental or + * consequential damages, including lost profits, arising out of the use of this + * software and its documentation, even if Memorial Sloan-Kettering Cancer + * Center has been advised of the possibility of such damage. + */ + +/* + * This file is part of cBioPortal. + * + * cBioPortal is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . +*/ + +package org.mskcc.cbio.portal.dao; + +import org.mskcc.cbio.portal.util.GlobalProperties; + +/** + * Exception Occurred while reading/writing data to database. + * + * @author Ethan Cerami + */ +public class DaoException extends Exception { + private final String msg; + + /** + * Constructor. + * + * @param throwable Throwable Object containing root cause. + */ + public DaoException(Throwable throwable) { + super(throwable); + this.msg = throwable.getMessage(); + } + + /** + * Constructor. + * + * @param msg Error Message. + */ + public DaoException(String msg) { + super(); + this.msg = msg; + } + + /** + * Gets Error Message. + * + * @return Error Message String.I + */ + public String getMessage() { + String dbVersion = DaoInfo.getVersion(); + String portalDbVersion = GlobalProperties.getDbVersion(); + //TODO - this dbVersion message should not be concatenated here, but should be given to constructor in the relevant scenario. + if (dbVersion != null && !dbVersion.equals(portalDbVersion)) + return "Database Version: " + dbVersion + " Portal DB Version Expected: " + portalDbVersion + ". " + msg; + return msg; + } +} diff --git a/DaoGene.java b/DaoGene.java new file mode 100644 index 0000000..56a3b4d --- /dev/null +++ b/DaoGene.java @@ -0,0 +1,439 @@ +/* + * Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS + * FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder + * is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no + * obligations to provide maintenance, support, updates, enhancements or + * modifications. In no event shall Memorial Sloan-Kettering Cancer Center be + * liable to any party for direct, indirect, special, incidental or + * consequential damages, including lost profits, arising out of the use of this + * software and its documentation, even if Memorial Sloan-Kettering Cancer + * Center has been advised of the possibility of such damage. + */ + +/* + * This file is part of cBioPortal. + * + * cBioPortal is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . +*/ + +package org.mskcc.cbio.portal.dao; + +import org.mskcc.cbio.portal.model.CanonicalGene; + +import edu.jhu.u01.DBProperties; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * Data Access Object to Gene Table. + * For faster access, consider using DaoGeneOptimized. + * + * @author Ethan Cerami. + */ +final class DaoGene { + + /** + * Private Constructor to enforce Singleton Pattern. + */ + private DaoGene() { + } + + private static int fakeEntrezId = 0; + private static synchronized int getNextFakeEntrezId() throws DaoException { + while (getGene(--fakeEntrezId)!=null); + return fakeEntrezId; + } + + public static synchronized int addGeneWithoutEntrezGeneId(CanonicalGene gene) throws DaoException { + CanonicalGene existingGene = getGene(gene.getHugoGeneSymbolAllCaps()); + gene.setEntrezGeneId(existingGene==null?getNextFakeEntrezId():existingGene.getEntrezGeneId()); + return addGene(gene); + } + + /** + * Adds a new Gene Record to the Database. + * + * @param gene Canonical Gene Object. + * @return number of records successfully added. + * @throws DaoException Database Error. + */ + public static int addGene(CanonicalGene gene) throws DaoException { + //because many tables depend on gene, we want to add gene directly to DB, and + //never through MySQLbulkLoader to avoid any Foreign key constraint violations: + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + int rows = 0; + CanonicalGene existingGene = getGene(gene.getEntrezGeneId()); + if (existingGene == null) { + con = JdbcUtil.getDbConnection(DaoGene.class); + switch(DBProperties.getDBVendor()){ + case mssql: + pstmt = con.prepareStatement + ("INSERT INTO gene ([ENTREZ_GENE_ID],[HUGO_GENE_SYMBOL],[TYPE],[CYTOBAND],[LENGTH]) " + + "VALUES (?,?,?,?,?)"); + break; + default: + pstmt = con.prepareStatement + ("INSERT INTO gene (`ENTREZ_GENE_ID`,`HUGO_GENE_SYMBOL`,`TYPE`,`CYTOBAND`,`LENGTH`) " + + "VALUES (?,?,?,?,?)"); + break; + }//JK-UPDATED + + + pstmt.setLong(1, gene.getEntrezGeneId()); + pstmt.setString(2, gene.getHugoGeneSymbolAllCaps()); + pstmt.setString(3, gene.getType()); + pstmt.setString(4, gene.getCytoband()); + pstmt.setInt(5, gene.getLength()); + rows += pstmt.executeUpdate(); + + } + + rows += addGeneAliases(gene); + + return rows; + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoGene.class, con, pstmt, rs); + } + } + + /** + * Add gene_alias records. + * @param gene Canonical Gene Object. + * @return number of records successfully added. + * @throws DaoException Database Error. + */ + public static int addGeneAliases(CanonicalGene gene) throws DaoException { + if (MySQLbulkLoader.isBulkLoad()) { + // write to the temp file maintained by the MySQLbulkLoader + Set aliases = gene.getAliases(); + for (String alias : aliases) { + MySQLbulkLoader.getMySQLbulkLoader("gene_alias").insertRecord( + Long.toString(gene.getEntrezGeneId()), + alias); + + } + // return 1 because normal insert will return 1 if no error occurs + return 1; + } + + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoGene.class); + Set aliases = gene.getAliases(); + Set existingAliases = getAliases(gene.getEntrezGeneId()); + int rows = 0; + for (String alias : aliases) { + if (!existingAliases.contains(alias)) { + pstmt = con.prepareStatement("INSERT INTO gene_alias " + + "([ENTREZ_GENE_ID],[GENE_ALIAS]) VALUES (?,?)");//JK-UPDATED + pstmt.setLong(1, gene.getEntrezGeneId()); + pstmt.setString(2, alias); + rows += pstmt.executeUpdate(); + } + } + + return rows; + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoGene.class, con, pstmt, rs); + } + } + + /** + * Gets the Gene with the Specified Entrez Gene ID. + * For faster access, consider using DaoGeneOptimized. + * + * @param entrezGeneId Entrez Gene ID. + * @return Canonical Gene Object. + * @throws DaoException Database Error. + */ + private static CanonicalGene getGene(long entrezGeneId) throws DaoException { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoGene.class); + pstmt = con.prepareStatement + ("SELECT * FROM gene WHERE ENTREZ_GENE_ID = ?"); + pstmt.setLong(1, entrezGeneId); + rs = pstmt.executeQuery(); + if (rs.next()) { + return extractGene(rs); + } else { + return null; + } + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoGene.class, con, pstmt, rs); + } + } + + /** + * Gets aliases for all genes. + * @return map from entrez gene id to a set of aliases. + * @throws DaoException Database Error. + */ + private static Set getAliases(long entrezGeneId) throws DaoException { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoGene.class); + pstmt = con.prepareStatement + ("SELECT * FROM gene_alias WHERE ENTREZ_GENE_ID = ?"); + pstmt.setLong(1, entrezGeneId); + rs = pstmt.executeQuery(); + Set aliases = new HashSet(); + while (rs.next()) { + aliases.add(rs.getString("GENE_ALIAS")); + } + return aliases; + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoGene.class, con, pstmt, rs); + } + } + + private static Map> getAllAliases() throws DaoException { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoGene.class); + pstmt = con.prepareStatement + ("SELECT * FROM gene_alias"); + rs = pstmt.executeQuery(); + Map> map = new HashMap>(); + while (rs.next()) { + Long entrez = rs.getLong("ENTREZ_GENE_ID"); + Set aliases = map.get(entrez); + if (aliases==null) { + aliases = new HashSet(); + map.put(entrez, aliases); + } + aliases.add(rs.getString("GENE_ALIAS")); + } + return map; + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoGene.class, con, pstmt, rs); + } + } + + /** + * Gets all Genes in the Database. + * + * @return ArrayList of Canonical Genes. + * @throws DaoException Database Error. + */ + public static ArrayList getAllGenes() throws DaoException { + Map> mapAliases = getAllAliases(); + ArrayList geneList = new ArrayList(); + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoGene.class); + pstmt = con.prepareStatement + ("SELECT * FROM gene"); + rs = pstmt.executeQuery(); + while (rs.next()) { + long entrezGeneId = rs.getInt("ENTREZ_GENE_ID"); + Set aliases = mapAliases.get(entrezGeneId); + CanonicalGene gene = new CanonicalGene(entrezGeneId, + rs.getString("HUGO_GENE_SYMBOL"), aliases); + gene.setCytoband(rs.getString("CYTOBAND")); + gene.setLength(rs.getInt("LENGTH")); + gene.setType(rs.getString("TYPE")); + geneList.add(gene); + } + return geneList; + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoGene.class, con, pstmt, rs); + } + } + + /** + * Gets the Gene with the Specified HUGO Gene Symbol. + * For faster access, consider using DaoGeneOptimized. + * + * @param hugoGeneSymbol HUGO Gene Symbol. + * @return Canonical Gene Object. + * @throws DaoException Database Error. + */ + private static CanonicalGene getGene(String hugoGeneSymbol) throws DaoException { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoGene.class); + pstmt = con.prepareStatement + ("SELECT * FROM gene WHERE HUGO_GENE_SYMBOL = ?"); + pstmt.setString(1, hugoGeneSymbol); + rs = pstmt.executeQuery(); + if (rs.next()) { + return extractGene(rs); + } else { + return null; + } + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoGene.class, con, pstmt, rs); + } + } + + private static CanonicalGene extractGene(ResultSet rs) throws SQLException, DaoException { + long entrezGeneId = rs.getInt("ENTREZ_GENE_ID"); + Set aliases = getAliases(entrezGeneId); + CanonicalGene gene = new CanonicalGene(entrezGeneId, + rs.getString("HUGO_GENE_SYMBOL"), aliases); + gene.setCytoband(rs.getString("CYTOBAND")); + gene.setLength(rs.getInt("LENGTH")); + gene.setType(rs.getString("TYPE")); + + return gene; + } + + /** + * Gets the Number of Gene Records in the Database. + * + * @return number of gene records. + * @throws DaoException Database Error. + */ + public static int getCount() throws DaoException { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoGene.class); + pstmt = con.prepareStatement + ("SELECT COUNT(*) FROM gene"); + rs = pstmt.executeQuery(); + if (rs.next()) { + return rs.getInt(1); + } + return 0; + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoGene.class, con, pstmt, rs); + } + } + + /** + * + * @param entrezGeneId + */ + public static void deleteGene(long entrezGeneId) throws DaoException { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoGene.class); + pstmt = con.prepareStatement("DELETE FROM gene WHERE ENTREZ_GENE_ID=?"); + pstmt.setLong(1, entrezGeneId); + pstmt.executeUpdate(); + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoGene.class, con, pstmt, rs); + } + + deleteGeneAlias(entrezGeneId); + } + + /** + * + * @param entrezGeneId + */ + public static void deleteGeneAlias(long entrezGeneId) throws DaoException { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoGene.class); + pstmt = con.prepareStatement("DELETE FROM gene_alias WHERE ENTREZ_GENE_ID=?"); + pstmt.setLong(1, entrezGeneId); + pstmt.executeUpdate(); + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoGene.class, con, pstmt, rs); + } + } + + /** + * Deletes all Gene Records in the Database. + * + * @throws DaoException Database Error. + */ + public static void deleteAllRecords() throws DaoException { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoGene.class); + JdbcUtil.disableForeignKeyCheck(con); + pstmt = con.prepareStatement("TRUNCATE TABLE gene"); + pstmt.executeUpdate(); + JdbcUtil.enableForeignKeyCheck(con); + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoGene.class, con, pstmt, rs); + } + deleteAllAliasRecords(); + } + + private static void deleteAllAliasRecords() throws DaoException { + Connection con = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + try { + con = JdbcUtil.getDbConnection(DaoGene.class); + pstmt = con.prepareStatement("TRUNCATE TABLE gene_alias"); + pstmt.executeUpdate(); + } catch (SQLException e) { + throw new DaoException(e); + } finally { + JdbcUtil.closeAll(DaoGene.class, con, pstmt, rs); + } + } + +} \ No newline at end of file diff --git a/DaoGeneOptimized.java b/DaoGeneOptimized.java new file mode 100644 index 0000000..225f91f --- /dev/null +++ b/DaoGeneOptimized.java @@ -0,0 +1,453 @@ +/* + * Copyright (c) 2015 Memorial Sloan-Kettering Cancer Center. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS + * FOR A PARTICULAR PURPOSE. The software and documentation provided hereunder + * is on an "as is" basis, and Memorial Sloan-Kettering Cancer Center has no + * obligations to provide maintenance, support, updates, enhancements or + * modifications. In no event shall Memorial Sloan-Kettering Cancer Center be + * liable to any party for direct, indirect, special, incidental or + * consequential damages, including lost profits, arising out of the use of this + * software and its documentation, even if Memorial Sloan-Kettering Cancer + * Center has been advised of the possibility of such damage. + */ + +/* + * This file is part of cBioPortal. + * + * cBioPortal is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . +*/ + +package org.mskcc.cbio.portal.dao; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.mskcc.cbio.portal.model.CanonicalGene; +import org.mskcc.cbio.portal.util.ProgressMonitor; + +/** + * A Utility Class that speeds access to Gene Info. + * + * @author Ethan Cerami + */ +public class DaoGeneOptimized { + private static final String CBIO_CANCER_GENES_FILE = "/cbio_cancer_genes.txt"; + private static final String GENE_SYMBOL_DISAMBIGUATION_FILE = "/gene_symbol_disambiguation.txt"; + + private static final DaoGeneOptimized daoGeneOptimized = new DaoGeneOptimized(); + //nb: make sure any map is also cleared in clearCache() method below: + private final HashMap geneSymbolMap = new HashMap (); + private final HashMap entrezIdMap = new HashMap (); + private final HashMap> geneAliasMap = new HashMap>(); + private final Set cbioCancerGenes = new HashSet(); + private final Map disambiguousGenes = new HashMap(); + + /** + * Private Constructor, to enforce singleton pattern. + * + * @throws DaoException Database Error. + */ + private DaoGeneOptimized () { + fillCache(); + } + + private synchronized void fillCache() { + try { + // Automatically populate hashmap upon init + ArrayList globalGeneList = DaoGene.getAllGenes(); + for (CanonicalGene currentGene: globalGeneList) { + cacheGene(currentGene); + } + } catch (DaoException e) { + e.printStackTrace(); + } + + try { + if (geneSymbolMap.size()>10000) { + // only for deployed version; not for unit test and importing + BufferedReader in = new BufferedReader( + new InputStreamReader(getClass().getResourceAsStream(CBIO_CANCER_GENES_FILE))); + for (String line=in.readLine(); line!=null; line=in.readLine()) { + String[] parts = line.trim().split("\t",-1); + CanonicalGene gene = null; + if (parts.length>1) { + gene = getGene(Long.parseLong(parts[1])); + } else { + gene = getGene(parts[0]); + } + if (gene!=null) { + cbioCancerGenes.add(gene); + } else { + ProgressMonitor.logWarning(line+" in the cbio cancer gene list config file [resources" + CBIO_CANCER_GENES_FILE + + "] is not a HUGO gene symbol. You should either update this file or update the `gene` and `gene_alias` tables to fix this."); + } + } + in.close(); + } + + { + BufferedReader in = new BufferedReader( + new InputStreamReader(getClass().getResourceAsStream(GENE_SYMBOL_DISAMBIGUATION_FILE))); + for (String line=in.readLine(); line!=null; line=in.readLine()) { + if (line.startsWith("#")) { + continue; + } + String[] parts = line.trim().split("\t",-1); + CanonicalGene gene = getGene(Long.parseLong(parts[1])); + if (gene==null) { + ProgressMonitor.logWarning(line+" in config file [resources" + GENE_SYMBOL_DISAMBIGUATION_FILE + + "]is not valid. You should either update this file or update the `gene` and `gene_alias` tables to fix this."); + } + disambiguousGenes.put(parts[0], gene); + } + in.close(); + } + } catch(IOException e) { + e.printStackTrace(); + } + } + + private void clearCache() + { + geneSymbolMap.clear(); + entrezIdMap.clear(); + geneAliasMap.clear(); + cbioCancerGenes.clear(); + disambiguousGenes.clear(); + } + + /** + * Clear and fill cache again. Useful for unit tests and + * for the Import procedure to update the genes table, clearing the + * cache without the need to restart the webserver. + */ + public synchronized void reCache() + { + clearCache(); + fillCache(); + } + + /** + * Adds a new Gene Record to the Database. If the Entrez Gene ID is negative, + * a fake Entrez Gene ID will be assigned. + * @param gene Canonical Gene Object. + * @return number of records successfully added. + * @throws DaoException Database Error. + */ + public int addGene(CanonicalGene gene) throws DaoException { + int ret; + if (gene.getEntrezGeneId()>0) { + ret = DaoGene.addGene(gene); + } else { + ret = DaoGene.addGeneWithoutEntrezGeneId(gene); + } + cacheGene(gene); + return ret; + } + + /** + * Update database with gene length + * @return number of records updated. + * @throws DaoException + */ + public int flushUpdateToDatabase() throws DaoException { + DaoGene.deleteAllRecords(); + MySQLbulkLoader.bulkLoadOn(); + int ret = 0; + for (CanonicalGene gene : getAllGenes()) { + ret += DaoGene.addGene(gene); + } + MySQLbulkLoader.flushAll(); + return ret; + } + + public void deleteGene(CanonicalGene gene) throws DaoException { + DaoGene.deleteGene(gene.getEntrezGeneId()); + geneSymbolMap.remove(gene.getHugoGeneSymbolAllCaps()); + for (String alias : gene.getAliases()) { + String aliasUp = alias.toUpperCase(); + List genes = geneAliasMap.get(aliasUp); + genes.remove(gene); + if (genes.isEmpty()) { + geneAliasMap.remove(aliasUp); + } + } + } + + private void cacheGene(CanonicalGene gene) { + geneSymbolMap.put(gene.getHugoGeneSymbolAllCaps(), gene); + entrezIdMap.put(gene.getEntrezGeneId(), gene); + + for (String alias : gene.getAliases()) { + String aliasUp = alias.toUpperCase(); + List genes = geneAliasMap.get(aliasUp); + if (genes==null) { + genes = new ArrayList(); + geneAliasMap.put(aliasUp, genes); + } + genes.add(gene); + } + } + + /** + * Gets Global Singleton Instance. + * + * @return DaoGeneOptimized Singleton. + * @throws DaoException Database Error. + */ + public static DaoGeneOptimized getInstance() { + return daoGeneOptimized; + } + + /** + * Gets Gene by HUGO Gene Symbol. + * + * @param hugoGeneSymbol HUGO Gene Symbol. + * @return Canonical Gene Object. + */ + public CanonicalGene getGene(String hugoGeneSymbol) { + return geneSymbolMap.get(hugoGeneSymbol.toUpperCase()); + } + + /** + * Looks for a Gene where HUGO Gene Symbol or an alias matches the given symbol. + * + * @param geneSymbol: HUGO Gene Symbol or an alias + * @param searchInAliases: set to true if this method should search for a match in this.geneAliasMap + * in case a matching hugo symbol cannot be found in this.geneSymbolMap + * + * @return + */ + public List getGene(String geneSymbol, boolean searchInAliases) { + CanonicalGene gene = getGene(geneSymbol); + if (gene!=null) { + return Collections.singletonList(gene); + } + + if (searchInAliases) { + List genes = geneAliasMap.get(geneSymbol.toUpperCase()); + if (genes!=null) { + return Collections.unmodifiableList(genes); + } + } + + return Collections.emptyList(); + } + + /** + * Gets Gene By Entrez Gene ID. + * + * @param entrezId Entrez Gene ID. + * @return Canonical Gene Object. + */ + public CanonicalGene getGene(long entrezId) { + return entrezIdMap.get(entrezId); + } + + /** + * Look for genes with a specific ID. First look for genes with the specific + * Entrez Gene ID, if found return this gene; then for HUGO symbol, if found, + * return this gene; and lastly for aliases, if found, return a list of + * matched genes (could be more than one). If nothing matches, return an + * empty list. + * @param geneId an Entrez Gene ID or HUGO symbol or gene alias + * @return A list of genes that match, an empty list if no match. + */ + public List guessGene(String geneId) { + return guessGene(geneId, null); + } + + /** + * Look for genes with a specific ID on a chr. First look for genes with the specific + * Entrez Gene ID, if found return this gene; then for HUGO symbol, if found, + * return this gene; and lastly for aliases, if found, return a list of + * matched genes (could be more than one). If chr is not null, use that to match too. + * If nothing matches, return an empty list. + * @param geneId an Entrez Gene ID or HUGO symbol or gene alias + * @param chr chromosome + * @return A list of genes that match, an empty list if no match. + */ + public List guessGene(String geneId, String chr) { + if (geneId==null) { + return Collections.emptyList(); + } + + CanonicalGene gene; + if (geneId.matches("[0-9]+")) { // likely to be a entrez gene id + gene = getGene(Integer.parseInt(geneId)); + if (gene!=null) { + return Collections.singletonList(gene); + } + } + + gene = getGene(geneId); // HUGO gene symbol + if (gene!=null) { + return Collections.singletonList(gene); + } + + List genes = geneAliasMap.get(geneId.toUpperCase()); + if (genes!=null) { + if (chr==null) { + return Collections.unmodifiableList(genes); + } + + String nchr = normalizeChr(chr); + + List ret = new ArrayList(); + for (CanonicalGene cg : genes) { + String gchr = getChrFromCytoband(cg.getCytoband()); + if (gchr==null // TODO: should we exlude this? + || gchr.equals(nchr)) { + ret.add(cg); + } + } + return ret; + } + + return Collections.emptyList(); + } + + + private static Map validChrValues = null; + public static String normalizeChr(String strChr) { + if (strChr==null) { + return null; + } + + if (validChrValues==null) { + validChrValues = new HashMap(); + for (int lc = 1; lc<=24; lc++) { + validChrValues.put(Integer.toString(lc),Integer.toString(lc)); + validChrValues.put("CHR" + Integer.toString(lc),Integer.toString(lc)); + } + validChrValues.put("X","23"); + validChrValues.put("CHRX","23"); + validChrValues.put("Y","24"); + validChrValues.put("CHRY","24"); + validChrValues.put("NA","NA"); + validChrValues.put("MT","MT"); // mitochondria + } + + return validChrValues.get(strChr); + } + + private static String getChrFromCytoband(String cytoband) { + if (cytoband==null) { + return null; + } + + if (cytoband.startsWith("X")) { + return "23"; + } + + if (cytoband.startsWith("Y")) { + return "24"; + } + + Pattern p = Pattern.compile("([0-9]+).*"); + Matcher m = p.matcher(cytoband); + if (m.find()) { + return m.group(1); + } + + return null; + } + + /** + * Look for gene that can be non-ambiguously determined. + * @param geneId an Entrez Gene ID or HUGO symbol or gene alias + * @return a gene that can be non-ambiguously determined, or null if cannot. + */ + public CanonicalGene getNonAmbiguousGene(String geneId) { + return getNonAmbiguousGene(geneId, null); + } + + /** + * Look for gene that can be non-ambiguously determined. + * @param geneId an Entrez Gene ID or HUGO symbol or gene alias + * @param chr chromosome + * @return a gene that can be non-ambiguously determined, or null if cannot. + */ + public CanonicalGene getNonAmbiguousGene(String geneId, String chr) { + List genes = guessGene(geneId, chr); + if (genes.isEmpty()) { + return null; + } + + if (genes.size()==1) { + return genes.get(0); + } + + if (disambiguousGenes.containsKey(geneId)) { + return disambiguousGenes.get(geneId); + } + + StringBuilder sb = new StringBuilder("Ambiguous alias "); + sb.append(geneId); + sb.append(": corresponding entrez ids of "); + for (CanonicalGene gene : genes) { + sb.append(gene.getEntrezGeneId()); + sb.append(","); + } + sb.deleteCharAt(sb.length()-1); + + ProgressMonitor.logWarning(sb.toString()); + return null; + + } + + public Set getEntrezGeneIds(Collection genes) { + Set entrezGeneIds = new HashSet(); + for (CanonicalGene gene : genes) { + entrezGeneIds.add(gene.getEntrezGeneId()); + } + return entrezGeneIds; + } + + public Set getCbioCancerGenes() { + return Collections.unmodifiableSet(cbioCancerGenes); + } + + public boolean isCbioCancerGene(CanonicalGene gene) { + return cbioCancerGenes.contains(gene); + } + + /** + * Gets an ArrayList of All Genes. + * @return Array List of All Genes. + */ + public ArrayList getAllGenes () { + return new ArrayList(entrezIdMap.values()); + } + + /** + * Deletes all Gene Records in the Database. + * @throws DaoException Database Error. + */ + public void deleteAllRecords() throws DaoException { + DaoGene.deleteAllRecords(); + } +} \ No newline at end of file diff --git a/edu/jhu/u01/DBProperties.java b/edu/jhu/u01/DBProperties.java new file mode 100644 index 0000000..ef7387f --- /dev/null +++ b/edu/jhu/u01/DBProperties.java @@ -0,0 +1,25 @@ +package edu.jhu.u01; + +import org.mskcc.cbio.portal.util.GlobalProperties; + +public class DBProperties { + + private static DBProperties instance; + private DBVendor vendor; + + public static DBProperties getInstance(){ + if(instance == null) + init(); + return instance; + } + private static void init(){ + instance = new DBProperties(); + instance.vendor = DBVendor.mysql; + String readVendor = GlobalProperties.getProperty("db.vendor"); + if (readVendor != null && readVendor.trim().length() > 0) + instance.vendor = DBVendor.valueOf(readVendor.trim()); + } + public static DBVendor getDBVendor(){ + return getInstance().vendor; + } +} diff --git a/edu/jhu/u01/DBVendor.java b/edu/jhu/u01/DBVendor.java new file mode 100644 index 0000000..bed1e0d --- /dev/null +++ b/edu/jhu/u01/DBVendor.java @@ -0,0 +1,6 @@ +package edu.jhu.u01; + +public enum DBVendor { + + mysql,mssql +} diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..311496e --- /dev/null +++ b/pom.xml @@ -0,0 +1,483 @@ + + + + + master + org.mskcc.cbio + 1.4.1 + + 4.0.0 + core + Portal Core + Core libraries shared among other modules + + + + org.mskcc.cbio + business + ${project.version} + + + org.mskcc.cbio + persistence-mybatis + ${project.version} + + + + + org.owasp + antisamy + 1.4 + + + + + org.antlr + antlr-runtime + 3.2 + + + + + commons-collections + commons-collections + 3.2.2 + + + org.apache.geronimo.bundles + commons-discovery + 0.4_1 + runtime + + + commons-dbcp + commons-dbcp + 1.2.2 + + + commons-fileupload + commons-fileupload + 1.2.2 + + + org.apache.axis + axis + 1.4 + runtime + + + org.apache.axis + axis-jaxrpc + 1.4 + runtime + + + commons-io + commons-io + 2.4 + + + commons-httpclient + commons-httpclient + 3.1 + + + org.apache.httpcomponents + httpcore + 4.1 + + + commons-lang + commons-lang + 2.4 + + + org.apache.commons + commons-math3 + 3.2 + + + commons-cli + commons-cli + 1.3 + + + + + com.google.guava + guava + 14.0.1 + + + + + org.codehaus.jackson + jackson-core-asl + 1.9.3 + + + org.codehaus.jackson + jackson-mapper-asl + 1.9.3 + + + + + javax.servlet + javax.servlet-api + 3.0.1 + provided + + + + + net.sf.jopt-simple + jopt-simple + 3.0-rc2 + + + + + com.googlecode.json-simple + json-simple + 1.1 + + + + + net.sf.jung + jung-api + 2.0.1 + + + net.sf.jung + jung-graph-impl + 2.0.1 + + + + + net.sf.opencsv + opencsv + 2.3 + + + + + org.biojava + biojava-core + 4.2.0 + + + org.apache.logging.log4j + log4j-slf4j-impl + + + org.apache.logging.log4j + log4j-api + + + org.apache.logging.log4j + log4j-core + + + + + org.biojava + biojava-structure + 4.2.0 + + + org.apache.logging.log4j + log4j-slf4j-impl + + + org.apache.logging.log4j + log4j-api + + + org.apache.logging.log4j + log4j-core + + + + + + + org.mockito + mockito-all + 1.9.5 + test + + + org.apache.commons + commons-io + 1.3.2 + + + commons-codec + commons-codec + 1.10 + + + + batik + batik + 1.5 + + + batik + batik-rasterizer + 1.5 + + + org.apache.xmlgraphics + batik-codec + 1.7 + + + org.apache.xmlgraphics + fop + 1.0 + + + xerces + xercesImpl + 2.11.0 + + + + dom4j + dom4j + 1.6.1 + + + jaxen + jaxen + 1.1.6 + + + org.springframework + spring-tx + ${spring.version} + + + org.springframework + spring-test + ${spring.version} + test + + + org.easymock + easymock + 3.2 + test + + + cglib + cglib-nodep + + + + + + + + heroku + + + + + maven-clean-plugin + 2.5 + + + clean-artifacts + install + + clean + + + true + + + target + + + + + + + + + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.16 + + always + true + + + log4j.configuration + file:${project.parent.basedir}/src/main/resources/log4j.properties + + + + ${project.parent.basedir}/src/main/resources/ + + false + + + + + org.codehaus.mojo + sql-maven-plugin + 1.5 + + + mysql + mysql-connector-java + 5.0.3 + + + + com.microsoft.sqlserver + mssql-jdbc + 6.1.0.jre8 + + + + + test-compile + + execute + + + + settingsKey + ${db.test.driver} + ${db.test.url} + ${db.test.username} + ${db.test.password} + + + src/main/resources/db/cgds_fixed4MSSQL.sql.MS.CREATE.sql + src/main/resources/db/cgds_fixed4MSSQL.sql.MS.KEYS.sql + src/test/resources/seed_mini.sql + + + + UTF-8 + characterEncoding=utf8, connectionCollation=utf8_general_ci + + ${skipTests} + + + + + + + org.apache.maven.plugins + maven-resources-plugin + + + copy-parent-resources + process-sources + + copy-resources + + + ${project.build.directory}/classes + + + ${project.parent.basedir}/src/main/resources + + **/*.properties + + + **/portal.properties.* + **/log4j.properties.* + **/*.EXAMPLE + + + + + + + + + + org.jacoco + jacoco-maven-plugin + ${jacoco-maven-plugin.version} + + + prepare-agent + + + report + prepare-package + report + + + + + + + + + src/main/resources + + sample_data/** + db/** + + + + ../src/main/resources + true + + **/portal.properties + + + + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.codehaus.mojo + sql-maven-plugin + [1.5,) + + execute + + + + + + + + + + + + + +