package gov.nih.ncgc.bard.tools;
import gov.nih.ncgc.bard.capextract.CAPAnnotation;
import gov.nih.ncgc.bard.capextract.CAPDictionary;
import gov.nih.ncgc.bard.entity.Assay;
import gov.nih.ncgc.bard.entity.BardEntity;
import gov.nih.ncgc.bard.entity.Biology;
import gov.nih.ncgc.bard.entity.Compound;
import gov.nih.ncgc.bard.entity.ETag;
import gov.nih.ncgc.bard.entity.Experiment;
import gov.nih.ncgc.bard.entity.ExperimentData;
import gov.nih.ncgc.bard.entity.ExperimentResultType;
import gov.nih.ncgc.bard.entity.PantherClassification;
import gov.nih.ncgc.bard.entity.Probe;
import gov.nih.ncgc.bard.entity.Project;
import gov.nih.ncgc.bard.entity.ProjectStep;
import gov.nih.ncgc.bard.entity.ProteinTarget;
import gov.nih.ncgc.bard.entity.Publication;
import gov.nih.ncgc.bard.entity.Substance;
import gov.nih.ncgc.bard.entity.TargetClassification;
import gov.nih.ncgc.bard.rest.rowdef.AssayDefinitionObject;
import gov.nih.ncgc.bard.rest.rowdef.DataResultObject;
import gov.nih.ncgc.bard.rest.rowdef.DoseResponseResultObject;
import gov.nih.ncgc.bard.search.Facet;
import gov.nih.ncgc.bard.search.SearchUtil;
import gov.nih.ncgc.bard.search.SolrField;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Reader;
import java.math.BigInteger;
import java.security.Principal;
import java.security.SecureRandom;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Set;
import java.util.TreeMap;
import java.util.Vector;
import java.util.concurrent.atomic.AtomicLong;
import javax.sql.DataSource;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import java.util.logging.Logger;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
import chemaxon.formats.MolFormatException;
import chemaxon.formats.MolImporter;
import chemaxon.struc.Molecule;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
* Utility methods to interact with the database backend.
*
* @author Rajarshi Guha
*/
public class DBUtils {
/*
* maximum size for an ETag
*/
static final int MAX_ETAG_SIZE = 10000;
static final int CHUNK_SIZE = 400;
static CAPDictionary dict = null;
static final String CACHE_PREFIX;
static {
SecureRandom rand = new SecureRandom();
byte[] id = new byte[8];
rand.nextBytes(id);
CACHE_PREFIX = Util.toString(id);
System.err.println("** CACHE PREFIX: " + CACHE_PREFIX + " **");
}
static final int MAX_CACHE_SIZE = 10000;
static final CacheManager cacheManager = CacheManager.getInstance();
static synchronized Cache getCache(String name) {
String cacheName = CACHE_PREFIX + "::" + name;
Cache cache = cacheManager.getCache(cacheName);
if (cache == null) {
cache = new Cache(cacheName,
MAX_CACHE_SIZE,
false, // overflowToDisk
false, // eternal (never expire)
2 * 60 * 60, // time to live (seconds)
2 * 60 * 60 // time to idle (seconds)
);
cacheManager.addCacheIfAbsent(cache);
cache.setStatisticsEnabled(true);
} else {
cache.removeAll();
}
return cache;
}
/**
* ****
* Cache Flush Handling methods (2)
*/
static CacheFlushManager cacheFlushManager;
static Vector<String> flushCachePrefixNames = null;
/**
* Initializes the list of cache prefixes to manage
* This is only called when the container is initialized.
*
* @param cachePrefixListCSV comma delimited list of cache prefixes;
*/
static public void initializeManagedCaches(String cachePrefixListCSV, String cacheClusterNodes) {
cacheFlushManager = new CacheFlushManager(cacheManager);
//make the list of cache prefixes
flushCachePrefixNames = new Vector<String>();
String[] cachePrefixes = cachePrefixListCSV.split(",");
for (String cachePrefix : cachePrefixes) {
flushCachePrefixNames.add(cachePrefix.trim());
}
//put the cache under management control
//if the prefix names are empty or just one (empty string), set flush all boolean
cacheFlushManager.manage(flushCachePrefixNames, cacheClusterNodes, (flushCachePrefixNames.size() < 2));
}
/**
* Called to shutdown cache management. This is typically called when the container is
* destroyed to shutdown the manager gracefully.
*/
static public void shutdownCacheFlushManager() {
cacheFlushManager.shutdown();
}
static class DataSourceContext implements Comparable<DataSourceContext> {
String name;
DataSource ds;
AtomicLong refs = new AtomicLong();
boolean writable;
DataSourceContext(String name, DataSource ds) {
this(name, ds, false);
}
DataSourceContext(String name, DataSource ds, boolean writable) {
this.name = name;
if (ds == null) {
throw new IllegalArgumentException("DataSource is null");
}
this.ds = ds;
this.writable = writable;
}
public String getName() {
return name;
}
public DataSource getDataSource() {
return ds;
}
public boolean isWritable() {
return writable;
}
public Connection getConnection() throws SQLException {
Connection con = ds.getConnection();
con.setAutoCommit(false);
// con.setClientInfo("ApplicationName", "DBUtils");
// con.setClientInfo("ClientUser", name);
refs.incrementAndGet();
return con;
}
public long getRefs() {
return refs.get();
}
public int compareTo(DataSourceContext dsc) {
return (int) (refs.get() - dsc.getRefs());
}
public String toString() {
return getClass() + "{" + name + ":" + refs.get() + "}";
}
}
static private List<DataSourceContext>
_resources = new ArrayList<DataSourceContext>();
static synchronized public void setDataSources(String... sources) {
_resources.clear();
boolean first = true;
for (String s : sources) {
DataSource ds = getDataSource(s);
if (ds != null) {
// the first resource is assumed writable!
_resources.add(new DataSourceContext(s, ds, first));
// log.info("Datasource "+s+" initialized!");
} else {
log.warning("Datasource " + s + " not initialized!");
}
first = false;
}
}
static public List<DataSourceContext> getDataSources() {
return _resources;
}
<T> T getCacheValue(Cache cache, Object key) {
Element el = cache.get(key);
if (el != null) {
return (T) el.getObjectValue();
}
return null;
}
static Logger log;
Map<Class, Query> fieldMap;
SecureRandom rand = new SecureRandom();
class Query {
List<String> validFields;
String orderField, tableName, idField, join;
Query(List<String> validFields, String orderField,
String idField, String tableName) {
this(validFields, orderField, idField, tableName, null);
}
Query(List<String> validFields, String orderField,
String idField, String tableName, String join) {
this.validFields = validFields;
this.orderField = orderField;
this.tableName = tableName;
this.join = join;
if (idField == null) this.idField = orderField;
else this.idField = idField;
}
public List<String> getValidFields() {
return validFields;
}
public String getOrderField() {
return orderField;
}
public String getTableName() {
return tableName;
}
public String getIdField() {
return idField;
}
public String getJoin() {
return join;
}
}
public DBUtils() {
log = Logger.getLogger(DBUtils.class.getName());
log.info("DBUtils initialized. No connection yet.");
final List<String> publicationFields = Arrays.asList("pmid", "title", "abstract", "doi");
final List<String> projectFields = Arrays.asList("name", "description");
final List<String> targetFields = Arrays.asList("accession", "name", "description", "uniprot_status");
final List<String> experimentFields = Arrays.asList("name", "description", "source", "grant_no");
final List<String> compoundFields = new ArrayList<String>();//Arrays.asList("url");
final List<String> substanceFields = Arrays.asList("substance_url", "source_name", "dep_regid");
final List<String> assayFields = Arrays.asList("name", "description", "protocol", "comemnt", "source", "grant_no");
final List<String> edFields = Arrays.asList();
final List<String> etagFields = Arrays.asList("name", "type");
final List<String> biologyFields = Arrays.asList("ext_id", "description");
fieldMap = new HashMap<Class, Query>() {{
put(Publication.class, new Query(publicationFields, "pmid", null, "publication"));
put(Project.class, new Query(projectFields, "bard_proj_id", null, "bard_project"));
put(ProteinTarget.class, new Query(targetFields, "accession", null, "protein_target"));
put(Biology.class, new Query(biologyFields, "serial", null, "bard_biology"));
put(Experiment.class, new Query(experimentFields, "bard_expt_id", null, "bard_experiment"));
put(Compound.class, new Query(compoundFields, "druglike desc, activity desc", "cid", "compound_rank"));
put(Probe.class, new Query(compoundFields, "updated desc", "cid", "compound", " probe_id is not null and compound_class = 'ML Probe'"));
put(Substance.class, new Query(substanceFields, "sid", null, "substance"));
put(Assay.class, new Query(assayFields, "bard_assay_id", null, "bard_assay"));
put(ExperimentData.class, new Query(edFields, "expt_data_id", null, "bard_experiment_data"));
put(ETag.class, new Query(etagFields, "etag_id", null, "etag", "status=1"));
}};
}
/**
* Indicates whether the database connection is ready / valid.
*
* @return <code>true</code> if there is a valid connection to the database, otherwise false
*/
public boolean ready() {
return !getDataSources().isEmpty();
}
public void closeConnection() throws SQLException {
}
private Connection getConnection() {
return getConnection(false);
}
private synchronized Connection getConnection(boolean writable) {
log.warning("Hey, in GET CONNECTION!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
List<DataSourceContext> sources = getDataSources();
if (sources.isEmpty()) {
log.warning("Hey, NO DATA SOURCES!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
throw new IllegalStateException("No data sources set!");
}
if (sources.size() == 1) {
DataSourceContext ctx = sources.iterator().next();
try {
return ctx.getConnection();
} catch (Exception ex) {
ex.printStackTrace();
log.warning("Hey, CANT GET SINGLE CONNECTION!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
log.warning("Can't get connection from " + ctx.getName() + "!");
}
return null;
}
// ? The code use to interate over this empty 'order' collection
// PriorityQueue<DataSourceContext> order =
// new PriorityQueue<DataSourceContext>();
for (Iterator<DataSourceContext> it = sources.iterator();
it.hasNext(); ) {
DataSourceContext ctx = it.next();
try {
if (writable == ctx.isWritable()) {
return ctx.getConnection();
}
} catch (Exception ex) {
ex.printStackTrace();
log.warning("Can't get connection from " + ctx.getName() + "!");
}
}
return null;
}
static private DataSource getDataSource(String jndi) {
javax.naming.Context initContext;
try {
initContext = new javax.naming.InitialContext();
return (DataSource) initContext.lookup("java:comp/env/" + jndi);
} catch (Exception ex) {
//log.info(ex.toString());
// try
try {
initContext = new javax.naming.InitialContext();
return (DataSource) initContext.lookup(jndi);
} catch (Exception e) {
System.err.println("Can't initialize resource " + jndi
+ "; not running in Tomcat/Jetty/Glassfish "
+ "or other app container?");
e.printStackTrace();
}
}
return null;
}
private String readFromClob(Reader reader) throws IOException {
StringBuilder sb = new StringBuilder();
if (reader == null) {
return null;
}
char[] buffer = new char[1];
while (reader.read(buffer) > 0) {
sb.append(buffer);
}
return sb.toString();
}
public Map<String, String> getCacheStatistics() {
Map<String, String> statMap = new HashMap<String, String>();
String[] cacheNames = cacheManager.getCacheNames();
for (String cacheName : cacheNames) {
statMap.put(cacheName, cacheManager.getCache(cacheName).getStatistics().toString());
}
return statMap;
}
public Publication getPublicationByPmid(Long pmid) throws SQLException, IOException {
if (pmid == null) return null;
Cache cache = getCache("PublicationByPmidCache");
try {
Publication pub = (Publication) getCacheValue(cache, pmid);
if (pub != null)
return pub;
} catch (ClassCastException ex) {
//
}
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement("select * from publication where pmid = ?");
try {
pst.setLong(1, pmid);
ResultSet rs = pst.executeQuery();
Publication p = new Publication();
while (rs.next()) {
p.setTitle(rs.getString("title"));
p.setDoi(rs.getString("doi"));
p.setPubmedId(pmid);
p.setAbs(readFromClob(rs.getCharacterStream("abstract")));
}
rs.close();
cache.put(new Element(pmid, p));
return p;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public Publication getPublicationByDoi(String doi) throws SQLException, IOException {
if (doi == null || doi.trim().equals("")) return null;
Cache cache = getCache("PublicationByDoiCache");
try {
Publication pub = (Publication) getCacheValue(cache, doi);
if (pub != null) {
return pub;
}
} catch (ClassCastException ex) {
}
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement("select * from publication where doi = ?");
try {
pst.setString(1, doi);
ResultSet rs = pst.executeQuery();
Publication p = new Publication();
while (rs.next()) {
p.setTitle(rs.getString("title"));
p.setDoi(rs.getString("doi"));
p.setPubmedId(rs.getLong("pmid"));
p.setAbs(readFromClob(rs.getCharacterStream("abstract")));
}
rs.close();
cache.put(new Element(doi, p));
return p;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public List<Publication> getProteinTargetPublications(String accession) throws SQLException {
if (accession == null || accession.trim().equals("")) return null;
Cache cache = getCache("ProteinTargetPublicationsCache");
try {
List list = getCacheValue(cache, accession);
if (list != null) {
return list;
}
} catch (ClassCastException ex) {
}
Connection conn = getConnection();
PreparedStatement pst2 = conn.prepareStatement("select a.* from publication a, target_pub b where b.accession = ? and b.pmid = a.pmid");
try {
pst2.setString(1, accession);
ResultSet rs2 = pst2.executeQuery();
List<Publication> pubs = new ArrayList<Publication>();
while (rs2.next()) {
Publication p = new Publication();
p.setDoi(rs2.getString("doi"));
p.setTitle(rs2.getString("title"));
p.setPubmedId(rs2.getLong("pmid"));
p.setAbs(rs2.getString("abstract"));
pubs.add(p);
}
rs2.close();
cache.put(new Element(accession, pubs));
return pubs;
} finally {
//close resources
JDBCResourceCloser.close(pst2, conn);
}
}
public ProteinTarget getProteinTargetByAccession(String accession) throws SQLException {
if (accession == null || accession.trim().equals("")) return null;
Cache cache = getCache("ProteinTargetByAccessionCache");
try {
ProteinTarget value = getCacheValue(cache, accession);
if (value != null)
return value;
} catch (ClassCastException ex) {
}
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement("select * from protein_target where accession = ?");
try {
pst.setString(1, accession);
ResultSet rs = pst.executeQuery();
ProteinTarget p = new ProteinTarget();
while (rs.next()) {
p.setAcc(accession);
p.setDescription(rs.getString("description"));
p.setGeneId(rs.getLong("gene_id"));
p.setTaxId(rs.getLong("taxid"));
p.setName(rs.getString("name"));
p.setStatus(rs.getString("uniprot_status"));
p.setClasses(getPantherClassesForAccession(accession));
}
rs.close();
cache.put(new Element(accession, p));
return p;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public ProteinTarget getProteinTargetByGeneid(Long geneId) throws SQLException {
if (geneId == null) return null;
Cache cache = getCache("ProteinTargetByGeneIdCache");
ProteinTarget p = null;
try {
p = getCacheValue(cache, geneId);
} catch (ClassCastException ex) {
}
if (p == null) {
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement
("select * from protein_target where gene_id = ?");
try {
pst.setLong(1, geneId);
ResultSet rs = pst.executeQuery();
p = new ProteinTarget();
while (rs.next()) {
p.setAcc(rs.getString("accession"));
p.setDescription(rs.getString("description"));
p.setGeneId(rs.getLong("gene_id"));
p.setTaxId(rs.getLong("taxid"));
p.setName(rs.getString("name"));
p.setStatus(rs.getString("uniprot_status"));
p.setClasses(getPantherClassesForAccession(p.getAcc()));
}
rs.close();
cache.put(new Element(geneId, p));
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
return p;
}
public Long getCidBySid(Long sid) throws SQLException {
Cache cache = getCache("CidBySidCache");
try {
Long value = getCacheValue(cache, sid);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement("select cid from cid_sid where sid = ?");
try {
pst.setLong(1, sid);
ResultSet rs = pst.executeQuery();
long cid = -1L;
if (rs.next()) cid = rs.getLong(1);
rs.close();
cache.put(new Element(sid, cid));
return cid;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public List<Long> getSidsByCid(Long cid) throws SQLException {
Cache cache = getCache("SidsByCidCache");
try {
List value = getCacheValue(cache, cid);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
List<Long> sids = new ArrayList<Long>();
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement("select sid from cid_sid where cid = ?");
try {
pst.setLong(1, cid);
ResultSet rs = pst.executeQuery();
while (rs.next()) sids.add(rs.getLong(1));
rs.close();
cache.put(new Element(cid, sids));
return sids;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public Long[][] getSidsByCids(Long[] cids) throws SQLException {
List<Long[]> list = new ArrayList<Long[]>();
Cache cache = getCache("SidsByCidCache");
List<Long> uncachedCids = new ArrayList<Long>();
try {
for (Long cid : cids) {
List<Long> sids = getCacheValue(cache, cid);
if (sids != null) {
for (Long sid : sids) list.add(new Long[]{cid, sid});
} else uncachedCids.add(cid);
}
} catch (ClassCastException ex) {
}
// if there's nothing in uncachedCids, we got everything from the cache
if (uncachedCids.size() == 0) return list.toArray(new Long[][]{});
Connection conn = getConnection();
List<List<Long>> chunks = Util.chunk(uncachedCids, CHUNK_SIZE);
for (List<Long> chunk : chunks) {
String cidClause = Util.join(chunk, ",");
String sql = "select cid, sid from cid_sid where cid in (" + cidClause + ") order by cid";
Statement stm = conn.createStatement();
try {
ResultSet rs = stm.executeQuery(sql);
List<Long> sids = new ArrayList<Long>();
rs.next();
Long oldCid = rs.getLong(1);
Long sid = rs.getLong(2);
list.add(new Long[]{oldCid, sid});
sids.add(sid);
while (rs.next()) {
Long cid = rs.getLong(1);
sid = rs.getLong(2);
list.add(new Long[]{cid, sid});
if (cid != oldCid) {
cache.put(new Element(oldCid, sids));
sids.clear();
}
sids.add(sid);
oldCid = cid;
}
cache.put(new Element(oldCid, sids));
rs.close();
} finally {
//close resources
JDBCResourceCloser.close(stm, conn);
}
}
return list.toArray(new Long[][]{});
}
/**
* Obtain compounds based on their CIDs.
*
* @param cids one or more CIDs. If any CID is null, then the function returns null
* @return a list of {@link Compound} objects
* @throws SQLException
*/
public List<Compound> getCompoundsByCid(Long... cids)
throws SQLException {
if (cids == null || cids.length < 0) return null;
Cache cache = getCache("CompoundsByCidCache");
List<Compound> compounds = new ArrayList<Compound>();
List<Long> notcached = new ArrayList<Long>();
for (Long acid : cids) {
Compound value = null;
try {
value = getCacheValue(cache, acid);
} catch (ClassCastException ex) {
}
if (value != null) {
compounds.add(value);
} else {
notcached.add(acid);
}
}
if (!notcached.isEmpty()) {
Connection conn = getConnection();
cids = notcached.toArray(new Long[0]);
List<List<Long>> chunks = Util.chunk(cids, CHUNK_SIZE);
for (List<Long> chunk : chunks) {
String cidClause = Util.join(chunk, ",");
String sql = ("select a.*,b.* from compound a, compound_props b "
+ "where a.cid in (" + cidClause + ") and "
+ "b.pubchem_compound_cid = a.cid");
Statement stm = conn.createStatement();
try {
ResultSet rs = stm.executeQuery(sql);
while (rs.next()) {
Compound c = new Compound();
c.setCid(rs.getLong("cid"));
fillCompound(rs, c);
compounds.add(c);
c.setNumAssay(getEntityCountByCid(c.getCid(), Assay.class));
c.setNumActiveAssay(getEntityCountByActiveCid(c.getCid(), Assay.class));
cache.put(new Element(c.getCid(), c));
}
rs.close();
} finally {
//close resources
JDBCResourceCloser.close(stm, conn);
}
}
}
return compounds;
}
/**
* Get {@link Compound} instances based on names.
* <p/>
* <b>TODO</b>
* In this case, we have to perform an SQL query for each supplied name as
* we are employing the full text query facility. It might be possible to
* enhance the performance by OR'ing the supplied names together.
*
* @param names an array of names
* @return a list of {@link Compound} objects
* @throws SQLException
*/
public List<Compound> getCompoundsByName(String... names)
throws SQLException {
if (names == null || names.length == 0) return null;
List<Compound> cmpds = new ArrayList<Compound>();
List<String> notcached = new ArrayList<String>();
Cache cache = getCache("CompoundsByNameCache");
for (String n : names) {
List<Compound> value = null;
try {
value = getCacheValue(cache, n);
} catch (ClassCastException ex) {
}
if (value != null) {
cmpds.addAll(value);
} else {
notcached.add(n);
}
}
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement("select distinct id from synonyms where type = 1 and match(syn) against (? in boolean mode)");
try {
ResultSet rs;
for (String name : notcached) {
// if names have spaces we quote here, since we can't pass
// quotes via URL. But we do check if the name contains quotes
// and if so, skip explicit quoting
if (!name.contains("\"") && name.contains(" ")) name = "\"" + name + "\"";
pst.setString(1, name);
rs = pst.executeQuery();
List<Compound> c = new ArrayList<Compound>();
while (rs.next()) {
c.addAll(getCompoundsByCid(rs.getLong(1)));
}
rs.close();
cache.put(new Element(name, c));
cmpds.addAll(c);
}
return cmpds;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public List<Compound> getCompoundsBySid(Long... sids) throws SQLException {
if (sids == null || sids.length == 0) return null;
List<Compound> cmpds = new ArrayList<Compound>();
List<Long> notcached = new ArrayList<Long>();
Cache cache = getCache("CompoundsBySidCache");
for (Long sid : sids) {
Compound value = null;
value = getCacheValue(cache, sid);
if (value != null) cmpds.add(value);
else notcached.add(sid);
}
Connection conn = getConnection();
PreparedStatement pst = null;
List<List<Long>> chunks = Util.chunk(notcached, CHUNK_SIZE);
try {
for (List<Long> chunk : chunks) {
String sidClause = Util.join(chunk, ",");
String sql = "select cid from cid_sid s where s.sid in (" + sidClause + ")";
pst = conn.prepareStatement(sql);
List<Long> cids = new ArrayList<Long>();
Set<Long> unique = new HashSet<Long>();
ResultSet rs = pst.executeQuery();
while (rs.next()) {
long cid = rs.getLong("cid");
if (!unique.contains(cid)) {
unique.add(cid);
cids.add(cid);
}
}
rs.close();
List<Compound> notCachedCompounds = getCompoundsByCid(cids.toArray(new Long[]{}));
for (Compound c : notCachedCompounds) {
List<Long> notCachedSids = c.getSids();
if (notCachedSids == null) continue;
for (Long sid : notCachedSids) cache.put(new Element(sid, c));
}
cmpds.addAll(notCachedCompounds);
}
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
return cmpds;
}
public String newETag(String name, String clazz) throws SQLException {
return newETag(name, null, clazz);
}
public String newETag(String name, String url, String clazz) throws SQLException {
if (clazz == null) {
throw new IllegalArgumentException("Please specify the class!");
}
Connection conn = getConnection(true); // master
PreparedStatement pst = conn.prepareStatement
("insert into etag(etag_id,name,type,created,modified,url) "
+ "values (?,?,?,?,?,?)");
try {
String etag = null;
int tries = 0;
do {
try {
byte[] id = new byte[8];
rand.nextBytes(id);
etag = Util.toString(id);
pst.setString(1, etag);
pst.setString(2, name);
pst.setString(3, clazz);
Timestamp ts = new Timestamp
(new java.util.Date().getTime());
pst.setTimestamp(4, ts);
pst.setTimestamp(5, ts);
pst.setString(6, url);
if (pst.executeUpdate() > 0) {
} else {
log.info("** Couldn't insert ETag " + etag);
etag = null;
}
break;
} catch (SQLException ex) { // etag already exists
//ex.printStackTrace();
log.info("** ETag " + etag
+ " already exists; generating a new one after "
+ tries + " tries!");
etag = null;
++tries;
}
}
while (etag == null && tries < 5);
if (etag != null) {
conn.commit();
}
return etag;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public int createETagLinks(String etag, String... parents)
throws SQLException {
Connection conn = getConnection(true);
PreparedStatement pst = conn.prepareStatement
("insert into etag_link(etag_id, parent_id) values (?,?)");
int links = 0;
try {
// should verify that both both parent and child are
// of the same type
pst.setString(1, etag);
for (String p : parents) {
pst.setString(2, p);
if (pst.executeUpdate() > 0) {
++links;
}
}
return links;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public int putETag(String etag, Long... ids) throws SQLException {
return putETag(etag, null, ids);
}
public int putETag(String etag, String name, Long... ids) throws SQLException {
int cnt = 0;
Connection conn = getConnection(true);
PreparedStatement pst = conn.prepareStatement
("select a.*,count(*) as size from etag a left join etag_data b "
+ "on a.etag_id = b.etag_id where a.etag_id = ? "
+ "group by a.etag_id");
try {
pst.setString(1, etag);
int size = 0;
ResultSet rs = pst.executeQuery();
if (rs.next()) {
String id = rs.getString("etag_id");
size = rs.getInt("size");
if (id == null) {
throw new IllegalArgumentException
("Unknown ETag \"" + etag + "\"");
}
}
rs.close();
pst.close();
if (name != null) {
pst = conn.prepareStatement
("update etag set name = ?, modified = ? where etag_id = ?");
pst.setString(1, name);
pst.setTimestamp(2, new java.sql.Timestamp
(new java.util.Date().getTime()));
pst.setString(3, etag);
pst.executeUpdate();
pst.close();
}
cnt = size;
pst = conn.prepareStatement
("insert into etag_data(etag_id, data_id) values (?,?)");
pst.setString(1, etag);
for (Long id : ids) {
if (id != null && (cnt + 1) <= MAX_ETAG_SIZE) {
pst.setLong(2, id);
try {
if (pst.executeUpdate() > 0) {
++cnt;
}
} catch (SQLException ex) {
log.warning("** " + id + ": " + ex.getMessage());
// ignore dups...
}
}
}
pst.close();
cnt -= size;
log.info("## " + cnt + " entries added for ETag " + etag);
if (cnt > 0) {
conn.commit();
pst = conn.prepareStatement
("update etag set modified = ? where etag_id = ?");
pst.setTimestamp(1, new java.sql.Timestamp
(new java.util.Date().getTime()));
pst.setString(2, etag);
pst.executeUpdate();
}
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
return cnt;
}
public void touchETag(String etag) throws SQLException {
PreparedStatement pst = null;
Connection conn = getConnection(true);
try {
pst = conn.prepareStatement
("update etag set accessed = ? where etag_id = ?");
pst.setTimestamp(1, new java.sql.Timestamp
(new java.util.Date().getTime()));
pst.setString(2, etag);
if (pst.executeUpdate() > 0) {
}
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public List<Compound> getCompoundsByProbeId(String... probeids)
throws SQLException {
Connection conn = getConnection();
if (probeids == null || probeids.length == 0) return null;
List<List<String>> chunks = Util.chunk(probeids, CHUNK_SIZE);
List<Compound> compounds = new ArrayList<Compound>();
for (List<String> chunk : chunks) {
List<String> qprobeids = new ArrayList<String>();
for (String pid : probeids) qprobeids.add("'" + pid + "'");
String probeidClause = Util.join(qprobeids, ",");
String sql = "select * from compound a, compound_props b "
+ "where probe_id in (" + probeidClause + ") "
+ "and a.cid = b.pubchem_compound_cid";
PreparedStatement pst = conn.prepareStatement(sql);
try {
ResultSet rs = pst.executeQuery();
while (rs.next()) {
Compound c = new Compound();
fillCompound(rs, c);
compounds.add(c);
}
rs.close();
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
//close resources
JDBCResourceCloser.close(conn);
// get Sids
for (Compound c : compounds) {
c.setSids(getSidsByCid(c.getCid()));
}
return compounds;
}
public ETag getEtagByEtagId(String id) throws SQLException {
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement("select a.*, count(*) as cnt from etag a, etag_data b where a.etag_id = ? and a.etag_id = b.etag_id");
ETag etag = new ETag();
try {
pst.setString(1, id);
ResultSet rs = pst.executeQuery();
while (rs.next()) {
etag.setEtag(id);
etag.setName(rs.getString("name"));
etag.setType(rs.getString("type"));
etag.setAccessed(rs.getDate("accessed"));
etag.setCreated(rs.getDate("created"));
etag.setModified(rs.getDate("modified"));
etag.setCount(rs.getInt("cnt"));
etag.setUrl(rs.getString("url"));
}
rs.close();
// pull in the children if any
PreparedStatement pst2 = conn.prepareStatement("select * from etag_link where parent_id = ?");
pst2.setString(1, id);
ResultSet rs2 = pst2.executeQuery();
List<ETag> linkedTags = new ArrayList<ETag>();
while (rs2.next()) {
ETag linkedTag = getEtagByEtagId(rs2.getString("etag_id"));
if (linkedTag.getEtag() != null) linkedTags.add(linkedTag);
}
etag.setLinkedTags(linkedTags);
rs2.close();
pst2.close();
return etag;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public Map getETagInfo(String etag) throws SQLException {
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement
("select a.*,count(*) as count from etag a, etag_data b "
+ "where a.etag_id = ? and a.etag_id = b.etag_id");
Map info = new HashMap();
try {
pst.setString(1, etag);
ResultSet rs = pst.executeQuery();
ResultSetMetaData meta = rs.getMetaData();
while (rs.next()) {
for (int c = 0; c < meta.getColumnCount(); ++c) {
int type = meta.getColumnType(c + 1);
String name = meta.getColumnName(c + 1);
info.put(name, rs.getObject(c + 1));
}
}
rs.close();
return info;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public Facet getCompoundCollectionFacet(String etag)
throws SQLException {
Map info = getETagInfo(etag);
Cache cache = getCache("CompoundCollectionFacetCache");
Element el = cache.get(etag);
if (el != null) {
Timestamp ts = (Timestamp) info.get("accessed");
if (ts.getTime() < el.getLastAccessTime()) {
try {
Facet value = getCacheValue(cache, etag);
if (value != null)
return value;
} catch (ClassCastException ex) {
}
}
}
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement
("select val,count(*) as cnt from "
+ "compound_annot a, etag_data b "
+ "where annot_key = 'COLLECTION' "
+ "and b.etag_id = ? "
+ "and a.cid = b.data_id "
+ "group by val "
// order don't matter because we use a hash below.. sigh
// +"order by cnt desc, val"
);
String[] wtf = new String[]{
"NPC screening",
"DrugBank v3.0",
"NPC informatics",
"INN", "Withdrawn"
};
try {
pst.setString(1, etag);
ResultSet rs = pst.executeQuery();
Map<String, Integer> counts = new HashMap<String, Integer>();
while (rs.next()) {
String f = rs.getString(1);
int cnt = rs.getInt(2);
// sigh...
int n = 0;
for (String s : wtf) {
if (f.startsWith(s)) {
++n;
Integer c = counts.get(s);
counts.put(s, c != null ? (c + cnt) : cnt);
}
}
if (n == 0 && !f.startsWith("ChemIDPlus")) {
Integer c = counts.get(f);
counts.put(f, c != null ? (c + cnt) : cnt);
}
}
rs.close();
Facet facet = new Facet("COLLECTION");
facet.setCounts(counts);
cache.put(new Element(etag, facet));
return facet;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public List<String> getCompoundSynonyms(Long cid) throws SQLException {
Cache cache = getCache("CompoundSynonymsCache");
try {
List value = getCacheValue(cache, cid);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement
("select syn from synonym_type where id = ? and type=1");
List<String> syns = new ArrayList<String>();
try {
pst.setLong(1, cid);
ResultSet rs = pst.executeQuery();
while (rs.next()) {
syns.add(rs.getString(1));
}
rs.close();
cache.put(new Element(cid, syns));
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
return syns;
}
public List<Facet> getCompoundPropertyFacets(String etag)
throws SQLException {
Object[][] props = new Object[][]{
{"xlogp", "PUBCHEM_XLOGP3", 0},
{"exact_mass", "PUBCHEM_EXACT_MASS", -2},
{"mwt", "PUBCHEM_MOLECULAR_WEIGHT", -2},
{"complexity", "PUBCHEM_CACTVS_COMPLEXITY", -2},
{"hbond_acceptor", "PUBCHEM_CACTVS_HBOND_ACCEPTOR", 0},
{"hbond_donnor", "PUBCHEM_CACTVS_HBOND_DONOR", 0},
{"rotatable", "PUBCHEM_CACTVS_ROTATABLE_BOND", 0},
{"tautomer", "PUBCHEM_CACTVS_TAUTO_COUNT", 0},
{"tpsa", "PUBCHEM_CACTVS_TPSA", -1},
{"mono_mwt", "PUBCHEM_MONOISOTOPIC_WEIGHT", -2}
};
List<Facet> facets = new ArrayList<Facet>();
for (int i = 0; i < props.length; ++i) {
try {
Facet f = getCompoundPropertyFacet
(etag, (String) props[i][0], (String) props[i][1],
(Integer) props[i][2]);
facets.add(f);
} catch (SQLException ex) {
ex.printStackTrace();
}
}
return facets;
}
public Facet getCompoundPropertyFacet
(String etag, String name, String column, int precision)
throws SQLException {
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement
("select round(" + column + "," + precision + ") as bucket,\n"
+ "count(*) as count\n"
+ "from compound_props a, etag_data b\n"
+ "where b.etag_id = ?\n"
+ "and b.data_id = a.pubchem_compound_cid\n"
+ "group by bucket\n"
+ "order by bucket");
try {
pst.setString(1, etag);
ResultSet rs = pst.executeQuery();
List<Integer[]> buckets = new ArrayList<Integer[]>();
while (rs.next()) {
Integer range = rs.getInt("bucket");
if (rs.wasNull()) {
range = null;
}
int count = rs.getInt("count");
buckets.add(new Integer[]{range, count});
}
rs.close();
//System.err.println(name+" => "+counts);
Facet f = new Facet(name);
Map<String, Integer> counts = new TreeMap<String, Integer>();
if (!buckets.isEmpty()) {
if (false) { // generate bins
for (int i = 0; i < buckets.size() - 1; ++i) {
Integer[] bin = buckets.get(i);
if (bin[0] == null) {
counts.put("", bin[1]);
} else {
Integer range = buckets.get(i + 1)[0];
counts.put("[" + bin[0] + ", " + range + ")", bin[1]);
}
}
Integer[] bin = buckets.get(buckets.size() - 1);
counts.put(">= " + bin[0], bin[1]);
} else {
// return the lower range and let the client create
// the bins
for (Iterator<Integer[]> iter = buckets.iterator();
iter.hasNext(); ) {
Integer[] bin = iter.next();
counts.put(bin[0] != null
? bin[0].toString() : "", bin[1]);
}
}
}
f.setCounts(counts);
return f;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public List<Facet> getProjectFacets(String etagId) throws SQLException {
List<Facet> facets = new ArrayList<Facet>();
ETag etag = getEtagByEtagId(etagId);
if (etag == null) throw new IllegalArgumentException(etagId + " does not exist");
if (etag.getType() == null) throw new IllegalArgumentException(etagId + " had a null type. Strange!");
if (!etag.getType().equals("gov.nih.ncgc.bard.entity.Project"))
throw new IllegalArgumentException("ETag " + etag + " is of type " + etag.getType());
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement("select data_id from etag_data where etag_id = ?");
try {
pst.setString(1, etagId);
ResultSet rs = pst.executeQuery();
Map<String, Integer> tcounts = new HashMap<String, Integer>();
Map<String, Integer> dcounts = new HashMap<String, Integer>();
Map<String, Integer> ecounts = new HashMap<String, Integer>();
while (rs.next()) {
Long bardProjectId = rs.getLong(1);
// List<CAPAssayAnnotation> capannots = getProjectAnnotations(bardProjectId);
// for (CAPAssayAnnotation annot : capannots) {
// if (annot.key.equals("detection_method_type")) {
// if (dtcounts.containsKey(annot.value)) {
// dtcounts.put(annot.value, dtcounts.get(annot.value) + 1);
// } else dtcounts.put(annot.value, 1);
// }
// }
// target facet
List<Biology> targets = getProjectTargets(bardProjectId);
for (Biology t : targets) {
if (tcounts.containsKey(t.getName())) {
tcounts.put(t.getName(), tcounts.get(t.getName()) + 1);
} else tcounts.put(t.getName(), 1);
}
// disease facet
PreparedStatement pst2 = conn.prepareStatement("select distinct b.* from kegg_gene2disease b, bard_biology c where c.entity = 'project' and c.entity_id = ? and c.biology_dict_id = 880 and b.gene_id = c.ext_id");
pst2.setLong(1, bardProjectId);
ResultSet rs2 = pst2.executeQuery();
while (rs2.next()) {
String dcat = rs2.getString(1);
if (dcounts.containsKey(dcat)) {
dcounts.put(dcat, dcounts.get(dcat) + 1);
} else dcounts.put(dcat, 1);
}
rs2.close();
pst2.close();
}
rs.close();
Facet facet = new Facet("target_name");
facet.setCounts(tcounts);
facets.add(facet);
facet = new Facet("kegg_disease_cat");
facet.setCounts(dcounts);
facets.add(facet);
// facet = new Facet("detection_method_type");
// facet.setCounts(dtcounts);
// facets.add(facet);
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
return facets;
}
public List<Facet> getAssayFacets(String etagId) throws SQLException {
List<Facet> facets = new ArrayList<Facet>();
ETag etag = getEtagByEtagId(etagId);
if (!etag.getType().equals("gov.nih.ncgc.bard.entity.Assay"))
throw new IllegalArgumentException("ETag " + etag + " is of type " + etag.getType());
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement("select data_id from etag_data where etag_id = ?");
PreparedStatement pst2 = null;
try {
pst.setString(1, etagId);
ResultSet rs = pst.executeQuery();
Map<String, Integer> tcounts = new HashMap<String, Integer>();
Map<String, Integer> dcounts = new HashMap<String, Integer>();
// detection_method_type
Map<String, Integer> dtcounts = new HashMap<String, Integer>();
Map<String, Integer> acrcounts = new HashMap<String, Integer>();
while (rs.next()) {
Long bardAssayId = rs.getLong(1);
List<CAPAnnotation> capannots = getAssayAnnotations(bardAssayId);
for (CAPAnnotation annot : capannots) {
if (annot.key == null) {
// source = 'cap-measure' doesn't have anno_key
} else if (annot.key.equals("detection_method_type")) {
if (dtcounts.containsKey(annot.value)) {
dtcounts.put(annot.value, dtcounts.get(annot.value) + 1);
} else dtcounts.put(annot.value, 1);
} else if (annot.key.equals("assay_component_role")) {
if (acrcounts.containsKey(annot.value)) {
acrcounts.put(annot.value, acrcounts.get(annot.value) + 1);
} else acrcounts.put(annot.value, 1);
}
}
// target facet
List<ProteinTarget> targets = getAssayTargets(bardAssayId);
for (ProteinTarget t : targets) {
if (tcounts.containsKey(t.getName())) {
tcounts.put(t.getName(), tcounts.get(t.getName()) + 1);
} else tcounts.put(t.getName(), 1);
}
// disease facet
pst2 = conn.prepareStatement("select disease_category from bard_assay a, kegg_gene2disease b, assay_target c where a.bard_assay_id = ? and a.bard_assay_id=c.bard_assay_id and c.gene_id=b.gene_id");
pst2.setLong(1, bardAssayId);
ResultSet rs2 = pst2.executeQuery();
while (rs2.next()) {
String dcat = rs2.getString(1);
if (dcounts.containsKey(dcat)) {
dcounts.put(dcat, dcounts.get(dcat) + 1);
} else dcounts.put(dcat, 1);
}
rs2.close();
pst2.close();
}
rs.close();
Facet facet = new Facet("target_name");
facet.setCounts(tcounts);
facets.add(facet);
facet = new Facet("kegg_disease_cat");
facet.setCounts(dcounts);
facets.add(facet);
facet = new Facet("detection_method_type");
facet.setCounts(dtcounts);
facets.add(facet);
facet = new Facet("assay_component_role");
facet.setCounts(dtcounts);
facets.add(facet);
} finally {
//close resources
JDBCResourceCloser.close(pst2);
JDBCResourceCloser.close(pst, conn);
}
return facets;
}
public List<Facet> getCompoundFacets(String etag) throws SQLException {
List<Facet> facets = new ArrayList<Facet>();
facets.add(getCompoundCollectionFacet(etag));
facets.addAll(getCompoundPropertyFacets(etag));
return facets;
}
public List<Compound> getEqvCompounds(Long cid) throws SQLException {
Cache cache = getCache("CompoundsEqvClassCache");
List value = getCacheValue(cache, cid);
if (value != null) {
return value;
}
Connection conn = getConnection();
// for extra safe measure we use an additional hash 1
PreparedStatement pstm1, pstm2 = null;
pstm1 = conn.prepareStatement
("select hash1, hash4 from bard2.compound_molfile where cid = ?");
try {
List<Compound> compounds = new ArrayList<Compound>();
pstm1.setLong(1, cid);
ResultSet rset = pstm1.executeQuery();
if (rset.next()) {
String h1 = rset.getString(1);
String h4 = rset.getString(2);
pstm2 = conn.prepareStatement
("select * from compound a, bard2.compound_molfile b, "
+ "compound_props c where a.cid = b.cid "
+ "and a.cid = c.pubchem_compound_cid "
+ "and b.hash1 = binary(?) and b.hash4 = binary(?) "
+ "order by a.cid");
pstm2.setString(1, h1);
pstm2.setString(2, h4);
ResultSet rs = pstm2.executeQuery();
while (rs.next()) {
Compound c = new Compound();
fillCompound(rs, c);
c.setNumAssay(getEntityCountByCid
(c.getCid(), Assay.class));
c.setNumActiveAssay
(getEntityCountByActiveCid(c.getCid(), Assay.class));
compounds.add(c);
}
rs.close();
}
rset.close();
cache.put(new Element(cid, compounds));
return compounds;
} finally {
//close resources
JDBCResourceCloser.close(pstm1, pstm2);
JDBCResourceCloser.close(conn);
}
}
public List<Compound> getCompoundsByHash
(String h1, String h2, String h3, String h4) throws SQLException {
StringBuilder sql = new StringBuilder
("select * from compound a, bard2.compound_molfile b, "
+ "compound_props c where a.cid = b.cid "
+ "and a.cid = c.pubchem_compound_cid");
String hash = "";
List<String> args = new ArrayList<String>();
if (h1 != null) {
sql.append(" and hash1 = binary(?)");
args.add(h1);
hash += h1;
}
if (h2 != null) {
sql.append(" and hash2 = binary(?)");
args.add(h2);
hash += h2;
}
if (h3 != null) {
sql.append(" and hash3 = binary(?)");
args.add(h3);
hash += h3;
}
if (h4 != null) {
sql.append(" and hash4 = binary(?)");
args.add(h4);
hash += h4;
}
Cache cache = getCache("CompoundsByHashCache");
List value = getCacheValue(cache, hash);
if (value != null) {
return value;
}
log.info("HASH: " + hash);
log.info("SQL: " + sql);
Connection conn = getConnection();
PreparedStatement pstm = conn.prepareStatement(sql.toString());
try {
for (int i = 0; i < args.size(); ++i) {
pstm.setString(i + 1, args.get(i));
}
List<Compound> compounds = new ArrayList<Compound>();
ResultSet rset = pstm.executeQuery();
while (rset.next()) {
Compound c = new Compound();
fillCompound(rset, c);
c.setNumAssay(getEntityCountByCid(c.getCid(), Assay.class));
c.setNumActiveAssay
(getEntityCountByActiveCid(c.getCid(), Assay.class));
compounds.add(c);
}
rset.close();
cache.put(new Element(hash, compounds));
return compounds;
} finally {
//close resources
JDBCResourceCloser.close(pstm, conn);
}
}
public List<Compound> getCompoundsByETag
(int skip, int top, String etag) throws SQLException {
Map info = getETagInfo(etag);
if (!Compound.class.getName().equals(info.get("type"))) {
throw new IllegalArgumentException
("ETag " + etag + " is of type " + Compound.class.getName());
}
List<Compound> compounds = new ArrayList<Compound>();
StringBuilder sql = new StringBuilder
("select c.*,d.* from compound c, compound_props d, etag e1, "
+ "etag_data e2 where e1.etag_id = ? "
+ "and e1.type = ? "
+ "and e2.etag_id = e1.etag_id "
+ "and c.cid = e2.data_id "
+ "and d.pubchem_compound_cid = e2.data_id "
+ "order by e2.index");
/*
* for some reaon, mysql takes much longer when limit <= 5.
* perhaps a bug in the query planner. we simply guard it here
* but not sure if we should do it elsewhere too!
*/
if (skip >= 0 && top > 0) {
sql.append(" limit " + skip + "," + Math.max(6, top));
} else if (top > 0) {
sql.append(" limit " + Math.max(6, top));
}
Connection conn = getConnection();
PreparedStatement pst1 = conn.prepareStatement(sql.toString());
try {
pst1.setString(2, Compound.class.getName());
Set<Long> unique = new HashSet<Long>();
pst1.setString(1, etag);
ResultSet rs = pst1.executeQuery();
while (rs.next()) {
Long cid = rs.getLong("cid");
if (!unique.contains(cid)) {
unique.add(cid);
Compound c = new Compound();
compounds.add(c);
c.setCid(cid);
c.setNumAssay(getEntityCountByCid(cid, Assay.class));
c.setNumActiveAssay
(getEntityCountByActiveCid(cid, Assay.class));
fillCompound(rs, c);
}
}
rs.close();
if (top > 0 && top < 6) {
// truncate it to fit the desired size
compounds = compounds.subList(0, top);
}
//touchETag(etag);
for (Compound c : compounds) {
c.setSids(getSidsByCid(c.getCid()));
Map<String, String[]> annots =
getCompoundAnnotations(c.getCid());
c.setAnno_key(annots.get("anno_key"));
c.setAnno_val(annots.get("anno_val"));
}
return compounds;
} finally {
//close resources
JDBCResourceCloser.close(pst1, conn);
}
}
public Map<String, String[]> getFilteredCompoundAnnotations(Long cid, List<String> annoKeys) throws SQLException {
Cache cache = getCache("CompoundAnnotationCache");
String cacheKey = "";
Collections.sort(annoKeys);
for (String annoKey : annoKeys) cacheKey += annoKey;
try {
Map<String, String[]> value = getCacheValue(cache, cacheKey);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
Connection conn = getConnection();
StringBuffer sb = new StringBuffer();
String delim = "";
for (String key : annoKeys) {
sb.append(delim).append("'").append(key).append("'");
delim = ",";
}
String filterClause;
if (annoKeys.size() > 0) filterClause = " and annot_key in (" + sb.toString() + ") ";
else filterClause = "";
PreparedStatement pst = conn.prepareStatement
("select * from compound_annot where cid = ? " + filterClause);
try {
pst.setLong(1, cid);
List<String> keys = new ArrayList<String>();
List<String> vals = new ArrayList<String>();
ResultSet rs = pst.executeQuery();
while (rs.next()) {
String key = rs.getString("annot_key");
String val = rs.getString("val");
if (val != null) {
keys.add(key);
vals.add(val.trim());
}
}
rs.close();
Map<String, String[]> anno = new TreeMap<String, String[]>();
anno.put("anno_key", keys.toArray(new String[keys.size()]));
anno.put("anno_val", vals.toArray(new String[vals.size()]));
cache.put(new Element(cacheKey, anno));
return anno;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public Map<String, String[]> getCompoundAnnotations
(Long cid) throws SQLException {
Cache cache = getCache("CompoundAnnotationCache");
try {
Map<String, String[]> value = getCacheValue(cache, cid);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement
("select * from compound_annot where cid = ?");
try {
pst.setLong(1, cid);
List<String> keys = new ArrayList<String>();
List<String> vals = new ArrayList<String>();
ResultSet rs = pst.executeQuery();
while (rs.next()) {
String key = rs.getString("annot_key");
String val = rs.getString("val");
if (val != null) {
keys.add(key);
vals.add(val.trim());
}
}
rs.close();
Map<String, String[]> anno = new TreeMap<String, String[]>();
anno.put("anno_key", keys.toArray(new String[keys.size()]));
anno.put("anno_val", vals.toArray(new String[vals.size()]));
cache.put(new Element(cid, anno));
return anno;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
protected void fillCompound(ResultSet rs, Compound c)
throws SQLException {
c.setCid(rs.getLong("cid"));
c.setProbeId(rs.getString("probe_id"));
c.setUrl(rs.getString("url"));
// huh? why?
try {
Molecule m = MolImporter.importMol(rs.getString("iso_smiles"));
c.setSmiles(m.toFormat("smiles"));
} catch (MolFormatException e) {
c.setSmiles(rs.getString("iso_smiles"));
}
String iupac = rs.getString("pubchem_iupac_name");
String prefName = rs.getString("preferred_term");
if (prefName != null) c.setName(prefName);
else c.setName(iupac);
c.setIupacName(iupac);
c.setMwt(rs.getDouble("pubchem_molecular_weight"));
if (rs.wasNull()) {
c.setMwt(null);
}
c.setTpsa(rs.getDouble("pubchem_cactvs_tpsa"));
if (rs.wasNull()) {
c.setTpsa(null);
}
c.setExactMass(rs.getDouble("pubchem_exact_mass"));
if (rs.wasNull()) {
c.setExactMass(null);
}
c.setXlogp(rs.getDouble("pubchem_xlogp3"));
if (rs.wasNull()) {
c.setXlogp(rs.getDouble("pubchem_xlogp3_aa"));
if (rs.wasNull()) {
c.setXlogp(null);
}
}
c.setComplexity(rs.getInt("pubchem_cactvs_complexity"));
if (rs.wasNull()) {
c.setComplexity(null);
}
c.setRotatable(rs.getInt("pubchem_cactvs_rotatable_bond"));
if (rs.wasNull()) {
c.setRotatable(null);
}
c.setHbondAcceptor(rs.getInt("pubchem_cactvs_hbond_acceptor"));
if (rs.wasNull()) {
c.setHbondAcceptor(null);
}
c.setHbondDonor(rs.getInt("pubchem_cactvs_hbond_donor"));
if (rs.wasNull()) {
c.setHbondDonor(null);
}
c.setCompoundClass(rs.getString("compound_class"));
if (rs.wasNull()) c.setCompoundClass(null);
if (c.getProbeId() != null) {
List<Long> projects = getProjectIdByProbeId(c.getProbeId());
if (projects != null && projects.size() > 0) {
Long id = projects.get(0);
List<CAPAnnotation> annos = getProjectAnnotations(id);
List<CAPAnnotation> props = new ArrayList();
for (CAPAnnotation anno : annos) {
// we only add annos that are Pubchem CID or probe reports
if (anno.key.equals("1776") || anno.key.equals("878")) props.add(anno);
}
// but a project may refer to many probes. We should only keep those probe
// annotations that are relevant to the current cid
long annoId = -1L;
for (CAPAnnotation anno : props) {
if (anno.key.equals("878") && Long.parseLong(anno.display) == c.getCid()) {
annoId = anno.id;
break;
}
}
List<CAPAnnotation> annosForCid = new ArrayList<CAPAnnotation>();
for (CAPAnnotation anno : props) {
if (anno.id == annoId) annosForCid.add(anno);
}
c.setProbeAnnotations(annosForCid);
}
}
}
/**
* Extract the measured results for a substance in an experiment.
* <p/>
* The identifier will usually be obtained via {@link #getExperimentData(Long, int, int, String)} using the
* experiment identifier (bard_expt_id).
* <p/>
* This method returns an {@link ExperimentData} object that contains the high level summary of the
* result (score, potency, outcome etc) as well as the actual measured data which may be single
* point or dose response.
*
* @param edid The experiment data identifier (of the form BARD_EXPT_ID.SID)
* @return
* @throws SQLException
*/
public ExperimentData getExperimentDataByDataId
(String edid) throws SQLException {
Cache cache = getCache("ExperimentDataByDataIdCache");
try {
ExperimentData value = getCacheValue(cache, edid);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
if (edid == null || !edid.contains(".")) return null;
String[] toks = edid.split("\\.");
Long bardExptId = Long.parseLong(toks[0]);
Long sid = Long.parseLong(toks[1]);
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement("select a . *, b . *, c . *, d.cap_assay_id as real_cap_assay_id from bard_experiment_data a left join bard_experiment_result b on a.expt_data_id = b.expt_data_id left join bard_experiment c on a.bard_expt_id = c.bard_expt_id left join bard_assay d on c.bard_assay_id = d.bard_assay_id where a.bard_expt_id = ? and a.sid = ?");
ExperimentData ed = null;
try {
pst.setLong(1, bardExptId);
pst.setLong(2, sid);
ResultSet rs = pst.executeQuery();
if (rs.next()) {
ed = getExperimentData(rs);
ed.setExptDataId(edid);
}
rs.close();
cache.put(new Element(edid, ed));
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
return ed;
}
/**
* Helper method to get experiment data in chunks.
* <p/>
* This method assumes that all the experiment data identifiers come from the same
* experiment, allowing us to take a shortcut in the SQL. If this is not the case,
* the results will be incomplete/
*
* @param edids
* @return
* @throws SQLException
* @throws IOException
*/
public List<ExperimentData> getExperimentDataByDataId(List<String> edids)
throws SQLException, IOException {
if (edids == null || edids.size() == 0) return null;
Cache cache = getCache("ExperimentDataByDataIdCache");
List<ExperimentData> ret = new ArrayList<ExperimentData>();
List<String> notcached = new ArrayList<String>();
for (String edi : edids) {
ExperimentData value = null;
try {
value = getCacheValue(cache, edi);
} catch (ClassCastException ex) {
}
if (value != null) {
ret.add(value);
} else {
notcached.add(edi);
}
}
if (!notcached.isEmpty()) {
Connection conn = getConnection();
Long bardExptId = -1L;
StringBuilder sbSid = new StringBuilder();
StringBuilder sbEid = new StringBuilder();
sbEid.append("(");
sbSid.append("(");
String sep = "";
for (String edid : notcached) {
String[] toks = edid.split("\\.");
if (toks.length != 2) continue;
bardExptId = Long.parseLong(toks[0]);
Long sid = Long.parseLong(toks[1]);
sbSid.append(sep).append(sid);
sbEid.append(sep).append(bardExptId);
sep = ",";
}
sbSid.append(")");
sbEid.append(")");
if (sbSid.toString().equals("()")) return ret;
// String sql = "select a.*, b.*, c.*, d.bard_proj_id from bard_experiment_data a, bard_experiment_result b, bard_experiment c, bard_project_experiment d where d.bard_expt_id = " + bardExptId + " and a.bard_expt_id = " + bardExptId + " and a.sid in " + sb.toString() + " and a.expt_data_id = b.expt_data_id and a.bard_expt_id = c.bard_expt_id";
String sql = "select a . *, b . *, c . *, d.cap_assay_id as real_cap_assay_id from bard_experiment_data a left join bard_experiment_result b on a.expt_data_id = b.expt_data_id left join bard_experiment c on a.bard_expt_id = c.bard_expt_id left join bard_assay d on c.bard_assay_id = d.bard_assay_id where a.bard_expt_id in " + sbEid.toString() + " and a.sid in " + sbSid.toString();
PreparedStatement pst = conn.prepareStatement(sql);
ExperimentData ed = null;
try {
ResultSet rs = pst.executeQuery();
while (rs.next()) {
ed = getExperimentData(rs);
ret.add(ed);
cache.put(new Element(ed.getExptDataId(), ed));
}
rs.close();
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
return ret;
}
/**
* Retrieves the experiment data by ETag, note the use of teh bardExptId as the experiment key
*
* @param skip
* @param top
* @param bardExptId
* @param etag
* @return
* @throws SQLException
* @throws IOException
*/
public List<ExperimentData> getExperimentDataByETag
(int skip, int top, Long bardExptId, String etag)
throws SQLException, IOException {
List<ExperimentData> data = new ArrayList<ExperimentData>();
Map info = getETagInfo(etag);
Cache cache = getCache("ExperimentDataByETagCache");
Object key = etag + "::" + bardExptId + "::" + skip + "::" + top;
Element el = cache.get(key);
if (el != null) {
Timestamp ts = (Timestamp) info.get("accessed");
if (ts.getTime() < el.getLastAccessTime()) {
try {
List<ExperimentData> value = getCacheValue(cache, key);
if (value != null)
return value;
} catch (ClassCastException ex) {
}
}
}
String type = (String) info.get("type");
log.info("## ETag=" + etag + " info=" + info);
StringBuilder sql = null;
if (type != null) {
if (type.equals(Compound.class.getName())) {
sql = new StringBuilder
("select *, e.cap_assay_id as real_cap_assay_id from bard_experiment_data a, "
+ "bard_experiment_result b, bard_experiment c, bard_assay e, "
+ "etag_data d where a.bard_expt_id = ? and "
+ "d.etag_id = ? and "
+ "a.cid = d.data_id and "
+ "c.bard_assay_id = e.bard_assay_id and "
+ "a.expt_data_id = b.expt_data_id and "
+ "a.bard_expt_id = c.bard_expt_id order by d.index");
} else if (type.equals(Substance.class.getName())) {
sql = new StringBuilder
("select *, e.cap_assay_id as real_cap_assay_id from bard_experiment_data a, "
+ "bard_experiment_result b, bard_experiment c, bard_assay e, "
+ "etag_data d where a.bard_expt_id = ? and "
+ "d.etag_id = ? and "
+ "a.sid = d.data_id and "
+ "c.bard_assay_id = e.bard_assay_id and "
+ "a.expt_data_id = b.expt_data_id and "
+ "a.bard_expt_id = c.bard_expt_id order by d.index");
} else {
log.warning("Can't retrieve experiment data "
+ "for etag of type: " + type);
}
} else {
log.warning("Invalid ETag " + etag);
}
System.out.println("sql = " + sql);
if (sql == null) {
return data;
}
if (skip >= 0 && top > 0) {
sql.append(" limit ").append(skip).append(",").append(top);
} else if (top > 0) {
sql.append(" limit ").append(top);
}
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement(sql.toString());
try {
pst.setLong(1, bardExptId);
pst.setString(2, etag);
ResultSet rs = pst.executeQuery();
while (rs.next()) {
ExperimentData ed = getExperimentData(rs);
ed.setExptDataId(ed.getBardExptId() + "." + ed.getSid());
data.add(ed);
}
rs.close();
cache.put(new Element(key, data));
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
return data;
}
/**
* Helper t build an <code>ExperimentData</code> object
*
* @param rs
* @return
* @throws SQLException
* @throws IOException
*/
ExperimentData getExperimentData(ResultSet rs)
throws SQLException, IOException {
ExperimentData ed = new ExperimentData();
//sets a new field for bard_expt_id
ed.setBardExptId(rs.getLong("bard_expt_id"));
ed.setSid(rs.getLong("sid"));
ed.setCid(rs.getLong("cid"));
ed.setExptDataId(ed.getBardExptId() + "." + ed.getSid());
ed.setBardAssayId(rs.getLong("bard_assay_id"));
ed.setCapAssayId(rs.getLong("real_cap_assay_id"));
ed.setCapExptId(rs.getLong("cap_expt_id"));
Integer classification = rs.getInt("classification");
if (rs.wasNull()) classification = null;
ed.setClassification(classification);
ed.setUpdated(rs.getDate("updated"));
ed.setOutcome(rs.getInt("outcome"));
ed.setScore(rs.getInt("score"));
Float potency = rs.getFloat("potency");
if (rs.wasNull()) potency = null;
ed.setPotency(potency);
Blob blob = rs.getBlob("json_response");
if (blob != null) {
ed.setResultJson(new String(blob.getBytes(1, (int) blob.length())));
}
// pull in associated projects
Connection conn = getConnection();
PreparedStatement ps = null;
try {
ps = conn.prepareStatement("select a.bard_proj_id, b.cap_proj_id from bard_project_experiment a, bard_project b where a.bard_expt_id = ? and a.bard_proj_id = b.bard_proj_id");
ps.setLong(1, ed.getBardExptId());
ResultSet rs2 = ps.executeQuery();
List<Long> bpids = new ArrayList<Long>();
List<Long> cpids = new ArrayList<Long>();
while (rs2.next()) {
bpids.add(rs2.getLong(1));
cpids.add(rs2.getLong(2));
}
ed.setBardProjId(bpids);
ed.setCapProjId(cpids);
rs2.close();
} finally {
//close resources
JDBCResourceCloser.close(ps, conn);
}
return ed;
}
ObjectNode getExperimentDataJsonByExperimentDataId(ExperimentData experimentData, String edid) throws Exception {
String exptId = "";
String[] tokens = edid.split("\\.");
if (tokens.length < 2) {
throw new Exception("Bogus experiment data id: " + edid);
} else if (tokens.length == 2) {
exptId = edid;
} else {
exptId = tokens[0] + "." + tokens[1];
}
if (experimentData == null || experimentData.getExptDataId() == null)
throw new Exception("experimentData should not be null");
//System.err.println("*** "+ Util.toJson(experimentData));
ObjectMapper mapper = new ObjectMapper();
ObjectNode root = mapper.createObjectNode();
root.putPOJO("exptdata", experimentData);
ArrayNode array = root.putArray("results");
AssayDefinitionObject[] ado = experimentData.getDefs();
DataResultObject[] results = experimentData.getResults();
// check the tid; data tid are stored in column coordinate,
// so we need to offset by 8
int tid = Integer.parseInt(tokens[2]);
if (tid == 0) { // return all?
for (AssayDefinitionObject d : ado) {
if ("DoseResponse".equals(d.getType())) {
// ignore dose response
continue;
}
tid = Integer.parseInt(d.getTid());
DataResultObject res = null;
for (DataResultObject r : results) {
if (tid == r.getTid() - 7) {
res = r;
break;
}
}
ObjectNode node = array.addObject();
node.putPOJO("result", d);
Object value = res.getValue();
if (value instanceof String) {
value = ((String) value).replaceAll("\"", "");
if ("".equals(value)) {
value = null;
}
}
node.putPOJO("value", value);
}
} else {
AssayDefinitionObject def = null;
for (AssayDefinitionObject d : ado) {
if (tid == Integer.parseInt(d.getTid())) {
def = d;
break;
}
}
DataResultObject res = null;
for (DataResultObject r : results) {
if (tid == r.getTid() - 7) {
res = r;
break;
}
}
ObjectNode node = array.addObject();
node.putPOJO("result", def);
if ("DoseResponse".equals(def.getType())) {
DoseResponseResultObject drObj = null;
for (DoseResponseResultObject dr :
experimentData.getDr()) {
if (tid == Integer.parseInt(dr.getTid())) {
drObj = dr;
break;
}
}
node.putPOJO("value", drObj);
} else {
Object value = res.getValue();
if (value instanceof String) {
value = ((String) value).replaceAll("\"", "");
if ("".equals(value)) {
value = null;
}
}
node.putPOJO("value", value);
}
}
return root;
}
/**
* Retrieves the experiment result definition based on the bard_expt_id
*
* @param bardExptId
* @return
* @throws SQLException
*/
public String getExperimentMetadataByExptId(Long bardExptId)
throws SQLException {
if (bardExptId == null || bardExptId <= 0) return null;
Cache cache = getCache("ExperimentMetadataByExptIdCache");
try {
String value = (String) getCacheValue(cache, bardExptId);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement
("select expt_result_def from bard_experiment where bard_expt_id = ?");
pst.setLong(1, bardExptId);
ResultSet rs = pst.executeQuery();
String json = null;
try {
if (rs.next()) {
Blob blob = rs.getBlob("expt_result_def");
if (blob == null) json = "";
else json = new String(blob.getBytes(1, (int) blob.length()));
}
rs.close();
cache.put(new Element(bardExptId, json));
return json;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
/**
* Retrieves the experiment object based on bard_experiment_id
*
* @param bardExptId
* @return
* @throws SQLException
*/
public Experiment getExperimentByExptId(Long bardExptId)
throws SQLException {
if (bardExptId == null || bardExptId <= 0) return null;
Cache cache = getCache("ExperimentByExptIdCache");
try {
Experiment value = getCacheValue(cache, bardExptId);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement
("select *, b.cap_assay_id as real_cap_assay_id from bard_experiment a, bard_assay b where bard_expt_id = ? and a.bard_assay_id = b.bard_assay_id");
try {
pst.setLong(1, bardExptId);
ResultSet rs = pst.executeQuery();
Experiment e = null;
if (rs.next()) {
e = getExperiment(rs);
}
rs.close();
//JCB: capture all projects behind the experiment
if (e != null) {
List<Project> projects = getProjectByExperimentId(bardExptId);
for (Project project : projects) {
Long projectId = project.getBardProjectId();
if (projectId != null)
e.addProjectID(project.getBardProjectId());
}
cache.put(new Element(bardExptId, e));
}
return e;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
protected Experiment getExperiment(ResultSet rs) throws SQLException {
Experiment e = new Experiment();
e.setBardExptId(rs.getLong("bard_expt_id"));
e.setBardAssayId(rs.getLong("bard_assay_id"));
e.setCapExptId(rs.getLong("cap_expt_id"));
e.setCapAssayId(rs.getLong("real_cap_assay_id"));
e.setName(rs.getString("name"));
e.setDescription(rs.getString("description"));
e.setDeposited(rs.getDate("deposited"));
e.setUpdated(rs.getDate("updated"));
e.setSubstances(rs.getInt("sample_count"));
e.setCompounds(rs.getInt("cid_count"));
e.setHasProbe(rs.getBoolean("have_probe"));
e.setPubchemAid(rs.getLong("pubchem_aid"));
e.setConfidenceLevel(rs.getFloat("confidence_level"));
e.setStatus(rs.getString("status"));
e.setActiveCompounds(getExperimentCidCount(e.getBardExptId(), true));
return e;
}
public List<Experiment> getExperimentsByExptIds(Long... bardExptIds) throws SQLException {
List<Experiment> expts = new ArrayList<Experiment>();
if (bardExptIds == null || bardExptIds.length == 0) return expts;
String idclause = Util.join(bardExptIds, ",");
String sql = "select *, b.cap_assay_id as real_cap_assay_id from bard_experiment a, bard_assay b where bard_expt_id in (" +
idclause + ") and a.bard_assay_id = b.bard_assay_id";
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement(sql);
try {
ResultSet rs = pst.executeQuery();
while (rs.next()) {
Experiment e = getExperiment(rs);
List<Project> projects = getProjectByExperimentId(e.getBardExptId());
for (Project project : projects) {
Long projectId = project.getBardProjectId();
if (projectId != null)
e.addProjectID(project.getBardProjectId());
}
expts.add(e);
}
rs.close();
return expts;
} finally {
JDBCResourceCloser.close(pst, conn);
}
}
/**
* Returns the list of experiments based on a given bard_assay_id (experiments that use the assay)
*
* @param bardAssayId
* @return
* @throws SQLException
*/
public List<Experiment> getExperimentByAssayId
(Long bardAssayId) throws SQLException {
if (bardAssayId == null || bardAssayId <= 0) return null;
Cache cache = getCache("ExperimentByAssayIdCache");
try {
List<Experiment> value = getCacheValue(cache, bardAssayId);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement
("select bard_expt_id from bard_experiment where bard_assay_id = ?");
try {
pst.setLong(1, bardAssayId);
ResultSet rs = pst.executeQuery();
List<Experiment> experiments = new ArrayList<Experiment>();
while (rs.next()) {
experiments.add(getExperimentByExptId(rs.getLong(1)));
}
rs.close();
cache.put(new Element(bardAssayId, experiments));
return experiments;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
/**
* Returns the Assay for a given bard_assay_id
*
* @param bardAssayID
* @return
* @throws SQLException
*/
public Assay getAssayByAid(Long bardAssayID) throws SQLException {
if (bardAssayID == null || bardAssayID <= 0) return null;
Cache cache = getCache("AssayByAidCache");
try {
Assay value = (Assay) getCacheValue(cache, bardAssayID);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement
("select * from bard_assay where bard_assay_id = ?");
Assay a = null;
try {
pst.setLong(1, bardAssayID);
ResultSet rs = pst.executeQuery();
if (rs.next()) {
a = getAssay(rs);
}
rs.close();
cache.put(new Element(bardAssayID, a));
return a;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
/**
* Helper method to build an Assay object based on a result set
*
* @param rs
* @return
* @throws SQLException
*/
Assay getAssay(ResultSet rs) throws SQLException {
Assay a = new Assay();
Long capAssayId = rs.getLong("cap_assay_id");
a.setCapAssayId(capAssayId);
long bardAssayId = rs.getLong("bard_assay_id");
//add the bard assay id
a.setBardAssayId(bardAssayId);
a.setDeposited(rs.getDate("deposited"));
a.setDescription(rs.getString("description"));
a.setName(rs.getString("name"));
a.setSource(rs.getString("source"));
a.setDesignedBy(rs.getString("designed_by"));
a.setUpdated(rs.getDate("updated"));
a.setComments(rs.getString("comment"));
a.setProtocol(rs.getString("protocol"));
a.setTitle(rs.getString("title"));
a.setAssayStatus(rs.getString("status"));
a.setAssayType(rs.getString("assay_type"));
a.setScore(rs.getFloat("score"));
a.setDocuments(getAssayPublications(bardAssayId));
a.setTargets(getBiologyByEntity("assay", (int) bardAssayId));
a.setExperiments(getExperimentByAssayId(bardAssayId));
a.setProjects(getProjectByAssayId(bardAssayId));
if (dict == null) try {
dict = getCAPDictionary();
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (ClassNotFoundException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
List<CAPAnnotation> capannots = getAssayAnnotations(bardAssayId);
List<String> l1 = new ArrayList<String>();
List<String> l2 = new ArrayList<String>();
for (CAPAnnotation capannot : capannots) {
if (capannot.key != null && Util.isNumber(capannot.key) && dict.getNode(new BigInteger(capannot.key)) != null)
l1.add(dict.getNode(new BigInteger(capannot.key)).getLabel());
if (capannot.value != null && Util.isNumber(capannot.value) && dict.getNode(new BigInteger(capannot.value)) != null)
l2.add(dict.getNode(new BigInteger(capannot.value)).getLabel());
else l2.add(capannot.display);
}
a.setAk_dict_label(l1);
a.setAv_dict_label(l2);
try {
a.setMinimumAnnotations(AnnotationUtils.getMinimumRequiredAssayAnnotations(bardAssayId, this));
} catch (ClassNotFoundException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
return a;
}
public List<Project> getProjectsByETag(int skip, int top, String etag) throws SQLException {
Map info = getETagInfo(etag);
Cache cache = getCache("ProjectsByETagCache");
Object key = etag + "::" + skip + "::" + top;
Element el = cache.get(key);
if (el != null) {
Timestamp ts = (Timestamp) info.get("accessed");
if (ts.getTime() < el.getLastAccessTime()) {
try {
List<Project> value = (List) getCacheValue(cache, key);
if (value != null)
return value;
} catch (ClassCastException ex) {
}
}
}
StringBuilder sql = null;
Object type = info.get("type");
if (Compound.class.getName().equals(type)) {
sql = new StringBuilder
("select * from bard_project where bard_proj_id in "
+ "(select distinct bard_proj_id from bard_project_experiment a, "
+ "bard_experiment_data b, etag_data c where etag_id = ? "
+ "and a.bard_expt_id = b.bard_expt_id "
+ "and b.cid = c.data_id)");
} else if (Substance.class.getName().equals(type)) {
sql = new StringBuilder
("select * from bard_project where bard_proj_id in "
+ "(select distinct bard_proj_id from bard_project_experiment a, "
+ "bard_experiment_data b, etag_data c where etag_id = ? "
+ "and a.bard_expt_id = b.bard_expt_id "
+ "and b.sid = c.data_id)");
} else if (Assay.class.getName().equals(type)) {
sql = new StringBuilder
("select * from bard_project where bard_proj_id in " +
" (select distinct bard_proj_id from bard_assay a, bard_experiment b, bard_project_experiment c " +
" etag_data e where etag_id = ? " +
" and a.bard_assay_id = e.data_id and a.bard_assay_id = b.bard_assay_id " +
" and b.bard_expt_id = c.bard_expt_id and d.bard_proj_id = c.bard_proj_id) ");
} else if (Project.class.getName().equals(type)) {
sql = new StringBuilder
("select a.* from bard_project a, etag_data e where etag_id = ? "
+ "and a.bard_proj_id = e.data_id order by e.index");
} else {
throw new IllegalArgumentException
("Don't know how to get Projects's for etag "
+ etag + " of type " + type + "!");
}
if (skip >= 0 && top > 0) {
sql.append(" limit " + skip + "," + top);
} else if (top > 0) {
sql.append(" limit " + top);
}
List<Project> projects = new ArrayList<Project>();
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement(sql.toString());
try {
pst.setString(1, etag);
ResultSet rs = pst.executeQuery();
while (rs.next()) {
Long bardProjectId = rs.getLong("bard_proj_id");
projects.add(getProject(bardProjectId));
}
rs.close();
cache.put(new Element(key, projects));
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
return projects;
}
/**
* Retruns a list of assay based on an etag.
*
* @param skip
* @param top
* @param etag
* @return
* @throws SQLException
*/
public List<Assay> getAssaysByETag(int skip, int top, String etag)
throws SQLException {
Map info = getETagInfo(etag);
Cache cache = getCache("AssaysByETagCache");
Object key = etag + "::" + skip + "::" + top;
Element el = cache.get(key);
if (el != null) {
Timestamp ts = (Timestamp) info.get("accessed");
if (ts.getTime() < el.getLastAccessTime()) {
try {
List<Assay> value = (List) getCacheValue(cache, key);
if (value != null)
return value;
} catch (ClassCastException ex) {
}
}
}
StringBuilder sql = null;
Object type = info.get("type");
if (Compound.class.getName().equals(type)) {
sql = new StringBuilder
("select * from bard_assay where bard_assay_id in "
+ "(select distinct bard_assay_id from bard_experiment a, "
+ "bard_experiment_data b, etag_data c where etag_id = ? "
+ "and a.bard_expt_id = b.bard_expt_id "
+ "and b.cid = c.data_id)");
} else if (Substance.class.getName().equals(type)) {
sql = new StringBuilder
("select * from bard_assay where bard_assay_id in "
+ "(select distinct bard_assay_id from bard_experiment a, "
+ "bard_experiment_data b, etag_data c where etag_id = ? "
+ "and a.bard_expt_id = b.bard_expt_id "
+ "and b.sid = c.data_id)");
} else if (Assay.class.getName().equals(type)) {
sql = new StringBuilder
("select a.* from bard_assay a, etag_data e where etag_id = ? "
+ "and a.bard_assay_id = e.data_id order by e.index");
} else {
throw new IllegalArgumentException
("Don't know how to get Assay's for etag "
+ etag + " of type " + type + "!");
}
if (skip >= 0 && top > 0) {
sql.append(" limit " + skip + "," + top);
} else if (top > 0) {
sql.append(" limit " + top);
}
List<Assay> assays = new ArrayList<Assay>();
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement(sql.toString());
try {
pst.setString(1, etag);
ResultSet rs = pst.executeQuery();
while (rs.next()) {
assays.add(getAssay(rs));
}
rs.close();
cache.put(new Element(key, assays));
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
return assays;
}
public List<Substance> getSubstanceByETag(int skip, int top, String etag)
throws SQLException {
Map info = getETagInfo(etag);
if (!Substance.class.getName().equals(info.get("type"))) {
throw new IllegalArgumentException
("ETag " + etag + " not of type " + Substance.class.getName());
}
Cache cache = getCache("SubstanceByETagCache");
Object key = etag + "::" + skip + "::" + top;
Element el = cache.get(etag);
if (el != null) {
Timestamp ts = (Timestamp) info.get("accessed");
if (ts.getTime() < el.getLastAccessTime()) {
try {
List<Substance> value = (List) getCacheValue(cache, key);
if (value != null)
return value;
} catch (ClassCastException ex) {
}
}
}
StringBuilder sql = new StringBuilder
("select a.* from substance a, etag_data e where etag_id = ? "
+ "and a.sid = e.data_id order by e.index");
if (skip >= 0 && top > 0) {
sql.append(" limit " + skip + "," + top);
} else if (top > 0) {
sql.append(" limit " + top);
}
ArrayList<Substance> substances = new ArrayList<Substance>();
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement(sql.toString());
try {
pst.setString(1, etag);
ResultSet rs = pst.executeQuery();
while (rs.next()) {
substances.add(getSubstanceBySid(rs.getLong("sid")));
}
rs.close();
cache.put(new Element(key, substances));
return substances;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
/**
* Returns a list of Experiments based on etag.
*
* @param skip
* @param top
* @param etag
* @return
* @throws SQLException
*/
public List<Experiment> getExperimentsByETag
(int skip, int top, String etag) throws SQLException {
Map info = getETagInfo(etag);
Cache cache = getCache("ExperimentsByETagCache");
Object key = etag + "::" + skip + "::" + top;
Element el = cache.get(key);
if (el != null) {
Timestamp ts = (Timestamp) info.get("accessed");
if (ts.getTime() < el.getLastAccessTime()) {
try {
List<Experiment> value = getCacheValue(cache, key);
if (value != null)
return value;
} catch (ClassCastException ex) {
}
}
}
StringBuilder sql = null;
Object type = info.get("type");
if (Compound.class.getName().equals(type)) {
sql = new StringBuilder
("select * from bard_experiment "
+ "where bard_expt_id in (select distinct bard_expt_id "
+ "from etag_data a, bard_experiment_data b "
+ "where etag_id = ? "
+ "and a.data_id = b.cid)");
} else if (Substance.class.getName().equals(type)) {
sql = new StringBuilder
("select * from bard_experiment "
+ "where bard_expt_id in (select distinct bard_expt_id "
+ "from etag_data a, bard_experiment_data b "
+ "where etag_id = ? "
+ "and a.data_id = b.sid)");
} else if (Experiment.class.getName().equals(type)) {
sql = new StringBuilder
("select a.* from bard_experiment a, etag_data e "
+ "where etag_id = ? and a.bard_expt_id = e.data_id "
+ "order by e.index");
} else {
throw new IllegalArgumentException
("Don't know how to get Experiment's for etag "
+ etag + " of type " + type + "!");
}
if (skip >= 0 && top > 0) {
sql.append(" limit " + skip + "," + top);
} else if (top > 0) {
sql.append(" limit " + top);
}
ArrayList<Experiment> expts = new ArrayList<Experiment>();
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement(sql.toString());
try {
pst.setString(1, etag);
ResultSet rs = pst.executeQuery();
while (rs.next()) {
Experiment e = getExperiment(rs);
if (e != null) {
expts.add(e);
}
}
rs.close();
cache.put(new Element(key, expts));
return expts;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public List<Assay> getAssays(Long... assayIds) throws SQLException {
List<Assay> assays = new ArrayList<Assay>();
for (Long aid : assayIds) assays.add(getAssayByAid(aid));
return assays;
}
public int getAssayCidCount(Long bardAssayId, boolean actives) throws SQLException {
if (bardAssayId == null || bardAssayId < 0) return -1;
PreparedStatement pst = null;
Connection conn = getConnection();
int n;
try {
if (!actives)
pst = conn.prepareStatement("select count(distinct cid) from bard_experiment_data a, bard_experiment c, bard_assay b " +
"where b.bard_assay_id = ? " +
"and b.bard_assay_id = c.bard_assay_id " +
"and c.bard_expt_id = a.bard_expt_id");
else
pst = conn.prepareStatement("select count(distinct cid) from bard_experiment_data a, bard_experiment c, bard_assay b " +
"where b.bard_assay_id = ? " +
"and b.bard_assay_id = c.bard_assay_id " +
"and c.bard_expt_id = a.bard_expt_id and a.outcome = 2");
pst.setLong(1, bardAssayId);
ResultSet rs = pst.executeQuery();
rs.next();
n = rs.getInt(1);
rs.close();
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
return n;
}
public int getAssaySidCount(Long bardAssayId, boolean actives) throws SQLException {
if (bardAssayId == null || bardAssayId < 0) return -1;
PreparedStatement pst = null;
Connection conn = getConnection();
int n;
try {
if (!actives)
pst = conn.prepareStatement("select count(distinct sid) from bard_experiment_data a, bard_experiment c, bard_assay b " +
"where b.bard_assay_id = ? " +
"and b.bard_assay_id = c.bard_assay_id " +
"and c.bard_expt_id = a.bard_expt_id");
else
pst = conn.prepareStatement("select count(distinct sid) from bard_experiment_data a, bard_experiment c, bard_assay b " +
"where b.bard_assay_id = ? " +
"and b.bard_assay_id = c.bard_assay_id " +
"and c.bard_expt_id = a.bard_expt_id and a.outcome = 2");
pst.setLong(1, bardAssayId);
ResultSet rs = pst.executeQuery();
rs.next();
n = rs.getInt(1);
rs.close();
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
return n;
}
public int getExperimentCidCount(Long bardExptId, boolean actives) throws SQLException {
if (bardExptId == null || bardExptId < 0) return -1;
PreparedStatement pst = null;
Connection conn = getConnection();
int n;
try {
if (!actives)
pst = conn.prepareStatement("select count(distinct cid) from bard_experiment_data where bard_expt_id = ?");
else
pst = conn.prepareStatement("select count(distinct cid) from bard_experiment_data where bard_expt_id = ? and outcome = 2");
pst.setLong(1, bardExptId);
ResultSet rs = pst.executeQuery();
rs.next();
n = rs.getInt(1);
rs.close();
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
return n;
}
public int getExperimentSidCount(Long bardExptId, boolean actives) throws SQLException {
if (bardExptId == null || bardExptId < 0) return -1;
Connection conn = getConnection();
PreparedStatement pst = null;
ResultSet rs = null;
int n;
try {
if (!actives)
pst = conn.prepareStatement("select count(distinct sid) from bard_experiment_data where bard_expt_id = ?");
else
pst = conn.prepareStatement("select count(distinct sid) from bard_experiment_data where bard_expt_id = ? and outcome = 2");
pst.setLong(1, bardExptId);
rs = pst.executeQuery();
rs.next();
n = rs.getInt(1);
} finally {
JDBCResourceCloser.close(rs, pst, conn);
}
return n;
}
public List<Long> getAssaySids(Long bardAssayId, int skip, int top, boolean actives)
throws SQLException {
if (bardAssayId == null || bardAssayId < 0) return null;
String cacheKey = bardAssayId + "#" + skip + "#" + top + "#" + actives;
Cache cache = getCache("AssaySidsCache");
try {
List<Long> value = (List) getCacheValue(cache, cacheKey);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
String limitClause = generateLimitClause(skip, top);
PreparedStatement pst;
Connection conn = getConnection();
if (!actives)
pst = conn.prepareStatement("select distinct sid from bard_experiment_data a, bard_experiment c, bard_assay b where b.bard_assay_id = ? and b.bard_assay_id = c.bard_assay_id and c.bard_expt_id = a.bard_expt_id order by sid " + limitClause);
else
pst = conn.prepareStatement("select distinct sid from bard_experiment_data a, bard_experiment c, bard_assay b where b.bard_assay_id = ? and b.bard_assay_id = c.bard_assay_id and c.bard_expt_id = a.bard_expt_id and a.outcome = 2 order by sid " + limitClause);
try {
pst.setLong(1, bardAssayId);
ResultSet rs = pst.executeQuery();
List<Long> ret = new ArrayList<Long>();
while (rs.next()) ret.add(rs.getLong("sid"));
rs.close();
cache.put(new Element(cacheKey, ret));
return ret;
} finally {
JDBCResourceCloser.close(pst, conn);
}
}
public List<Long> getAssayCids(Long bardAssayId, int skip, int top, boolean actives)
throws SQLException {
if (bardAssayId == null || bardAssayId < 0) return null;
String cacheKey = bardAssayId + "#" + skip + "#" + top + "#" + actives;
Cache cache = getCache("AssayCidsCache");
try {
List<Long> value = (List) getCacheValue(cache, cacheKey);
if (value != null) {
return value;
}
} catch (ClassCastException ignored) {
}
String limitClause = generateLimitClause(skip, top);
PreparedStatement pst;
Connection conn = getConnection();
if (!actives)
pst = conn.prepareStatement("select distinct cid from bard_experiment_data a, bard_experiment c, bard_assay b where b.bard_assay_id = ? and b.bard_assay_id = c.bard_assay_id and c.bard_expt_id = a.bard_expt_id order by cid " + limitClause);
else
pst = conn.prepareStatement("select distinct cid from bard_experiment_data a, bard_experiment c, bard_assay b where b.bard_assay_id = ? and b.bard_assay_id = c.bard_assay_id and c.bard_expt_id = a.bard_expt_id and a.outcome = 2 order by cid " + limitClause);
try {
pst.setLong(1, bardAssayId);
ResultSet rs = pst.executeQuery();
List<Long> ret = new ArrayList<Long>();
while (rs.next()) ret.add(rs.getLong("cid"));
rs.close();
cache.put(new Element(cacheKey, ret));
return ret;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public List<Compound> getAssayCompounds(Long bardAssayId, int skip, int top, boolean actives)
throws SQLException {
if (bardAssayId == null || bardAssayId < 0) return null;
String cacheKey = bardAssayId + "#" + skip + "#" + top + "#" + actives;
Cache cache = getCache("AssayCompoundsCache");
try {
List<Compound> value = (List<Compound>) getCacheValue(cache, cacheKey);
if (value != null) {
return value;
}
} catch (ClassCastException ignored) {
}
String limitClause = generateLimitClause(skip, top);
PreparedStatement pst;
Connection conn = getConnection();
if (!actives)
pst = conn.prepareStatement("select distinct cid from bard_experiment_data a, bard_experiment c, bard_assay b where b.bard_assay_id = ? and b.bard_assay_id = c.bard_assay_id and c.bard_expt_id = a.bard_expt_id order by cid " + limitClause);
else
pst = conn.prepareStatement("select distinct cid from bard_experiment_data a, bard_experiment c, bard_assay b where b.bard_assay_id = ? and b.bard_assay_id = c.bard_assay_id and c.bard_expt_id = a.bard_expt_id and a.outcome = 2 order by cid " + limitClause);
try {
pst.setLong(1, bardAssayId);
ResultSet rs = pst.executeQuery();
List<Compound> ret = new ArrayList<Compound>();
while (rs.next()) {
ret.addAll(getCompoundsByCid(rs.getLong("cid")));
}
rs.close();
cache.put(new Element(cacheKey, ret));
return ret;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public List<Substance> getAssaySubstances(Long bardAssayId, int skip, int top, boolean actives)
throws SQLException {
if (bardAssayId == null || bardAssayId < 0) return null;
String cacheKey = bardAssayId + "#" + skip + "#" + top + "#" + actives;
Cache cache = getCache("AssaySubstancesCache");
try {
List<Substance> value = (List<Substance>) getCacheValue(cache, cacheKey);
if (value != null) {
return value;
}
} catch (ClassCastException ignored) {
}
String limitClause = generateLimitClause(skip, top);
PreparedStatement pst;
Connection conn = getConnection();
if (!actives)
pst = conn.prepareStatement("select distinct sid from bard_experiment_data a, bard_experiment c, bard_assay b where b.bard_assay_id = ? and b.bard_assay_id = c.bard_assay_id and c.bard_expt_id = a.bard_expt_id order by cid " + limitClause);
else
pst = conn.prepareStatement("select distinct sid from bard_experiment_data a, bard_experiment c, bard_assay b where b.bard_assay_id = ? and b.bard_assay_id = c.bard_assay_id and c.bard_expt_id = a.bard_expt_id and a.outcome = 2 order by cid " + limitClause);
try {
pst.setLong(1, bardAssayId);
ResultSet rs = pst.executeQuery();
List<Substance> ret = new ArrayList<Substance>();
while (rs.next()) {
ret.add(getSubstanceBySid(rs.getLong("sid")));
}
rs.close();
cache.put(new Element(cacheKey, ret));
return ret;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
/**
* Retrieve CIDs for compounds associated with an experiment (based on bard_expt_id).
*
* @param bardExptId The experiment identifier
* @param skip how many records to skip
* @param top how many records to return
* @return A list of compound CIDs
* @throws SQLException if an invalid limit specification is supplied or there is an error in the SQL query
*/
public List<Long> getExperimentCids(Long bardExptId, int skip, int top, boolean actives)
throws SQLException {
if (bardExptId == null || bardExptId < 0) return null;
String cacheKey = bardExptId + "#" + skip + "#" + top + "#" + actives;
Cache cache = getCache("ExperimentCidsCache");
try {
List<Long> value = (List) getCacheValue(cache, cacheKey);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
String limitClause = generateLimitClause(skip, top);
PreparedStatement pst;
Connection conn = getConnection();
if (!actives)
pst = conn.prepareStatement("select distinct cid from bard_experiment_data where bard_expt_id = ? order by cid " + limitClause);
else
pst = conn.prepareStatement("select distinct cid from bard_experiment_data where bard_expt_id = ? and outcome = 2 order by cid " + limitClause);
try {
pst.setLong(1, bardExptId);
ResultSet rs = pst.executeQuery();
List<Long> ret = new ArrayList<Long>();
while (rs.next()) ret.add(rs.getLong("cid"));
rs.close();
cache.put(new Element(cacheKey, ret));
return ret;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
/**
* Return experiment data ids for an experiment.
* <p/>
* The identifiers used to refer to experiment data are a combination of the
* experiment id and the substance identifier in the form <code>EXPT_ID.SID</code>.
*
* @param bardExptId The experiment id (AKA Pubchem AID for experiments taken from Pubchem)
* @param skip how many records to skip
* @param top how many records to return
* @return a list of experiment data ids
* @throws SQLException
*/
public List<String> getExperimentDataIds(Long bardExptId, int skip, int top, String filter)
throws SQLException {
if (bardExptId == null || bardExptId < 0) return null;
String cacheKey = bardExptId + "#" + skip + "#" + top + "#" + filter;
Cache cache = getCache("ExperimentDataIdsCache");
try {
List<String> value = (List) getCacheValue(cache, cacheKey);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
Connection conn = getConnection();
// does the exploded results table have any numeric values for this expt id?
// if not we have to ignore some filter fields and avoid a simple join (and
// a left outer join is prohibitive on expts from primary screens)
PreparedStatement erpst = conn.prepareStatement("select * from exploded_results where bard_expt_id = ? limit 1");
erpst.setLong(1, bardExptId);
ResultSet errs = erpst.executeQuery();
boolean hasExplodedResults = false;
while (errs.next()) hasExplodedResults = true;
errs.close();
erpst.close();
String limitClause = generateLimitClause(skip, top);
String filterClause = "";
String orderClause = "";
if (filter != null) {
// use result types for the experiment to create a list of SolrField
// objects so that we can reuse our search filter parsing code
List<ExperimentResultType> rtypes = getExperimentResultTypes(bardExptId, null);
List<SolrField> fields = new ArrayList<SolrField>();
for (ExperimentResultType rtype : rtypes) {
fields.add(new SolrField(rtype.getName(), "float"));
}
fields.add(new SolrField("outcome", "text"));
fields.add(new SolrField("order", "text"));
Map<String, List<String>> fqs = SearchUtil.extractFilterQueries(filter, fields);
for (String fieldName : fqs.keySet()) {
List<String> vals = fqs.get(fieldName);
if (vals.size() == 0) continue;
// handle outcome specially
if (fieldName.equals("outcome") && vals.size() == 1) {
if (vals.get(0).toLowerCase().contains("\"active\"")) filterClause += " and outcome = 2 ";
else if (vals.get(0).toLowerCase().contains("\"inactive\"")) filterClause += " and outcome = 1 ";
} else if (hasExplodedResults && fieldName.equals("order") && vals.size() == 1) {
String val = vals.get(0).toLowerCase();
if (val.contains("\"asc")) orderClause = " order by value asc ";
else if (val.contains("\"desc")) orderClause = " order by value desc ";
else throw new SQLException("Invalid order specified. Must be asc or desc");
} else if (hasExplodedResults) {
// now deal with individual result types
filterClause += " and display_name = '" + fieldName + "'";
if (!vals.get(0).contains("[")) filterClause += " and value = " + vals.get(0) + " ";
else { // provided a range
String[] toks = vals.get(0).replace("[", "").replace("]", "").split(" TO ");
String lower = toks[0];
String upper = toks[1];
if (lower.equals("*") && !upper.equals("*")) filterClause += " and value <= " + upper + " ";
else if (!lower.equals("*") && upper.equals("*"))
filterClause += " and value >= " + lower + " ";
else if (!lower.equals("*") && !upper.equals("*"))
filterClause += " and value >= " + lower + " and value <= " + upper + " ";
}
}
}
}
// TODO we join exploded_results and bard_experiment_data and then apply limits - might be better to
// query exploded_results and bard_experiment_data in separate calls?
PreparedStatement pst;
if (hasExplodedResults) {
pst = conn.prepareStatement("select distinct concat(cast(b.bard_expt_id as char), '.', cast(b.sid as char)) as id from " +
"exploded_results a, bard_experiment_data b " +
"where a.bard_expt_id = ? " +
filterClause +
"and a.expt_data_id = b.expt_data_id " +
orderClause +
limitClause);
} else {
pst = conn.prepareStatement("select distinct concat(cast(b.bard_expt_id as char), '.', cast(b.sid as char)) as id from " +
"bard_experiment_data b " +
"where b.bard_expt_id = ? " +
filterClause +
limitClause);
}
try {
pst.setLong(1, bardExptId);
ResultSet rs = pst.executeQuery();
List<String> ret = new ArrayList<String>();
while (rs.next()) ret.add(rs.getString(1));
rs.close();
cache.put(new Element(cacheKey, ret));
return ret;
} finally {
JDBCResourceCloser.close(errs, erpst);
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
List<ExperimentData> getExperimentData(PreparedStatement pst) throws SQLException, IOException {
ResultSet rs = pst.executeQuery();
List<ExperimentData> ret = new ArrayList<ExperimentData>();
List<String> chunk = new ArrayList<String>();
int chunkSize = 1000;
int n = 0;
while (rs.next()) {
chunk.add(rs.getString(1));
n++;
if (n == chunkSize) {
ret.addAll(getExperimentDataByDataId(chunk));
chunk.clear();
n = 0;
}
}
if (chunk.size() > 0) ret.addAll(getExperimentDataByDataId(chunk));
rs.close();
return ret;
}
/**
* Return experiment data objects for an experiment.
*
* @param bardExptId The experiment id (AKA Pubchem AID for experiments taken from Pubchem)
* @param skip how many records to skip
* @param top how many records to return
* @return
* @throws SQLException
*/
public List<ExperimentData> getExperimentData
(Long bardExptId, int skip, int top, String filter) throws SQLException, IOException {
if (bardExptId == null || bardExptId < 0) return null;
String cacheKey = bardExptId + "#" + skip + "#" + top + "#" + filter;
Cache cache = getCache("ExperimentDataCache");
try {
List<ExperimentData> value = getCacheValue(cache, cacheKey);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
String limitClause = generateLimitClause(skip, top);
String filterClause = "";
if (filter != null) {
if (filter.toLowerCase().equals("active")) filterClause = " and outcome = 2 ";
else if (filter.toLowerCase().equals("inactive")) filterClause = " and outcome = 1 ";
}
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement("select concat(cast(bard_expt_id as char), '.', cast(sid as char)) as id from bard_experiment_data where bard_expt_id = ? " +
filterClause + " order by score desc, bard_expt_id, sid " + limitClause);
try {
pst.setLong(1, bardExptId);
List<ExperimentData> ret = getExperimentData(pst);
cache.put(new Element(cacheKey, ret));
return ret;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
/**
* Return experiment data objects for an experiment.
*
* @param bardExptId The experiment id (AKA Pubchem AID for experiments taken from Pubchem)
* @param skip how many records to skip
* @param top how many records to return
* @return
* @throws SQLException
*/
public List<ExperimentData> getActiveExperimentData
(Long bardExptId, int skip, int top) throws SQLException, IOException {
if (bardExptId == null || bardExptId < 0) return null;
String cacheKey = bardExptId + "#" + skip + "#" + top;
Cache cache = getCache("ActiveExperimentDataCache");
try {
List<ExperimentData> value = getCacheValue(cache, cacheKey);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
String limitClause = generateLimitClause(skip, top);
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement("select concat(cast(bard_expt_id as char), '.', cast(sid as char)) as id from bard_experiment_data where bard_expt_id = ? and outcome = 2 order by score desc, bard_expt_id, sid " + limitClause);
try {
pst.setLong(1, bardExptId);
List<ExperimentData> ret = getExperimentData(pst);
cache.put(new Element(cacheKey, ret));
return ret;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
/**
* Return experiment data ids for an substance.
*
* @param sid The Pubchem SID
* @param skip how many records to skip
* @param top how many records to return
* @return
* @throws SQLException
*/
public List<String> getSubstanceDataIds(Long sid, int skip, int top, String filter)
throws SQLException {
if (sid == null || sid < 0) return null;
String cacheKey = sid + "#" + skip + "#" + top + "#" + filter;
Cache cache = getCache("SubstanceDataIdsCache");
try {
List<String> value = getCacheValue(cache, cacheKey);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
String limitClause = generateLimitClause(skip, top);
String filterClause = "";
if (filter != null) {
if (filter.toLowerCase().equals("active")) filterClause = " and outcome = 2 ";
else if (filter.toLowerCase().equals("inactive")) filterClause = " and outcome = 1 ";
}
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement("select concat(cast(bard_expt_id as char), '.', cast(sid as char)) as id from bard_experiment_data where sid = ? " + filterClause + " order by classification desc, score desc " + limitClause);
try {
pst.setLong(1, sid);
ResultSet rs = pst.executeQuery();
List<String> ret = new ArrayList<String>();
while (rs.next()) ret.add(rs.getString(1));
rs.close();
cache.put(new Element(cacheKey, ret));
return ret;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
/**
* Get a substance by its SID.
*
* @param sid the SID in question
* @return a {@link Substance} object
* @throws SQLException TODO Should include CID and also include SMILES from CID (rel_type=1)
*/
public Substance getSubstanceBySid(Long sid) throws SQLException {
if (sid == null || sid < 0) return null;
Cache cache = getCache("SubstanceBySidCache");
try {
Substance value = getCacheValue(cache, sid);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement("select a . *, b.cid, c.iso_smiles from substance a left join cid_sid b on a.sid = b.sid left join compound c on c.cid = b.cid where a.sid = ?");
try {
pst.setLong(1, sid);
ResultSet rs = pst.executeQuery();
Substance s = new Substance();
if (rs.next()) {
s.setDepRegId(rs.getString("dep_regid"));
s.setSourceName(rs.getString("source_name"));
s.setUrl(rs.getString("substance_url"));
s.setSid(sid);
s.setDeposited(rs.getDate("deposited"));
s.setUpdated(rs.getDate("updated"));
String pidText = rs.getString("patent_ids");
if (pidText != null) s.setPatentIds(pidText.split("\\s+"));
s.setCid(rs.getLong("cid"));
s.setSmiles(rs.getString("iso_smiles"));
}
rs.close();
if (s.getSid() == null) return null;
cache.put(new Element(sid, s));
return s;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
/**
* Return experiment data objects for a substance.
*
* @param sid The Pubchem SID
* @param skip how many records to skip
* @param top how many records to return
* @return
* @throws SQLException
*/
public List<ExperimentData> getSubstanceData
(Long sid, int skip, int top, String filter) throws SQLException, IOException {
if (sid == null || sid < 0) return null;
String cacheKey = sid + "#" + skip + "#" + top + "#" + filter;
Cache cache = getCache("SubstanceDataCache");
try {
List<ExperimentData> value = getCacheValue(cache, cacheKey);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
String limitClause = generateLimitClause(skip, top);
String filterClause = "";
if (filter != null) {
if (filter.toLowerCase().equals("active")) filterClause = " and outcome = 2 ";
else if (filter.toLowerCase().equals("inactive")) filterClause = " and outcome = 1 ";
}
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement("select concat(cast(bard_expt_id as char), '.', cast(sid as char)) as id from bard_experiment_data where sid = ? " +
filterClause + " order by classification desc, score desc " + limitClause);
try {
pst.setLong(1, sid);
ResultSet rs = pst.executeQuery();
List<ExperimentData> ret = new ArrayList<ExperimentData>();
while (rs.next())
ret.add(getExperimentDataByDataId(rs.getString(1)));
rs.close();
cache.put(new Element(cacheKey, ret));
return ret;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
/**
* Return experiment data ids for a compound.
*
* @param cid The Pubchem CID
* @param skip how many records to skip
* @param top how many records to return
* @return
* @throws SQLException
*/
public List<String> getCompoundDataIds(Long cid, int skip, int top, String filter)
throws SQLException {
if (cid == null || cid < 0) return null;
String cacheKey = cid + "#" + skip + "#" + top + "#" + filter;
Cache cache = getCache("CompoundDataIdsCache");
try {
List<String> value = getCacheValue(cache, cacheKey);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
String limitClause = generateLimitClause(skip, top);
String filterClause = "";
if (filter != null) {
if (filter.toLowerCase().equals("active")) filterClause = " and outcome = 2 ";
else if (filter.toLowerCase().equals("inactive")) filterClause = " and outcome = 1 ";
}
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement("select concat(cast(bard_expt_id as char), '.', cast(sid as char)) as id from bard_experiment_data where cid = ? " + filterClause + " order by classification desc, score desc " + limitClause);
try {
pst.setLong(1, cid);
ResultSet rs = pst.executeQuery();
List<String> ret = new ArrayList<String>();
while (rs.next()) ret.add(rs.getString(1));
rs.close();
cache.put(new Element(cacheKey, ret));
return ret;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
/**
* Return experiment ids for a compound.
*
* @param cid The Pubchem CID
* @param skip how many records to skip
* @param top how many records to return
* @return
* @throws SQLException
*/
/*
public List<Long> getCompoundExperimentIds(Long cid, int skip, int top)
throws SQLException {
if (cid == null || cid < 0) return null;
Cache cache = getCache ("CompoundExperimentIdsCache");
List<Long> value = (List) getCacheValue (cache, cid);
if (value != null) {
return value;
}
String limitClause = "";
if (skip >= 0 && top > 0) {
limitClause = " limit " + skip + "," + top;
}
else if (top > 0) {
limitClause = " limit " + top;
}
else if (skip >= 0) {
limitClause = " limit "+skip+","+CHUNK_SIZE;
}
PreparedStatement pst = conn.prepareStatement("select distinct(bard_expt_id) from bard_experiment_data where cid = ? order by classification desc, score desc " + limitClause);
try {
pst.setLong(1, cid);
ResultSet rs = pst.executeQuery();
List<Long> ret = new ArrayList<Long>();
while (rs.next()) ret.add(rs.getLong(1));
rs.close();
cache.put(new Element (cid, ret));
return ret;
}
finally {
pst.close();
}
}
*/
/**
* Return experiment ids for a substance.
*
* @param sid The Pubchem SID
* @param skip how many records to skip
* @param top how many records to return
* @return
* @throws SQLException
*/
public List<Long> getSubstanceExperimentIds(Long sid, int skip, int top)
throws SQLException {
if (sid == null || sid < 0) return null;
String cacheKey = sid + "#" + skip + "#" + top;
Cache cache = getCache("SubstanceExperimentIdsCache");
try {
List<Long> value = getCacheValue(cache, cacheKey);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
String limitClause = generateLimitClause(skip, top);
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement("select distinct(bard_expt_id) from bard_experiment_data where sid = ? order by classification desc, score desc " + limitClause);
try {
pst.setLong(1, sid);
ResultSet rs = pst.executeQuery();
List<Long> ret = new ArrayList<Long>();
while (rs.next()) ret.add(rs.getLong(1));
rs.close();
cache.put(new Element(cacheKey, ret));
return ret;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
/**
* Return experiment objects for a compound.
*
* @param cid The Pubchem CID
* @param skip how many records to skip
* @param top how many records to return
* @return
* @throws SQLException
*/
/*
public List<Experiment> getCompoundExperiment
(Long cid, int skip, int top) throws SQLException {
if (cid == null || cid < 0) return null;
Cache cache = getCache ("CompoundExperimentCache");
List<Experiment> value = (List) getCacheValue (cache, cid);
if (value != null) {
return value;
}
String limitClause = "";
if (skip >= 0 && top > 0) {
limitClause = " limit " + skip + "," + top;
}
else if (top > 0) {
limitClause = " limit " + top;
}
else if (skip >= 0) {
limitClause = " limit "+skip+","+CHUNK_SIZE;
}
PreparedStatement pst = conn.prepareStatement("select distinct(bard_expt_id) from bard_experiment_data where cid = ? order by classification desc,score desc " + limitClause);
try {
pst.setLong(1, cid);
ResultSet rs = pst.executeQuery();
List<Experiment> ret = new ArrayList<Experiment>();
while (rs.next()) ret.add(getExperimentByExptId(rs.getLong(1)));
rs.close();
cache.put(new Element (cid, ret));
return ret;
}
finally {
pst.close();
}
}
*/
/**
* Return experiment objects for a subtstance.
*
* @param sid The Pubchem SID
* @param skip how many records to skip
* @param top how many records to return
* @return
* @throws SQLException
*/
public List<Experiment> getSubstanceExperiment
(Long sid, int skip, int top) throws SQLException {
if (sid == null || sid < 0) return null;
String cacheKey = sid + "#" + skip + "#" + top;
Cache cache = getCache("SubstanceExperimentCache");
try {
List<Experiment> value = (List) getCacheValue(cache, cacheKey);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
String limitClause = generateLimitClause(skip, top);
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement("select distinct(bard_expt_id) from bard_experiment_data where sid = ? order by classification desc, score desc " + limitClause);
try {
pst.setLong(1, sid);
ResultSet rs = pst.executeQuery();
List<Experiment> ret = new ArrayList<Experiment>();
while (rs.next()) ret.add(getExperimentByExptId(rs.getLong(1)));
rs.close();
cache.put(new Element(cacheKey, ret));
return ret;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
/**
* Return {@link Assay} objects for a substance.
*
* @param sid The Pubchem CID
* @param skip how many records to skip
* @param top how many records to return
* @return
* @throws SQLException
*/
public List<Assay> getSubstanceAssays(Long sid, int skip, int top)
throws SQLException {
if (sid == null || sid < 0) return null;
String cacheKey = sid + "#" + skip + "#" + top;
Cache cache = getCache("SubstanceAssaysCache");
try {
List<Assay> value = getCacheValue(cache, cacheKey);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
String limitClause = generateLimitClause(skip, top);
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement("select distinct b.bard_assay_id from bard_experiment_data a, bard_experiment b where a.sid = ? and a.bard_expt_id = b.bard_expt_id " + limitClause);
try {
pst.setLong(1, sid);
ResultSet rs = pst.executeQuery();
List<Assay> ret = new ArrayList<Assay>();
while (rs.next()) ret.add(getAssayByAid(rs.getLong(1)));
rs.close();
cache.put(new Element(cacheKey, ret));
return ret;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
/**
* Retrieve SIDs for compounds associated with an experiment.
*
* @param bardExptId The experiment identifier
* @param skip how many records to skip
* @param top how many records to return
* @return A list of compound SIDs
* @throws SQLException if an invalid limit specification is supplied or there is an error in the SQL query
*/
public List<Long> getExperimentSids(Long bardExptId, int skip, int top, boolean actives)
throws SQLException {
if (bardExptId == null || bardExptId < 0) return null;
String cacheKey = bardExptId + "#" + skip + "#" + top + "#" + actives;
Cache cache = getCache("ExperimentSidsCache");
try {
List<Long> value = getCacheValue(cache, cacheKey);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
String limitClause = generateLimitClause(skip, top);
PreparedStatement pst;
Connection conn = getConnection();
if (!actives)
pst = conn.prepareStatement("select distinct sid from bard_experiment_data where bard_expt_id = ? order by sid " + limitClause);
else
pst = conn.prepareStatement("select distinct sid from bard_experiment_data where bard_expt_id = ? and outcome = 2 order by sid " + limitClause);
try {
pst.setLong(1, bardExptId);
ResultSet rs = pst.executeQuery();
List<Long> ret = new ArrayList<Long>();
while (rs.next()) ret.add(rs.getLong("sid"));
rs.close();
cache.put(new Element(cacheKey, ret));
return ret;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
private String generateLimitClause(Integer skip, Integer top) {
if (skip == null) skip = -1;
if (top == null) top = -1;
String limitClause = "";
if (skip >= 0 && top > 0) {
limitClause = " limit " + skip + "," + top;
} else if (top > 0) {
limitClause = " limit " + top;
} else if (skip >= 0) {
limitClause = " limit " + skip + "," + CHUNK_SIZE;
}
return limitClause;
}
public List<Float[]> getExperimentResultTypeHistogram(Long bardExptId, String typeName, Integer nbin) throws SQLException {
if (bardExptId == null || bardExptId < 0) return null;
String cacheKey = bardExptId + "#" + typeName + "#" + nbin;
Cache cache = getCache("ExperimentRTHistogramCache");
try {
List<Float[]> value = getCacheValue(cache, cacheKey);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
PreparedStatement pst = null;
Connection conn = getConnection();
List<Float[]> ret = new ArrayList<Float[]>();
try {
pst = conn.prepareStatement("select n, l, u from exploded_histograms where bard_expt_id = ? and display_name = ? order by l");
pst.setLong(1, bardExptId);
pst.setString(2, typeName);
ResultSet rs = pst.executeQuery();
while (rs.next()) ret.add(new Float[]{rs.getFloat("n"), rs.getFloat("l"), rs.getFloat("u")});
rs.close();
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
if (nbin != null && nbin < ret.size()) { // collapse bins
int chunkSize = (int) Math.ceil((double) ret.size() / nbin);
List<Float[]> collapsed = new ArrayList<Float[]>();
List<List<Float[]>> chunks = Util.chunk(ret, chunkSize);
for (List<Float[]> chunk : chunks) {
float count = 0;
float l, u;
l = chunk.get(0)[1];
u = chunk.get(chunk.size() - 1)[2];
for (Float[] elem : chunk) count += elem[0];
collapsed.add(new Float[]{count, l, u});
}
ret = collapsed;
}
cache.put(new Element(ret, cacheKey));
return ret;
}
public List<Float[]> getExperimentResultTypeHistogram(Long bardExptId, String typeName) throws SQLException {
return getExperimentResultTypeHistogram(bardExptId, typeName, null);
}
public List<ExperimentResultType> getExperimentResultTypes(Long bardExptId, Integer collapse) throws SQLException {
if (bardExptId == null || bardExptId < 0) return null;
PreparedStatement pst = null;
String cacheKey = String.valueOf(bardExptId);
Cache cache = getCache("ExperimentResultTypeCache");
try {
List<ExperimentResultType> value = getCacheValue(cache, cacheKey);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
Connection conn = getConnection();
List<ExperimentResultType> ret = new ArrayList<ExperimentResultType>();
try {
pst = conn.prepareStatement("select * from exploded_statistics where bard_expt_id = ?");
pst.setLong(1, bardExptId);
ResultSet rs = pst.executeQuery();
while (rs.next()) {
ExperimentResultType rtype = new ExperimentResultType();
rtype.setName(rs.getString("display_name"));
rtype.setMin(rs.getFloat("minval"));
rtype.setMax(rs.getFloat("maxval"));
rtype.setNum(rs.getLong("n"));
rtype.setMean(rs.getFloat("mean"));
rtype.setSd(rs.getFloat("sd"));
rtype.setQ1(rs.getFloat("q1"));
rtype.setQ2(rs.getFloat("q2"));
rtype.setQ3(rs.getFloat("q3"));
rtype.setHistogram(getExperimentResultTypeHistogram(bardExptId, rtype.getName(), collapse));
ret.add(rtype);
}
rs.close();
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
cache.put(new Element(ret, cacheKey));
return ret;
}
/**
* Retrieve compounds associated with an experiment.
*
* @param bardExptId The experiment identifier
* @param skip how many records to skip
* @param top how many records to return
* @return A list of {@link Compound} objects
* @throws SQLException if an invalid limit specification is supplied or there is an error in the SQL query
*/
public List<Compound> getExperimentCompounds
(Long bardExptId, int skip, int top, boolean actives) throws SQLException {
if (bardExptId == null || bardExptId < 0) return null;
String cacheKey = bardExptId + "#" + skip + "#" + top + "#" + actives;
Cache cache = getCache("ExperimentCompoundsCache");
try {
List<Compound> value = getCacheValue(cache, cacheKey);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
String limitClause = generateLimitClause(skip, top);
PreparedStatement pst;
Connection conn = getConnection();
if (!actives)
pst = conn.prepareStatement("select cid, sid from bard_experiment_data where bard_expt_id = ? order by sid " + limitClause);
else
pst = conn.prepareStatement("select cid, sid from bard_experiment_data where bard_expt_id = ? and outcome = 2 order by sid " + limitClause);
try {
pst.setLong(1, bardExptId);
ResultSet rs = pst.executeQuery();
List<Compound> ret = new ArrayList<Compound>();
while (rs.next()) {
ret.addAll(getCompoundsByCid(rs.getLong("cid")));
}
rs.close();
cache.put(new Element(cacheKey, ret));
return ret;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
/**
* Retrieve substances associated with an assay.
*
* @param bardExptId The assay identifier
* @param skip how many records to skip
* @param top how many records to return
* @return A list of {@link Compound} objects
* @throws SQLException if an invalid limit specification is supplied or there is an error in the SQL query
*/
public List<Compound> getExperimentSubstances
(Long bardExptId, int skip, int top, boolean actives) throws SQLException {
if (bardExptId == null || bardExptId < 0) return null;
String cacheKey = bardExptId + "#" + skip + "#" + top + "#" + actives;
Cache cache = getCache("ExperimentSubstancesCache");
try {
List<Compound> value = getCacheValue(cache, cacheKey);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
String limitClause = generateLimitClause(skip, top);
PreparedStatement pst;
Connection conn = getConnection();
if (!actives)
pst = conn.prepareStatement("select cid, sid from bard_experiment_data where bard_expt_id = ? order by sid " + limitClause);
else
pst = conn.prepareStatement("select cid, sid from bard_experiment_data where bard_expt_id = ? and outcome = 2 order by sid " + limitClause);
try {
pst.setLong(1, bardExptId);
ResultSet rs = pst.executeQuery();
List<Compound> ret = new ArrayList<Compound>();
while (rs.next()) {
// TODO should return a Substance entity
ret.addAll(getCompoundsBySid(rs.getLong("sid")));
}
rs.close();
cache.put(new Element(cacheKey, ret));
return ret;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
/**
* Retrieve publications associated with a 'bard_assay_id'.
* <p/>
* This query requires that the publication details are available in the publication table.
*
* @param bardAssayId The bard assay id to query for
* @return a List of {@link Publication} objects
* @throws SQLException
*/
public List<Publication> getAssayPublications(Long bardAssayId) throws SQLException {
if (bardAssayId == null || bardAssayId <= 0) return null;
Cache cache = getCache("AssayPublicationsCache");
try {
List<Publication> value = getCacheValue(cache, bardAssayId);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
Connection conn = getConnection();
PreparedStatement pst2 = conn.prepareStatement("select a.* from publication a, assay_pub b where b.bard_assay_id = ? and b.pmid = a.pmid");
try {
pst2.setLong(1, bardAssayId);
ResultSet rs2 = pst2.executeQuery();
List<Publication> pubs = new ArrayList<Publication>();
while (rs2.next()) {
Publication p = new Publication();
p.setDoi(rs2.getString("doi"));
p.setTitle(rs2.getString("title"));
p.setPubmedId(rs2.getLong("pmid"));
p.setAbs(rs2.getString("abstract"));
pubs.add(p);
}
rs2.close();
cache.put(new Element(bardAssayId, pubs));
return pubs;
} finally {
//close resources
JDBCResourceCloser.close(pst2, conn);
}
}
/**
* Return a list of protein targets based on on a bard assay id
*
* @param bardAssayId
* @return
* @throws SQLException
*/
public List<ProteinTarget> getAssayTargets(Long bardAssayId)
throws SQLException {
Cache cache = getCache("AssayTargetsCache");
try {
List<ProteinTarget> value = getCacheValue(cache, bardAssayId);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
Connection conn = getConnection();
PreparedStatement pst2 = conn.prepareStatement("select distinct a.* from protein_target a, assay_target b where b.bard_assay_id = ? and a.gene_id = b.gene_id");
try {
pst2.setLong(1, bardAssayId);
ResultSet rs2 = pst2.executeQuery();
List<ProteinTarget> targets = new ArrayList<ProteinTarget>();
while (rs2.next()) {
String acc = rs2.getString("accession");
// targets.add(getProteinTargetByAccession(acc));
ProteinTarget t = new ProteinTarget();
t.setDescription(rs2.getString("description"));
t.setGeneId(rs2.getLong("gene_id"));
t.setName(rs2.getString("name"));
t.setStatus(rs2.getString("uniprot_status"));
t.setAcc(rs2.getString("accession"));
t.setTaxId(rs2.getLong("taxid"));
t.setClasses(getPantherClassesForAccession(t.getAcc()));
targets.add(t);
}
rs2.close();
cache.put(new Element(bardAssayId, targets));
return targets;
} finally {
//close resources
JDBCResourceCloser.close(pst2, conn);
}
}
/**
* Return a list of target biologies based on on a bard project id
*
* @param bardProjectid
* @return
* @throws SQLException
*/
public List<Biology> getProjectTargets(Long bardProjectid)
throws SQLException {
Cache cache = getCache("ProjectTargetsCache");
try {
List<Biology> value = getCacheValue(cache, bardProjectid);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
List<Biology> targets = getBiologyByEntity("project", bardProjectid);
cache.put(new Element(bardProjectid, targets));
return targets;
}
/**
* Retrieve assays based on query.
* <p/>
* Currently a crude query language is supported which requries you to specify the field
* to be queried on or if no field is specified then a full text search is applied to all
* text fields.
* <p/>
* Queries should in the form of query_string[field_name]
* <p/>
* This method is limited and should not be used. Instead consider the <code>/search</code>
* resource ({@link gov.nih.ncgc.bard.rest.BARDSearchResource})
*
* @param query the query to use
* @return A list of {@link Assay} objects, whuich may be empty if no assays match the query.
* @deprecated
*/
public List<Assay> searchForAssay(String query) throws SQLException {
Cache cache = getCache("SearchAssayCache");
try {
List<Assay> value = getCacheValue(cache, query);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
boolean freeTextQuery = false;
if (!query.contains("[")) freeTextQuery = true;
Connection conn = getConnection();
PreparedStatement pst = null;
if (freeTextQuery) {
String q = "%" + query + "%";
pst = conn.prepareStatement("select bard_assay_id from bard_assay where (name like ? or description like ? or source like ? or protocol like ?)");
pst.setString(1, q);
pst.setString(2, q);
pst.setString(3, q);
pst.setString(4, q);
pst.setString(5, q);
} else {
String[] toks = query.split("\\[");
String q = toks[0].trim();
String field = toks[1].trim().replace("]", "");
String sql = "select bard_assay_id from bard_assay where " + field + " like '%" + q + "%'";
pst = conn.prepareStatement(sql);
}
try {
ResultSet rs = pst.executeQuery();
List<Assay> assays = new ArrayList<Assay>();
while (rs.next()) {
Long aid = rs.getLong("bard_assay_id");
assays.add(getAssayByAid(aid));
}
rs.close();
cache.put(new Element(query, assays));
return assays;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public List<Assay> getAssaysByExperimentId(Long eid) throws SQLException {
Cache cache = getCache("AssaysByExperimentIdCache");
try {
List<Assay> value = getCacheValue(cache, eid);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement("select distinct bard_assay_id from bard_experiment where bard_expt_id = ?");
try {
pst.setLong(1, eid);
List<Assay> assays = new ArrayList<Assay>();
ResultSet rs = pst.executeQuery();
while (rs.next()) assays.add(getAssayByAid(rs.getLong(1)));
rs.close();
cache.put(new Element(eid, assays));
return assays;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
/**
* Returns assays for a given accession
*
* @param acc
* @return
* @throws SQLException
*/
public List<Assay> getAssaysByTargetAccession(String acc)
throws SQLException {
Cache cache = getCache("AssaysByTargetAccessionCache");
try {
List<Assay> value = getCacheValue(cache, acc);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
Connection conn = getConnection();
PreparedStatement pst = null;
try {
pst = conn.prepareStatement("select distinct b.bard_assay_id from protein_target a, assay_target b where a.accession = ? and a.accession = b.accession");
pst.setString(1, acc);
List<Assay> assays = new ArrayList<Assay>();
ResultSet rs = pst.executeQuery();
while (rs.next()) assays.add(getAssayByAid(rs.getLong(1)));
rs.close();
cache.put(new Element(acc, assays));
return assays;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
/**
* Returns assay for a given accession
*
* @param geneid
* @return
* @throws SQLException
*/
public List<Assay> getAssaysByTargetGeneid(Long geneid)
throws SQLException {
Cache cache = getCache("AssaysByTargetGeneidCache");
try {
List<Assay> value = getCacheValue(cache, geneid);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
Connection conn = getConnection();
PreparedStatement pst = null;
try {
pst = conn.prepareStatement("select distinct b.bard_assay_id from protein_target a, assay_target b where a.gene_id = ? and a.accession = b.accession");
pst.setLong(1, geneid);
List<Assay> assays = new ArrayList<Assay>();
ResultSet rs = pst.executeQuery();
while (rs.next()) assays.add(getAssayByAid(rs.getLong(1)));
rs.close();
cache.put(new Element(geneid, assays));
return assays;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public List<Long> getProjectIds() throws SQLException {
Cache cache = getCache("ProjectIdsCache");
try {
List<Long> value = getCacheValue(cache, "all");
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
Connection conn = getConnection();
PreparedStatement pst = null;
try {
pst = conn.prepareStatement("select bard_proj_id from bard_project");
ResultSet rs = pst.executeQuery();
List<Long> ret = new ArrayList<Long>();
while (rs.next()) {
ret.add(rs.getLong(1));
}
rs.close();
cache.put(new Element("all", ret));
return ret;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
/**
* Return a list of all aids.
*
* @return
* @throws SQLException
*/
public List<Long> getAssayCount() throws SQLException {
Cache cache = getCache("AssayCountCache");
try {
List<Long> value = getCacheValue(cache, "all");
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
Connection conn = getConnection();
PreparedStatement pst = null;
try {
pst = conn.prepareStatement("select bard_assay_id from bard_assay order by bard_assay_id");
ResultSet rs = pst.executeQuery();
List<Long> ret = new ArrayList<Long>();
while (rs.next()) {
ret.add(rs.getLong(1));
}
rs.close();
cache.put(new Element("all", ret));
return ret;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
/**
* Returns a list of all experiment ids.
*
* @return
* @throws SQLException
*/
/*
public List<Long> getExperimentIds() throws SQLException {
Cache cache = getCache ("ExperimentIdsCache");
List<Long> value = (List) getCacheValue (cache, "all");
if (value != null) {
return value;
}
PreparedStatement pst = conn.prepareStatement("select bard_expt_id from bard_experiment order by bard_expt_id");
try {
ResultSet rs = pst.executeQuery();
List<Long> ret = new ArrayList<Long>();
while (rs.next()) {
ret.add(rs.getLong("bard_expt_id"));
}
rs.close();
cache.put(new Element ("all", ret));
return ret;
}
finally {
pst.close();
}
}
*/
public Project getProject(Long bardProjId) throws SQLException {
Cache cache = getCache("ProjectCache");
try {
Project value = getCacheValue(cache, bardProjId);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
Project p = null;
Connection conn = getConnection();
PreparedStatement pst = null;
try {
pst = conn.prepareStatement("select * from bard_project where bard_proj_id = ?");
pst.setLong(1, bardProjId);
ResultSet rs = pst.executeQuery();
if (rs.next()) {
p = new Project();
p.setBardProjectId(bardProjId);
p.setDescription(rs.getString("description"));
p.setName(rs.getString("name"));
p.setDeposited(rs.getDate("deposited"));
p.setSource(rs.getString("source"));
p.setCapProjectId(rs.getLong("cap_proj_id"));
p.setScore(rs.getFloat("score"));
cache.put(new Element(bardProjId, p));
}
rs.close();
} finally {
//close resources
JDBCResourceCloser.close(pst);
}
if (p == null) {
return p;
}
// publications
try {
pst = conn.prepareStatement("select pmid from project_pub where bard_proj_id = ?");
pst.setLong(1, bardProjId);
List<Long> pubs = new ArrayList<Long>();
ResultSet rs = pst.executeQuery();
while (rs.next()) {
pubs.add(rs.getLong(1));
}
rs.close();
p.setPublications(pubs);
} finally {
//close resources
JDBCResourceCloser.close(pst);
}
// probe details
List<Long> probeIds = getProbeCidsForProject(bardProjId);
p.setProbeIds(probeIds);
p.setProbes(getCompoundsByCid(probeIds.toArray(new Long[]{})));
// find all experiments for this project
try {
pst = conn.prepareStatement("select bard_expt_id from bard_project_experiment where bard_proj_id = ?");
pst.setLong(1, bardProjId);
ResultSet rs = pst.executeQuery();
List<Long> eids = new ArrayList<Long>();
while (rs.next()) eids.add(rs.getLong(1));
rs.close();
p.setEids(eids);
} finally {
//close resources
JDBCResourceCloser.close(pst);
}
// find assays
try {
pst = conn.prepareStatement
("select distinct a.bard_assay_id from bard_experiment a, bard_project_experiment b " +
"where a.bard_expt_id=b.bard_expt_id and b.bard_proj_id = ?");
List<Long> aids = new ArrayList<Long>();
pst.setLong(1, bardProjId);
ResultSet rs = pst.executeQuery();
while (rs.next()) {
aids.add(rs.getLong(1));
}
rs.close();
p.setAids(aids);
} finally {
//close resources
JDBCResourceCloser.close(pst);
}
//find targets, get collected bard_assay_ids, for each bard_assay_id under the project
p.setTargets(getProjectTargets(bardProjId));
// experiment types - this can't go in Experiment, since the 'type' of the
// experiment depends on how it was used in a project
try {
pst = conn.prepareStatement("select * from bard_project_experiment where bard_proj_id = ?");
pst.setLong(1, bardProjId);
ResultSet rs = pst.executeQuery();
Map<Long, String> etypes = new HashMap<Long, String>();
while (rs.next()) etypes.put(rs.getLong("bard_expt_id"), rs.getString("expt_type"));
rs.close();
p.setExperimentTypes(etypes);
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
return p;
}
public List<Project> getProjects(Long... projectIds) throws SQLException {
List<Project> p = new ArrayList<Project>();
for (Long pid : projectIds) {
Project proj = getProject(pid);
if (proj != null) {
p.add(proj);
}
}
return p;
}
/**
* Returns a list of {@link Project} objects that are associated with an experiment.
* <p/>
* It is possible, that an experiment is not assigned to a project ("orphan"), in
* which case the project id is -1.
* <p/>
*
* @param bardExptId The experiment id
* @return A {@link Project} object
* @throws SQLException
*/
public List<Project> getProjectByExperimentId(Long bardExptId)
throws SQLException {
Cache cache = getCache("ProjectByExperimentIdCache");
try {
List<Project> value = getCacheValue(cache, bardExptId);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
Connection conn = getConnection();
PreparedStatement pst = null;
try {
pst = conn.prepareStatement("select bard_proj_id from bard_project_experiment where bard_expt_id = ?");
pst.setLong(1, bardExptId);
ResultSet rs = pst.executeQuery();
List<Project> ps = new ArrayList<Project>();
while (rs.next()) {
Project project = getProject(rs.getLong("bard_proj_id"));
if (project != null) ps.add(project);
}
rs.close();
cache.put(new Element(bardExptId, ps));
return ps;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public List<Long> getProjectIdByProbeId(String probeId) throws SQLException {
List<Long> ids = new ArrayList<Long>();
Connection conn = getConnection();
PreparedStatement pst = null;
try {
pst = conn.prepareStatement("select bard_proj_id from project_probe where probe_id = ?");
pst.setString(1, probeId);
ResultSet rs = pst.executeQuery();
while (rs.next()) ids.add(rs.getLong(1));
rs.close();
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
return ids;
}
public List<Project> getProjectByProbeId(String probeId)
throws SQLException {
Cache cache = getCache("ProjectByProbeIdCache");
try {
List<Project> value = getCacheValue(cache, probeId);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
Connection conn = getConnection();
PreparedStatement pst = null;
try {
pst = conn.prepareStatement("select bard_proj_id from project_probe where probe_id = ?");
pst.setString(1, probeId);
ResultSet rs = pst.executeQuery();
List<Project> ps = new ArrayList<Project>();
while (rs.next()) {
Project project = getProject(rs.getLong("bard_proj_id"));
if (project != null) ps.add(project);
}
rs.close();
cache.put(new Element(probeId, ps));
return ps;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
/**
* Returns the bard_project_ids for projects based on a bard_assay_id
*
* @param bardAssayId
* @return
* @throws SQLException
*/
public List<Project> getProjectByAssayId(Long bardAssayId)
throws SQLException {
Cache cache = getCache("ProjectByAssayIdCache");
try {
List<Project> value = getCacheValue(cache, bardAssayId);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
Connection conn = getConnection();
PreparedStatement pst = null;
try {
pst = conn.prepareStatement("select distinct b.bard_proj_id from bard_experiment a, bard_project_experiment b where a.bard_assay_id = ? and a.bard_expt_id = b.bard_expt_id");
pst.setLong(1, bardAssayId);
ResultSet rs = pst.executeQuery();
List<Long> pids = new ArrayList<Long>();
while (rs.next()) pids.add(rs.getLong("bard_proj_id"));
rs.close();
List<Project> projs = getProjects
(pids.toArray(new Long[pids.size()]));
cache.put(new Element(bardAssayId, projs));
return projs;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public List<Long> getProbeCidsForProject(Long bardProjectId)
throws SQLException {
Cache cache = getCache("ProbesForProjectCache");
try {
List<Long> value = getCacheValue(cache, bardProjectId);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
Connection conn = getConnection();
// PreparedStatement pst = conn.prepareStatement("select a.cid from bard_experiment_data a, compound b where b.probe_id is not null and a.bard_expt_id = ? and a.cid = b.cid");
PreparedStatement pst = conn.prepareStatement("select * from project_probe where bard_proj_id = ?");
try {
pst.setLong(1, bardProjectId);
ResultSet rs = pst.executeQuery();
List<Long> probeids = new ArrayList<Long>();
while (rs.next()) probeids.add(rs.getLong("cid"));
rs.close();
cache.put(new Element(bardProjectId, probeids));
return probeids;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
/* ****************/
/* Query methods */
/* ****************/
public List<ExperimentData> searchForExperimentData(String query, int skip, int top) throws SQLException, IOException {
Cache cache = getCache("SearchForExperimentDataCache");
try {
List<ExperimentData> value = getCacheValue(cache, query);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
boolean freeTextQuery = false;
if (!query.contains("[")) freeTextQuery = true;
Connection conn = getConnection();
PreparedStatement pst = null;
List<ExperimentData> experimentData = new ArrayList<ExperimentData>();
try {
if (freeTextQuery) {
return new ArrayList<ExperimentData>();
} else {
String[] toks = query.split("\\[");
String q = toks[0].trim();
String field = toks[1].trim().replace("]", "");
String sql = "select concat(cast(bard_expt_id as char), '.', cast(sid as char)) as id from bard_experiment_data where " + field + " = " + q + "";
pst = conn.prepareStatement(sql);
}
ResultSet rs = pst.executeQuery();
while (rs.next()) {
String exptId = rs.getString(1);
experimentData.add(getExperimentDataByDataId(exptId));
}
rs.close();
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
cache.put(new Element(query, experimentData));
return experimentData;
}
/**
* Get a count of the instances of an entity currently stored in the database.
*
* @param klass The class of the entity to be counted
* @return the count of the instances present
* @throws SQLException if there is an error in the query
*/
public <T extends BardEntity> int getEntityCount(Class<T> klass) throws SQLException {
Query queryParams;
if (fieldMap.containsKey(klass)) queryParams = fieldMap.get(klass);
else throw new IllegalArgumentException("Invalid entity class was specified");
String sql = "select count(" + queryParams.getIdField() + ") from " + queryParams.getTableName();
if (queryParams.getJoin() != null) {
sql += " where " + queryParams.getJoin();
}
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement(sql);
try {
ResultSet rs = pst.executeQuery();
int n = 0;
while (rs.next()) n = rs.getInt(1);
rs.close();
pst.close();
return (n);
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public <T extends BardEntity> int getEntityCount(Class<T> klass, String query) throws SQLException {
Query queryParams;
if (fieldMap.containsKey(klass)) queryParams = fieldMap.get(klass);
else throw new IllegalArgumentException("Invalid entity class was specified");
String sql;
if (query != null && !query.contains("[")) {
String q = "'%" + query + "%' ";
List<String> tmp = new ArrayList<String>();
for (String s : queryParams.getValidFields())
tmp.add(s + " like " + q);
String tmp2 = "";
if (!tmp.isEmpty())
tmp2 = "(" + Util.join(tmp, " or ") + ")";
sql = "select count(" + queryParams.getIdField() + ") from "
+ queryParams.getTableName() + " where ";
if (queryParams.getJoin() != null) {
sql += queryParams.getJoin() + " AND ";
}
sql += tmp2;
} else {
// TODO we currently only assume a single query field is specified
String[] toks = query.split("\\[");
String q = toks[0].trim();
String field = toks[1].trim().replace("]", "");
if (!queryParams.getValidFields().contains(field))
throw new SQLException("Invalid field was specified");
sql = "select count(" + queryParams.getIdField() + ") from "
+ queryParams.getTableName() + " where ";
if (queryParams.getJoin() != null) {
sql += queryParams.getJoin() + " AND ";
}
sql += field + " like '%" + q + "%'";
}
if (queryParams.getJoin() != null) {
sql += " where " + queryParams.getJoin();
}
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement(sql);
try {
ResultSet rs = pst.executeQuery();
int n = 0;
while (rs.next()) n = rs.getInt(1);
rs.close();
pst.close();
return (n);
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public int getCompoundTestCount() throws SQLException {
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement("select count(distinct cid) from bard_experiment_data");
ResultSet rs = pst.executeQuery();
try {
rs.next();
int n = rs.getInt(1);
rs.close();
return n;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public int getCompoundActiveCount() throws SQLException {
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement("select count(distinct cid) from bard_experiment_data where outcome = 2");
try {
ResultSet rs = pst.executeQuery();
rs.next();
int n = rs.getInt(1);
rs.close();
return n;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public int getSubstanceTestCount() throws SQLException {
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement("select count(distinct sid) from bard_experiment_data");
try {
ResultSet rs = pst.executeQuery();
rs.next();
int n = rs.getInt(1);
rs.close();
return n;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public int getSubstanceActiveCount() throws SQLException {
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement("select count(distinct sid) from bard_experiment_data where outcome = 2");
try {
ResultSet rs = pst.executeQuery();
rs.next();
int n = rs.getInt(1);
rs.close();
return n;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
private List<String> getCompoundAnnotationKeys() throws SQLException {
List<String> ret = new ArrayList<String>();
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement("select distinct annot_key from compound_annot order by annot_key");
try {
ResultSet rs = pst.executeQuery();
while (rs.next()) ret.add(rs.getString(1));
rs.close();
return ret;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
/**
* Return compounds based on a query.
*
* @param filter The filter, currently indicating active or tested compounds
* @param skip Number of results to skip
* @param top Number of results to return
* @param hasAnno if <code>true</code> only return compounds that have annotations, otherwise
* return all compounds satisfying the query
* @return a list of {@link Compound} objects
* @throws SQLException
*/
public List<Compound> searchForCompounds(String filter, int skip, int top, boolean hasAnno) throws SQLException {
List<String> annokeys = getCompoundAnnotationKeys();
List<SolrField> fields = new ArrayList<SolrField>();
for (String annokey : annokeys) {
fields.add(new SolrField(annokey, "string"));
}
fields.add(new SolrField("annotation", "text"));
fields.add(new SolrField("active", "text"));
fields.add(new SolrField("order", "text"));
List<Compound> ret = new ArrayList<Compound>();
String limitClause = generateLimitClause(skip, top);
boolean filterForActives = false;
// Map<String, List<String>> fqs = SearchUtil.extractFilterQueries(filter, fields);
// for (String fieldName : fqs.keySet()) {
// List<String> vals = fqs.get(fieldName);
// if (vals.size() == 0) continue;
//
// // handle outcome specially
// if (fieldName.equals("active") && vals.size() == 1) {
// filterForActives = true;
// } else if (hasExplodedResults && fieldName.equals("order") && vals.size() == 1) {
// String val= vals.get(0).toLowerCase();
// if (val.contains("\"asc")) orderClause = " order by value asc ";
// else if (val.contains("\"desc")) orderClause = " order by value desc ";
// else throw new SQLException("Invalid order specified. Must be asc or desc");
// } else if (hasExplodedResults) {
// // now deal with individual result types
// filterClause += " and display_name = '" + fieldName + "'";
// if (!vals.get(0).contains("[")) filterClause += " and value = " + vals.get(0) + " ";
// else { // provided a range
// String[] toks = vals.get(0).replace("[", "").replace("]", "").split(" TO ");
// String lower = toks[0];
// String upper = toks[1];
// if (lower.equals("*") && !upper.equals("*")) filterClause += " and value <= " + upper + " ";
// else if (!lower.equals("*") && upper.equals("*"))
// filterClause += " and value >= " + lower + " ";
// else if (!lower.equals("*") && !upper.equals("*"))
// filterClause += " and value >= " + lower + " and value <= " + upper + " ";
// }
// }
// }
String sql = "select distinct cid from bard_experiment_data order by cid " + limitClause;
if (filter.contains("active"))
sql = "select distinct cid from bard_experiment_data where outcome = 2 order by cid " + limitClause;
Cache cache = getCache("SearchForCompoundCache");
try {
List<Compound> value = getCacheValue(cache, sql);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
log.info("## SQL: " + sql);
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement(sql);
try {
ResultSet rs = pst.executeQuery();
while (rs.next()) {
if (!hasAnno) ret.addAll(getCompoundsByCid(rs.getLong(1)));
else {
List<Compound> cs = getCompoundsByCid(rs.getLong(1));
for (Compound c : cs) {
if (getCompoundAnnotations(c.getCid()).get("anno_key").length > 0) ret.add(c);
}
}
}
rs.close();
cache.put(new Element(sql, ret));
return ret;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
/**
* Get substances based on query string.
*
* @param filter the query string. Currently can be "tested" or "active", with the
* default being "tested"
* @param skip records to skip
* @param top number of records to return
* @param hasAnno ignored, since we don't deal with substance annotations
* @return
* @throws SQLException
*/
public List<Substance> searchForSubstances(String filter, int skip, int top, boolean hasAnno) throws SQLException {
List<Substance> ret = new ArrayList<Substance>();
String limitClause = generateLimitClause(skip, top);
String sql = "select distinct sid from bard_experiment_data order by sid " + limitClause;
if (filter != null && filter.contains("active"))
sql = "select distinct sid from bard_experiment_data where outcome = 2 order by sid " + limitClause;
Cache cache = getCache("SearchForSubstanceCache");
try {
List<Substance> value = getCacheValue(cache, sql);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
log.info("## SQL: " + sql);
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement(sql);
try {
ResultSet rs = pst.executeQuery();
while (rs.next()) {
ret.add(getSubstanceBySid(rs.getLong(1)));
}
rs.close();
cache.put(new Element(sql, ret));
return ret;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public <T extends BardEntity> List<Object> searchForEntityId(String query, int skip, int top, Class<T> klass)
throws SQLException, IOException {
Query queryParams;
if (fieldMap.containsKey(klass)) queryParams = fieldMap.get(klass);
else return new ArrayList<Object>();
String limitClause = generateLimitClause(skip, top);
PreparedStatement pst;
String sql;
if (query == null && top > 0) { // get all rows - caller had better implement paging
sql = "select " + queryParams.getIdField()
+ " from " + queryParams.getTableName();
if (queryParams.getJoin() != null) {
sql += " where " + queryParams.getJoin();
}
sql += " order by " + queryParams.getOrderField()
+ " " + limitClause;
} else if (query != null && !query.contains("[")) {
String q = "'%" + query + "%' ";
List<String> tmp = new ArrayList<String>();
for (String s : queryParams.getValidFields())
tmp.add(s + " like " + q);
String tmp2 = "";
if (!tmp.isEmpty())
tmp2 = "(" + Util.join(tmp, " or ") + ")";
sql = "select " + queryParams.getIdField() + " from "
+ queryParams.getTableName() + " where ";
if (queryParams.getJoin() != null) {
sql += queryParams.getJoin() + " AND ";
}
sql += tmp2 + " order by " + queryParams.getOrderField()
+ " " + limitClause;
} else {
// TODO we currently only assume a single query field is specified
String[] toks = query.split("\\[");
String q = toks[0].trim();
String field = toks[1].trim().replace("]", "");
if (!queryParams.getValidFields().contains(field))
throw new SQLException("Invalid field was specified");
sql = "select " + queryParams.getIdField() + " from "
+ queryParams.getTableName() + " where ";
if (queryParams.getJoin() != null) {
sql += queryParams.getJoin() + " AND ";
}
sql += field + " like '%" + q + "%' order by "
+ queryParams.getOrderField() + " " + limitClause;
}
Cache cache = getCache("SearchForEntityIdCache");
try {
List<Object> value = getCacheValue(cache, sql);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
log.info("## searchForEntity SQL: " + sql);
System.out.println("## searchForEntity SQL: " + sql);
Connection conn = getConnection();
pst = conn.prepareStatement(sql);
List<Object> idlist = new ArrayList<Object>();
try {
ResultSet rs = pst.executeQuery();
while (rs.next()) {
Object id = rs.getObject(queryParams.getIdField());
idlist.add(id);
}
rs.close();
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
cache.put(new Element(sql, idlist));
return idlist;
}
/**
* Search for entities.
* <p/>
* The <code>skip</code> and <code>top</code> arguments can be used to
* implement paging. This implies that the SQL query orders the result
* and this is currently pre-defined by the API.
*
* @param query The query string, possible suffixed by search fields. If <code>null</code>
* the method returns all entities available. In such a case, the <code>skip</code>
* and <code>top</code> parameters should be specified (though this is not currently
* enforce)
* @param skip How many entities to skip
* @param top How many entities to return
* @param klass The class of the entity desired
* @return A list of entities matching the query
* @throws SQLException if there is an error during query
* @throws IOException if there is an error during query
*/
public <T extends BardEntity> List<T> searchForEntity(String query, int skip, int top, Class<T> klass) throws SQLException, IOException {
Query queryParams;
if (fieldMap.containsKey(klass)) queryParams = fieldMap.get(klass);
else return new ArrayList<T>();
String limitClause = generateLimitClause(skip, top);
PreparedStatement pst;
String sql;
if (query == null && top > 0) { // get all rows - caller had better implement paging
sql = "select " + queryParams.getIdField()
+ " from " + queryParams.getTableName();
if (queryParams.getJoin() != null) {
sql += " where " + queryParams.getJoin();
}
sql += " order by " + queryParams.getOrderField()
+ " " + limitClause;
} else if (query != null && !query.contains("[")) {
String q = "'%" + query + "%' ";
List<String> tmp = new ArrayList<String>();
for (String s : queryParams.getValidFields())
tmp.add(s + " like " + q);
String tmp2 = "";
if (!tmp.isEmpty())
tmp2 = "(" + Util.join(tmp, " or ") + ")";
sql = "select " + queryParams.getIdField() + " from "
+ queryParams.getTableName() + " where ";
if (queryParams.getJoin() != null) {
sql += queryParams.getJoin() + " AND ";
}
sql += tmp2 + " order by " + queryParams.getOrderField()
+ " " + limitClause;
} else {
// TODO we currently only assume a single query field is specified
String[] toks = query.split("\\[");
String q = toks[0].trim();
String field = toks[1].trim().replace("]", "");
if (!queryParams.getValidFields().contains(field))
throw new SQLException("Invalid field was specified");
sql = "select " + queryParams.getIdField() + " from "
+ queryParams.getTableName() + " where ";
if (queryParams.getJoin() != null) {
sql += queryParams.getJoin() + " AND ";
}
sql += field + " like '%" + q + "%' order by "
+ queryParams.getOrderField() + " " + limitClause;
}
Cache cache = getCache("SearchForEntityCache");
try {
List<T> value = getCacheValue(cache, sql);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
log.info("## SQL: " + sql);
System.out.println("## searchForEntity SQL: " + sql);
Connection conn = getConnection();
pst = conn.prepareStatement(sql);
List<T> entities = new ArrayList<T>();
try {
ResultSet rs = pst.executeQuery();
while (rs.next()) {
Object id = rs.getObject(queryParams.getIdField());
Object entity = null;
if (klass.equals(Publication.class)) entity = getPublicationByPmid((Long) id);
if (klass.equals(Biology.class)) entity = getBiologyBySerial((Long) id);
else if (klass.equals(ProteinTarget.class)) entity = getProteinTargetByAccession((String) id);
else if (klass.equals(Project.class)) entity = getProject((Long) id);
else if (klass.equals(Experiment.class)) entity = getExperimentByExptId((Long) id);
else if (klass.equals(Compound.class)) entity = getCompoundsByCid((Long) id);
else if (klass.equals(Probe.class)) entity = getCompoundsByCid((Long) id);
else if (klass.equals(Substance.class)) entity = getSubstanceBySid((Long) id);
else if (klass.equals(Assay.class)) entity = getAssayByAid((Long) id);
else if (klass.equals(ETag.class)) entity = getEtagByEtagId((String) id);
if (entity != null) {
if (entity instanceof List) entities.addAll((Collection<T>) entity);
else if (entity instanceof BardEntity) entities.add((T) entity);
}
}
rs.close();
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
cache.put(new Element(sql, entities));
return entities;
}
public <T extends BardEntity> List<T> getEntitiesByEtag(String etag, int skip, int top) throws SQLException {
return getEntitiesByEtag(getEtagByEtagId(etag), skip, top);
}
public <T extends BardEntity> List<T> getEntitiesByEtag(ETag etag, int skip, int top) throws SQLException {
List<T> entities = new ArrayList<T>();
if (Assay.class.getName().equals(etag.getType()))
entities = (List<T>) getAssaysByETag(skip, top, etag.getEtag());
else if (Compound.class.getName().equals(etag.getType()))
entities = (List<T>) getCompoundsByETag(skip, top, etag.getEtag());
else if (Substance.class.getName().equals(etag.getType()))
entities = (List<T>) getSubstanceByETag(skip, top, etag.getEtag());
else if (Experiment.class.getName().equals(etag.getType()))
entities = (List<T>) getExperimentsByETag(skip, top, etag.getEtag());
else if (Project.class.getName().equals(etag.getType()))
entities = (List<T>) getProjectsByETag(skip, top, etag.getEtag());
return entities;
}
/*
* Return all known ETag's for a given principal
*/
public List<String> getETagsForEntity(int skip, int top,
Principal principal,
Class<? extends BardEntity> clazz)
throws SQLException {
String limits = "";
if (skip >= 0 && top > 0) {
limits = " limit " + skip + "," + top;
} else if (top > 0) {
limits = " limit " + top;
}
/*
* TODO: we should do proper checking of principal here!
*/
String sql = "select etag_id from etag where status = 1";
PreparedStatement pst;
Connection conn = getConnection();
if (clazz != null) {
pst = conn.prepareStatement(sql + " and type = ?" + limits);
pst.setString(1, clazz.getName());
} else {
pst = conn.prepareStatement(sql + limits);
}
try {
List<String> etags = new ArrayList<String>();
ResultSet rs = pst.executeQuery();
while (rs.next()) {
String id = rs.getString(1);
etags.add(id);
}
rs.close();
return etags;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
/**
* **********************************************************************
* <p/>
* CAP related methods (dictionary, annotations)
* <p/>
* ************************************************************************
*/
private List<CAPAnnotation> convertKeggToAnno(ResultSet rs, String entity, Integer entityId) throws SQLException {
List<CAPAnnotation> annos = new ArrayList<CAPAnnotation>();
while (rs.next()) {
String[] toks;
String diseaseName = rs.getString("disease_names");
String diseaseCat = rs.getString("disease_category");
String diseaseId = rs.getString("disease_id");
String url = "http://www.kegg.jp/medicus-bin/search?q=" + diseaseId + "&display=disease&from=disease";
CAPAnnotation anno = new CAPAnnotation(null,
entityId.intValue(),
diseaseName, null,
"keggdiseaseid", diseaseId,
diseaseId, "KEGG",
url, -1, entity,
diseaseCat, null);
annos.add(anno);
}
return annos;
}
private List<CAPAnnotation> convertGoToAnno(ResultSet rs, String entity, Integer entityId) throws SQLException {
List<CAPAnnotation> annos = new ArrayList<CAPAnnotation>();
while (rs.next()) {
String term = rs.getString("go_term");
String goid = rs.getString("go_id");
String gotype = rs.getString("go_type");
String targetAcc = rs.getString("target_acc");
String assoc = rs.getString("go_assoc_db_ref");
String evCode = rs.getString("ev_code");
assoc = assoc == null ? "" : assoc;
String related = "target=" + targetAcc + ",gotype=" + gotype + ",evcode=" + evCode + ",ev=" + assoc;
// work out the direct parent of an annotation
// In go_term2term, term1_id is id of the parent term and term2_id is id of the child term.
// Since we want the parent of the current term, it is the child
StringBuilder parentId = new StringBuilder();
// String delim = "";
// PreparedStatement pst = conn.prepareStatement("select acc from go_term where id in (select term1_id from go_term2term a, go_term b where b.acc = ? and a.term2_id = b.id)");
// pst.setString(1, goid);
// ResultSet trs = pst.executeQuery();
// while (trs.next()) {
// parentId.append(delim).append(trs.getString("acc"));
// delim = ",";
// }
// pst.close();
related += ",parentid=" + parentId;
CAPAnnotation anno = new CAPAnnotation(null,
entityId.intValue(),
term, null,
"goid", goid,
goid, "GO",
"http://amigo.geneontology.org/cgi-bin/amigo/term_details?term=" + goid, -1, entity,
related, null);
annos.add(anno);
}
return annos;
}
/**
* Get annotations for an assay.
* <p/>
* The assay tables currently use Pubchem AID as the primary identifier, whereas
* CAP annotations use the CAP assay ID to refer to assays. Thus when retrieving
* annotations (at least from CAP annotations on CAP assays), we must map Pubchem
* AID to CAP AID.
* <p/>
* Currently the annotations are restricted to CAP derived annotations only.
*
* @param bardAssayId The assay identifier. This is currently a BARD assay identifier.
* @return A list of assay annotations
* @throws SQLException
*/
public List<CAPAnnotation> getAssayAnnotations(Long bardAssayId) throws SQLException {
Cache cache = getCache("AssayAnnotationsCache");
try {
List<CAPAnnotation> value = getCacheValue
(cache, bardAssayId);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement("select a.* from cap_annotation a where a.entity = 'assay' and a.entity_id = ?");
PreparedStatement gopst = conn.prepareStatement("select * from go_assay where bard_assay_id = ? and implied = 0 order by go_type");
PreparedStatement keggpst = conn.prepareStatement("select a.* from kegg_gene2disease a, (select distinct um.acc as gene_id from bard_biology a, uniprot_map um where a.entity = 'assay' and a.entity_id = ? and a.biology_dict_id = 1398 and um.uniprot_acc = a.ext_id and acc_type = 'GeneID' union select distinct ext_id as gene_id from bard_biology a where a.entity = 'assay' and a.entity_id = ? and a.biology_dict_id = 880) t where t.gene_id = a.gene_id");
try {
pst.setLong(1, bardAssayId);
ResultSet rs = pst.executeQuery();
List<CAPAnnotation> annos = new ArrayList<CAPAnnotation>();
while (rs.next()) {
String anno_id = rs.getString("anno_id");
String anno_key = rs.getString("anno_key");
String anno_value = rs.getString("anno_value");
String anno_display = rs.getString("anno_display");
String anno_value_text = rs.getString("anno_value_text");
int displayOrder = rs.getInt("display_order");
String source = rs.getString("source");
String entity = rs.getString("entity");
String url = rs.getString("url");
String contextName = rs.getString("context_name");
String contextGroup = rs.getString("context_group");
String related = rs.getString("related");
String extValueId = null;
if (related != null && !related.trim().equals("")) {
String[] toks = related.split("\\|");
if (toks.length == 2) extValueId = toks[1];
}
if (extValueId == null && anno_value_text != null) extValueId = anno_value_text;
// TODO Updated the related annotations field to support grouping
CAPAnnotation anno = new CAPAnnotation(Integer.parseInt(anno_id), null,
anno_display, contextName, anno_key, anno_value,
extValueId, source, url, displayOrder, entity, related, contextGroup);
annos.add(anno);
}
rs.close();
// now pull in GO annotations and create CAPAnnotation objects from them
gopst.setLong(1, bardAssayId);
rs = gopst.executeQuery();
annos.addAll(convertGoToAnno(rs, "assay", bardAssayId.intValue()));
rs.close();
// pull in KEGG disease annotations
keggpst.setLong(1, bardAssayId);
keggpst.setLong(2, bardAssayId);
rs = keggpst.executeQuery();
annos.addAll(convertKeggToAnno(rs, "assay", bardAssayId.intValue()));
rs.close();
keggpst.close();
cache.put(new Element(bardAssayId, annos));
return annos;
} finally {
//close resources
JDBCResourceCloser.close(pst, gopst, keggpst);
JDBCResourceCloser.close(conn);
}
}
public List<CAPAnnotation> getExperimentAnnotations(Long bardExptId) throws SQLException {
Cache cache = getCache("ExperimentAnnotationsCache");
try {
List<CAPAnnotation> value = getCacheValue
(cache, bardExptId);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement("select a.* from cap_annotation a where a.entity = 'experiment' and a.entity_id = ?");
try {
pst.setLong(1, bardExptId);
ResultSet rs = pst.executeQuery();
List<CAPAnnotation> annos = new ArrayList<CAPAnnotation>();
while (rs.next()) {
String anno_id = rs.getString("anno_id");
String anno_key = rs.getString("anno_key");
String anno_value = rs.getString("anno_value");
String anno_display = rs.getString("anno_display");
String anno_value_text = rs.getString("anno_value_text");
int displayOrder = rs.getInt("display_order");
String source = rs.getString("source");
String entity = rs.getString("entity");
String url = rs.getString("url");
String contextName = rs.getString("context_name");
String contextGroup = rs.getString("context_group");
String related = rs.getString("related");
String extValueId = null;
if (related != null && !related.trim().equals("")) {
String[] toks = related.split("\\|");
if (toks.length == 2) extValueId = toks[1];
}
if (extValueId == null && anno_value_text != null) extValueId = anno_value_text;
// TODO Updated the related annotations field to support grouping
CAPAnnotation anno = new CAPAnnotation(Integer.parseInt(anno_id), null,
anno_display, contextName, anno_key, anno_value,
extValueId, source, url, displayOrder, entity, related, contextGroup);
annos.add(anno);
}
rs.close();
cache.put(new Element(bardExptId, annos));
return annos;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public List<CAPAnnotation> getProjectAnnotations(Long bardProjectId)
throws SQLException {
Cache cache = getCache("ProjectAnnotationsCache");
try {
List<CAPAnnotation> value =
getCacheValue(cache, bardProjectId);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement("select a.* from cap_project_annotation a, bard_project b where b.bard_proj_id = ? and a.cap_proj_id = b.cap_proj_id");
PreparedStatement gopst = conn.prepareStatement("select * from go_project where bard_proj_id = ? and implied = 0 order by go_type");
// ensure we select biologies that used Entrez Gene ID
PreparedStatement keggpst = conn.prepareStatement("select a.* from kegg_gene2disease a, (select distinct um.acc as gene_id from bard_biology a, uniprot_map um where a.entity = 'project' and a.entity_id = ? and a.biology_dict_id = 1398 and um.uniprot_acc = a.ext_id and acc_type = 'GeneID' union select distinct ext_id as gene_id from bard_biology a where a.entity = 'project' and a.entity_id = ? and a.biology_dict_id = 880) t where t.gene_id = a.gene_id");
try {
pst.setLong(1, bardProjectId);
ResultSet rs = pst.executeQuery();
List<CAPAnnotation> annos = new ArrayList<CAPAnnotation>();
while (rs.next()) {
String anno_id = rs.getString("anno_id");
String anno_key = rs.getString("anno_key");
String anno_value = rs.getString("anno_value");
String anno_display = rs.getString("anno_display");
String source = rs.getString("source");
int displayOrder = rs.getInt("display_order");
String entity = rs.getString("entity");
String contextRef = rs.getString("context_name");
String contextGroup = rs.getString("context_group");
String url = rs.getString("url");
String related = rs.getString("related");
String extValueId = null;
if (related != null && !related.trim().equals("")) {
String[] toks = related.split("\\|");
if (toks.length == 2) extValueId = toks[1];
}
CAPAnnotation anno = new CAPAnnotation(Integer.parseInt(anno_id), null,
anno_display, contextRef, anno_key, anno_value,
extValueId, source, url, displayOrder, entity, related, contextGroup);
annos.add(anno);
}
rs.close();
// now pull in GO annotations and create CAPAnnotation objects from them
gopst.setLong(1, bardProjectId);
rs = gopst.executeQuery();
annos.addAll(convertGoToAnno(rs, "project", bardProjectId.intValue()));
rs.close();
// deal with KEGG annotations
keggpst.setLong(1, bardProjectId);
keggpst.setLong(2, bardProjectId);
rs = keggpst.executeQuery();
annos.addAll(convertKeggToAnno(rs, "project", bardProjectId.intValue()));
rs.close();
keggpst.close();
cache.put(new Element(bardProjectId, annos));
return annos;
} finally {
//close resources
JDBCResourceCloser.close(pst, gopst, keggpst);
JDBCResourceCloser.close(conn);
}
}
public CAPDictionary getCAPDictionary()
throws SQLException, IOException, ClassNotFoundException {
Cache cache = getCache("CAPDictionaryCache");
try {
CAPDictionary cap = getCacheValue(cache, "cap");
if (cap != null) {
return cap;
}
} catch (ClassCastException ex) {
log.warning("** Cache miss due to ClassLoader changed");
}
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement("select dict, ins_date from cap_dict_obj order by ins_date desc");
try {
ResultSet rs = pst.executeQuery();
Object obj = null;
if (rs.next()) {
byte[] buf = rs.getBytes(1);
log.info("Retrived CAP dictionary blob with ins_date = "
+ rs.getDate(2));
ObjectInputStream objectIn = null;
if (buf != null) {
objectIn = new ObjectInputStream(new ByteArrayInputStream(buf));
obj = objectIn.readObject();
}
}
rs.close();
if (!(obj instanceof CAPDictionary)) return null;
cache.put(new Element("cap", obj));
return (CAPDictionary) obj;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
/**
* Get an estimated of the rows to be returned by a query.
* <p/>
* This obtains a rough row count via MySQL's EXPLAIN functionality
*
* @param query The SQL query
* @return the number of estimated rows
* @throws SQLException
*/
public int getEstimatedRowCount(String query) throws SQLException {
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement(query);
int nrow = -1;
try {
ResultSet rs = pst.executeQuery();
while (rs.next()) {
nrow = rs.getInt("rows");
}
rs.close();
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
return nrow;
}
/**
* Return a list of entities in which the specified CID is active.
* <p/>
* In general this is based on the experiment that the CID is active in
*
* @param cid
* @param entity
* @param skip
* @param top
* @param <T>
* @return
* @throws SQLException
*/
public <T> List<T> getEntitiesByActiveCid
(Long cid, Class<T> entity, Integer skip, Integer top)
throws SQLException {
String sql = null;
PreparedStatement pst;
if (cid == null || cid < 0) return null;
String limitClause = generateLimitClause(skip, top);
if (entity.isAssignableFrom(Assay.class)) {
sql = "select distinct b.bard_assay_id from bard_experiment_data a, bard_experiment b where a.cid = ? and a.bard_expt_id = b.bard_expt_id and a.outcome = 2 order by a.classification desc, score desc " + limitClause;
} else if (entity.isAssignableFrom(Project.class)) {
// JB: original sql joined compound and used the proj_id in experiment which no longer exists since one experiment can have multiple projects
// It also used a nested select.
// I'll leave this here for review in case the new query doesn't perform as expected
//
// sql = "select p.bard_proj_id from project p, bard_experiment e where e.bard_expt_id in " +
// "(select distinct ed.bard_expt_id from bard_experiment_data ed, bard_experiment e, compound a " +
// "where a.cid = ? and ed.cid = a.cid and ed.bard_expt_id = e.bard_expt_id) and e.proj_id = p.proj_id";
//new query: uses bard_project, doesn't join with compound
sql = "select distinct(pe.bard_proj_id) from bard_experiment_data ed, bard_project_experiment pe " +
"where ed.cid = ? and pe.bard_expt_id=ed.bard_expt_id and ed.outcome = 2 order by ed.classification desc, score desc " + limitClause;
} else if (entity.isAssignableFrom(Substance.class)) {
sql = "select a.sid from cid_sid a, bard_experiment_data b where a.cid = ? and a.cid = b.cid and b.outcome = 2 order by classification desc, score desc " + limitClause;
} else if (entity.isAssignableFrom(ExperimentData.class)) {
sql = "select concat(cast(bard_expt_id as char), '.', cast(sid as char)) as id from bard_experiment_data where cid = ? and outcome = 2 order by expt_data_id order by classification desc, score desc " + limitClause;
} else if (entity.isAssignableFrom(Experiment.class)) {
sql = "select distinct bard_expt_id from bard_experiment_data where cid = ? and outcome = 2 order by classification desc, score desc " + limitClause;
}
Cache cache = getCache("EntitiesByActiveCid::" + entity.getClass());
try {
List<T> value = (List) getCacheValue(cache, cid);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
Connection conn = getConnection();
pst = conn.prepareStatement(sql);
try {
pst.setLong(1, cid);
ResultSet rs = pst.executeQuery();
List<T> ret = new ArrayList<T>();
while (rs.next()) {
Long id = rs.getLong(1);
if (entity.isAssignableFrom(Assay.class)) ret.add((T) getAssayByAid(id));
else if (entity.isAssignableFrom(Project.class)) ret.add((T) getProject(id));
else if (entity.isAssignableFrom(Substance.class)) ret.add((T) getSubstanceBySid(id));
else if (entity.isAssignableFrom(Experiment.class)) ret.add((T) getExperimentByExptId(id));
else if (entity.isAssignableFrom(ExperimentData.class))
ret.add((T) getExperimentDataByDataId(rs.getString(1)));
}
rs.close();
cache.put(new Element(cid, ret));
return ret;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public <T> List<T> getRecentEntities(Class<T> entity, Integer n) throws SQLException {
if (n == null || n <= 0) n = 5;
String sql = null;
PreparedStatement pst;
String limitClause = " limit " + n;
if (entity.isAssignableFrom(Assay.class)) {
sql = "select bard_assay_id from bard_assay order by updated desc ";
} else if (entity.isAssignableFrom(Project.class)) {
sql = "select bard_proj_id from bard_project order by updated desc ";
} else if (entity.isAssignableFrom(Experiment.class)) {
sql = "select bard_expt_id from bard_experiment order by updated desc";
} else if (entity.isAssignableFrom(Substance.class)) {
sql = "select sid from substance order by updated desc";
} else if (entity.isAssignableFrom(Biology.class)) {
sql = "select serial from bard_biology order by updated desc";
} else if (entity.isAssignableFrom(Probe.class)) {
sql = "select cid from compound where probe_id is not null and compound_class = 'ML Probe' order by updated desc";
}
sql += limitClause;
Connection conn = getConnection();
pst = conn.prepareStatement(sql);
try {
ResultSet rs = pst.executeQuery();
List<T> ret = new ArrayList<T>();
while (rs.next()) {
Long id = rs.getLong(1);
if (entity.isAssignableFrom(Assay.class)) ret.add((T) getAssayByAid(id));
else if (entity.isAssignableFrom(Project.class)) ret.add((T) getProject(id));
else if (entity.isAssignableFrom(Substance.class)) ret.add((T) getSubstanceBySid(id));
else if (entity.isAssignableFrom(Experiment.class)) ret.add((T) getExperimentByExptId(id));
else if (entity.isAssignableFrom(Biology.class)) ret.add((T) getBiologyBySerial(id).get(0));
else if (entity.isAssignableFrom(Probe.class)) {
List<Compound> cmpds = getCompoundsByCid(id);
if (cmpds != null && cmpds.size() > 0) ret.add((T) cmpds.get(0));
}
}
rs.close();
return ret;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public <T> List<T> getEntitiesByCid(Long cid, Class<T> entity, Integer skip, Integer top) throws SQLException {
String sql = null;
PreparedStatement pst;
if (cid == null || cid < 0) return null;
String limitClause = generateLimitClause(skip, top);
if (entity.isAssignableFrom(Assay.class)) {
sql = "select distinct b.bard_assay_id "
+ "from bard_experiment_data a, bard_experiment b "
+ "where a.cid = ? and a.bard_expt_id = b.bard_expt_id "
+ "order by a.classification desc, score desc "
+ limitClause;
} else if (entity.isAssignableFrom(Project.class)) {
// JB: original sql joined compound and used the proj_id in experiment which no longer exists since one experiment can have multiple projects
// It also used a nested select.
// I'll leave this here for review in case the new query doesn't perform as expected
//
// sql = "select p.bard_proj_id from project p, bard_experiment e where e.bard_expt_id in " +
// "(select distinct ed.bard_expt_id from bard_experiment_data ed, bard_experiment e, compound a " +
// "where a.cid = ? and ed.cid = a.cid and ed.bard_expt_id = e.bard_expt_id) and e.proj_id = p.proj_id";
//new query: uses bard_project, doesn't join with compound
sql = "select distinct(pe.bard_proj_id) "
+ "from bard_experiment_data ed,bard_project_experiment pe "
+ "where ed.cid = ? and pe.bard_expt_id=ed.bard_expt_id "
+ "and pe.bard_proj_id > 0 "
+ "order by ed.classification desc, score desc "
+ limitClause;
} else if (entity.isAssignableFrom(Substance.class)) {
sql = "select sid from cid_sid where cid = ? order by sid " + limitClause;
} else if (entity.isAssignableFrom(ExperimentData.class)) {
sql = "select concat(cast(bard_expt_id as char), '.', cast(sid as char)) as id from bard_experiment_data where cid = ? order by classification desc, score desc " + limitClause;
} else if (entity.isAssignableFrom(Experiment.class)) {
sql = "select distinct bard_expt_id from bard_experiment_data where cid = ? order by classification desc, score desc " + limitClause;
} else {
throw new IllegalArgumentException
("Unsupported entity class: " + entity);
}
Cache cache = getCache("EntitiesByCidCache::" + entity.getName());
try {
List<T> value = (List<T>) getCacheValue(cache, cid);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
Connection conn = getConnection();
pst = conn.prepareStatement(sql);
try {
pst.setLong(1, cid);
ResultSet rs = pst.executeQuery();
List<T> ret = new ArrayList<T>();
while (rs.next()) {
if (entity.isAssignableFrom(Assay.class)) ret.add((T) getAssayByAid(rs.getLong(1)));
else if (entity.isAssignableFrom(Project.class)) ret.add((T) getProject(rs.getLong(1)));
else if (entity.isAssignableFrom(Substance.class)) ret.add((T) getSubstanceBySid(rs.getLong(1)));
else if (entity.isAssignableFrom(Experiment.class)) ret.add((T) getExperimentByExptId(rs.getLong(1)));
else if (entity.isAssignableFrom(ExperimentData.class))
ret.add((T) getExperimentDataByDataId(rs.getString(1)));
}
rs.close();
pst.close();
cache.put(new Element(cid, ret));
return ret;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public <T> Integer getEntityCountByCid(Long cid, Class<T> entity) throws SQLException {
String sql = null;
PreparedStatement pst;
if (cid == null || cid < 0) return null;
if (entity.isAssignableFrom(Assay.class)) {
sql = "select count(distinct b.bard_assay_id) "
+ "from bard_experiment_data a, bard_experiment b "
+ "where a.cid = ? and a.bard_expt_id = b.bard_expt_id "
+ "order by a.classification desc, score desc ";
} else if (entity.isAssignableFrom(Project.class)) {
sql = "select count(distinct(pe.bard_proj_id)) "
+ "from bard_experiment_data ed,bard_project_experiment pe "
+ "where ed.cid = ? and pe.bard_expt_id=ed.bard_expt_id "
+ "and pe.bard_proj_id > 0 "
+ "order by ed.classification desc, score desc ";
} else if (entity.isAssignableFrom(Substance.class)) {
sql = "select count(sid) from cid_sid where cid = ? order by sid ";
} else if (entity.isAssignableFrom(ExperimentData.class)) {
sql = "select count(concat(cast(bard_expt_id as char), '.', cast(sid as char))) as id from bard_experiment_data where cid = ? order by classification desc, score desc ";
} else if (entity.isAssignableFrom(Experiment.class)) {
sql = "select count(distinct bard_expt_id) from bard_experiment_data where cid = ? order by classification desc, score desc ";
}
String cacheName = "Class";
if (entity.isAssignableFrom(Assay.class)) cacheName = "Assay";
else if (entity.isAssignableFrom(Project.class)) cacheName = "Project";
else if (entity.isAssignableFrom(Substance.class)) cacheName = "Substance";
else if (entity.isAssignableFrom(Experiment.class)) cacheName = "Experiment";
else if (entity.isAssignableFrom(ExperimentData.class)) cacheName = "ExperimentData";
Cache cache = getCache("EntityCountByCidCache::" + cacheName);
try {
Integer value = getCacheValue(cache, cid);
if (value != null) return value;
} catch (ClassCastException ignored) {
}
Connection conn = getConnection();
pst = conn.prepareStatement(sql);
try {
pst.setLong(1, cid);
ResultSet rs = pst.executeQuery();
rs.next();
Integer ret = rs.getInt(1);
pst.close();
rs.close();
cache.put(new Element(cid, ret));
return ret;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public <T> Integer getEntityCountByActiveCid(Long cid, Class<T> entity)
throws SQLException {
String sql = null;
PreparedStatement pst;
if (entity.isAssignableFrom(Assay.class)) {
sql = "select count(distinct b.bard_assay_id) from bard_experiment_data a, bard_experiment b where a.cid = ? and a.bard_expt_id = b.bard_expt_id and a.outcome = 2 order by a.classification desc, score desc ";
} else if (entity.isAssignableFrom(Project.class)) {
sql = "select count(distinct(pe.bard_proj_id)) from bard_experiment_data ed, bard_project_experiment pe " +
"where ed.cid = ? and pe.bard_expt_id=ed.bard_expt_id and ed.outcome = 2 order by ed.classification desc, score desc ";
} else if (entity.isAssignableFrom(Substance.class)) {
sql = "select count(a.sid) from cid_sid a, bard_experiment_data b where a.cid = ? and a.cid = b.cid and b.outcome = 2 order by classification desc, score desc ";
} else if (entity.isAssignableFrom(ExperimentData.class)) {
sql = "select count(concat(cast(bard_expt_id as char), '.', cast(sid as char))) as id from bard_experiment_data where cid = ? and outcome = 2 order by expt_data_id order by classification desc, score desc ";
} else if (entity.isAssignableFrom(Experiment.class)) {
sql = "select count(distinct bard_expt_id) from bard_experiment_data where cid = ? and outcome = 2 order by classification desc, score desc ";
}
Cache cache = getCache("EntityCountByActiveCid::" + entity.getClass());
try {
Integer value = getCacheValue(cache, cid);
if (value != null) return value;
} catch (ClassCastException ignored) {
}
Connection conn = getConnection();
pst = conn.prepareStatement(sql);
try {
pst.setLong(1, cid);
ResultSet rs = pst.executeQuery();
rs.next();
Integer ret = rs.getInt(1);
rs.close();
cache.put(new Element(cid, ret));
return ret;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public Map<String, Object> getProjectSumary(Long projectId) throws SQLException {
Cache cache = getCache("ProjectSummaryCache");
try {
Map<String, Object> value = getCacheValue(cache, projectId);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
Project project = getProject(projectId);
if (project == null || project.getBardProjectId() == null)
return null;
int pcount = 0, syncount = 0, nassay = 0;
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement("select sum(a.purchased_count) as pcount, sum(a.synthesized_count) as scount from bard_experiment a join bard_project_experiment b on a.bard_expt_id=b.bard_expt_id where b.bard_proj_id = ?");
List<Experiment> expts = new ArrayList<Experiment>();
try {
pst.setLong(1, projectId);
ResultSet rs = pst.executeQuery();
while (rs.next()) {
pcount = rs.getInt("pcount");
syncount = rs.getInt("scount");
}
rs.close();
pst.close();
pst = conn.prepareStatement("select * from bard_project_experiment where bard_proj_id = ?");
pst.setLong(1, projectId);
rs = pst.executeQuery();
while (rs.next()) expts.add(getExperimentByExptId(rs.getLong("bard_expt_id")));
rs.close();
pst.close();
pst = conn.prepareStatement("select count(*) from bard_project_experiment a, bard_experiment b where a.bard_proj_id = ? and a.bard_expt_id = b.bard_expt_id");
pst.setLong(1, projectId);
rs = pst.executeQuery();
rs.next();
nassay = rs.getInt(1);
rs.close();
pst.close();
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
List<Long> probeIds = getProbeCidsForProject(projectId);
List<Compound> probes = getCompoundsByCid(probeIds.toArray(new Long[]{}));
List<String> probeReports = new ArrayList<String>();
for (Compound c : probes) {
if (c.getProbeId() != null) probeReports.add(c.getUrl());
}
Map<String, Object> ret = new HashMap<String, Object>();
ret.put("name", project.getName());
ret.put("probes", probes);
ret.put("probe_reports", probeReports);
ret.put("depositor", project.getSource());
ret.put("description", project.getDescription());
ret.put("targets", project.getTargets());
// ret.put("cmpd_purchase_count", pcount);
// ret.put("cmpd_synthesis_count", syncount);
ret.put("assay_count", nassay);
ret.put("experiment_count", expts.size());
ret.put("experiments", expts);
cache.put(new Element(projectId, ret));
return ret;
}
public List<String> getChemblTargetClasses(List<String> accs, int level) throws SQLException {
if (level < 1 || level > 8) throw new IllegalArgumentException("Level must be between 1 & 8, inclusive");
if (accs.size() < 1) throw new IllegalArgumentException("Must provide at least one Uniprot accession");
Connection conn = getConnection();
StringBuilder sb = new StringBuilder("(");
String delim = "";
for (String acc : accs) {
sb.append(delim).append("'").append(acc).append("'");
delim = ",";
}
sb.append(")");
PreparedStatement pst = conn.prepareStatement("select distinct a.accession, d.l1, d.l2, d.l3, d.l4, d.l5, d.l6, d.l7, d.l8 from assay_target a, gene2uniprot b, " +
"chembl_13.target_dictionary c,chembl_13.target_class d " +
"where a.gene_id = b.gene_id " +
"and b.accession = c.protein_accession " +
"and a.accession in " + sb.toString() +
"and c.tid = d.tid");
try {
ResultSet rs = pst.executeQuery();
Map<String, String> map = new HashMap<String, String>();
while (rs.next()) {
String acc = rs.getString(1);
String tclass = rs.getString("l" + level);
map.put(acc, tclass);
}
rs.close();
List<String> ret = new ArrayList<String>();
for (String acc : accs) ret.add(map.get(acc));
return ret;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public List<ProjectStep> getProjectStepsByProjectId(Long projectId) throws SQLException {
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement("select * from project_step where bard_proj_id = ?");
try {
pst.setLong(1, projectId);
List<ProjectStep> steps = new ArrayList<ProjectStep>();
ResultSet rs = pst.executeQuery();
while (rs.next()) {
ProjectStep step = new ProjectStep();
step.setStepId(rs.getLong("step_id"));
step.setBardProjId(projectId);
step.setEdgeName(rs.getString("edge_name"));
step.setNextBardExpt(rs.getLong("next_bard_expt_id"));
step.setPrevBardExpt(rs.getLong("prev_bard_expt_id"));
step.setAnnotations(getProjectStepAnnotations(step.getStepId()));
step.setPrevStageRef(getExperimentTypeByProject(projectId, step.getPrevBardExpt()));
step.setNextStageRef(getExperimentTypeByProject(projectId, step.getNextBardExpt()));
steps.add(step);
}
rs.close();
return steps;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public String getExperimentTypeByProject(Long bardProjId, Long bardExptId) throws SQLException {
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement("select expt_type from bard_project_experiment where bard_proj_id = ? and bard_expt_id = ?");
try {
pst.setLong(1, bardProjId);
pst.setLong(2, bardExptId);
ResultSet rs = pst.executeQuery();
String ret = null;
while (rs.next()) ret = rs.getString(1);
rs.close();
return ret;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public List<CAPAnnotation> getProjectStepAnnotations(Long projectStepId) throws SQLException {
Cache cache = getCache("ProjectStepAnnotationsCache");
try {
List<CAPAnnotation> value = getCacheValue
(cache, projectStepId);
if (value != null) {
return value;
}
} catch (ClassCastException ex) {
}
Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement("select a.* from cap_project_annotation a where a.bard_proj_id = ?");
try {
pst.setLong(1, projectStepId);
ResultSet rs = pst.executeQuery();
List<CAPAnnotation> annos = new ArrayList<CAPAnnotation>();
while (rs.next()) {
String anno_id = rs.getString("anno_id");
String anno_key = rs.getString("anno_key");
String anno_value = rs.getString("anno_value");
String anno_display = rs.getString("anno_display");
int displayOrder = rs.getInt("display_order");
String source = rs.getString("source");
String entity = rs.getString("entity");
String contextName = rs.getString("context_name");
String contextGroup = rs.getString("context_group");
String related = rs.getString("related");
String extValueId = null;
if (related != null && !related.trim().equals("")) {
String[] toks = related.split("\\|");
if (toks.length == 2) extValueId = toks[1];
}
// TODO Updated the related annotations field to support grouping
CAPAnnotation anno = new CAPAnnotation(Integer.parseInt(anno_id), projectStepId.intValue(),
anno_display, contextName, anno_key, anno_value,
extValueId, source, null, displayOrder, entity, related, contextGroup);
annos.add(anno);
}
rs.close();
cache.put(new Element(projectStepId, annos));
return annos;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public List<TargetClassification> getPantherClassesForAccession(String acc) throws SQLException {
Connection conn = getConnection();
Cache cache = getCache("PantherClassesCache");
try {
List<TargetClassification> value = getCacheValue(cache, acc);
if (value != null) return value;
} catch (ClassCastException e) {
}
PreparedStatement pst = conn.prepareStatement("select b.* from panther_uniprot_map a, panther_class b where a.accession = ? and a.pclass_id = b.pclass_id order by node_level");
try {
pst.setString(1, acc);
ResultSet rs = pst.executeQuery();
List<TargetClassification> classes = new ArrayList<TargetClassification>();
while (rs.next()) {
PantherClassification pc = new PantherClassification();
pc.setDescription(rs.getString("class_descr"));
pc.setName(rs.getString("class_name"));
pc.setId(rs.getString("pclass_id"));
pc.setLevelIdentifier(rs.getString("node_code"));
pc.setNodeLevel(rs.getInt("node_level"));
classes.add(pc);
}
rs.close();
cache.put(new Element(acc, classes));
return classes;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public List<ProteinTarget> getProteinTargetsForPantherClassification(String clsid) throws SQLException {
Connection conn = getConnection();
Cache cache = getCache("TargetsForPantherClassCache");
try {
List<ProteinTarget> value = getCacheValue(cache, clsid);
if (value != null) return value;
} catch (ClassCastException e) {
}
PreparedStatement pst = conn.prepareStatement("select distinct a.accession from panther_uniprot_map a where a.pclass_id = ?");
try {
pst.setString(1, clsid);
ResultSet rs = pst.executeQuery();
List<ProteinTarget> targets = new ArrayList<ProteinTarget>();
while (rs.next()) {
String acc = rs.getString(1);
targets.add(getProteinTargetByAccession(acc));
}
rs.close();
cache.put(new Element(clsid, targets));
return targets;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public List<Biology> getBiologyByDictId(String dictId)
throws SQLException {
Connection conn = getConnection();
PreparedStatement pst;
pst = conn.prepareStatement("select * from bard_biology where biology_dict_id = ?");
try {
pst.setString(1, dictId);
ResultSet rs = pst.executeQuery();
List<Biology> bios = new ArrayList<Biology>();
while (rs.next()) {
Biology bio = new Biology();
bio.setSerial(rs.getLong("serial"));
bio.setBiology(Biology.BiologyType.fromString(rs.getString("biology")));
bio.setName(rs.getString("description"));
bio.setDictId(rs.getLong("biology_dict_id"));
bio.setDictLabel(rs.getString("biology_dict_label"));
bio.setEntity(rs.getString("entity"));
bio.setEntityId(rs.getLong("entity_id"));
bio.setExtId(rs.getString("ext_id"));
bio.setExtRef(rs.getString("ext_ref"));
bios.add(bio);
}
rs.close();
return bios;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public List<Biology> getBiologyByType(String typeName, String extId) throws SQLException {
Connection conn = getConnection();
String cachKey = typeName;
if (extId != null) cachKey = cachKey + "#" + extId;
Cache cache = getCache("BiologyCache");
try {
List<Biology> value = getCacheValue(cache, cachKey);
if (value != null) return value;
} catch (ClassCastException e) {
}
PreparedStatement pst;
if (extId == null) {
pst = conn.prepareStatement("select * from bard_biology where biology = ?");
pst.setString(1, typeName);
} else {
pst = conn.prepareStatement("select * from bard_biology where biology = ? and ext_id = ?");
pst.setString(1, typeName);
pst.setString(2, extId);
}
try {
ResultSet rs = pst.executeQuery();
List<Biology> bios = new ArrayList<Biology>();
while (rs.next()) {
Biology bio = new Biology();
bio.setSerial(rs.getLong("serial"));
bio.setBiology(Biology.BiologyType.fromString(rs.getString("biology")));
bio.setName(rs.getString("description"));
bio.setDictId(rs.getLong("biology_dict_id"));
bio.setDictLabel(rs.getString("biology_dict_label"));
bio.setEntity(rs.getString("entity"));
bio.setEntityId(rs.getLong("entity_id"));
bio.setExtId(rs.getString("ext_id"));
bio.setExtRef(rs.getString("ext_ref"));
bios.add(bio);
}
cache.put(new Element(bios, cachKey));
rs.close();
return bios;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public List<Biology> getBiologyByType(String typeName) throws SQLException {
return getBiologyByType(typeName, null);
}
public List<Biology> getBiologyBySerial(Long serial) throws SQLException {
Connection conn = getConnection();
Cache cache = getCache("BiologyCache");
try {
List<Biology> value = getCacheValue(cache, serial);
if (value != null) return value;
} catch (ClassCastException e) {
}
PreparedStatement pst = conn.prepareStatement("select * from bard_biology where serial = ?");
try {
pst.setLong(1, serial);
ResultSet rs = pst.executeQuery();
List<Biology> bios = new ArrayList<Biology>();
while (rs.next()) {
Biology bio = new Biology();
bio.setSerial(rs.getLong("serial"));
bio.setBiology(Biology.BiologyType.fromString(rs.getString("biology")));
bio.setName(rs.getString("description"));
bio.setDictId(rs.getLong("biology_dict_id"));
bio.setDictLabel(rs.getString("biology_dict_label"));
bio.setEntity(rs.getString("entity"));
bio.setEntityId(rs.getLong("entity_id"));
bio.setExtId(rs.getString("ext_id"));
bio.setExtRef(rs.getString("ext_ref"));
bios.add(bio);
}
cache.put(new Element(bios, serial));
rs.close();
return bios;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
public List<Biology> getBiologyByEntity(String entity, long entityId) throws SQLException {
Connection conn = getConnection();
Cache cache = getCache("BiologyCache");
try {
List<Biology> value = getCacheValue(cache, entity + "#" + entityId);
if (value != null) return value;
} catch (ClassCastException e) {
}
PreparedStatement pst = conn.prepareStatement("select * from bard_biology where entity = ? and entity_id = ?");
try {
pst.setString(1, entity);
pst.setLong(2, entityId);
ResultSet rs = pst.executeQuery();
List<Biology> bios = new ArrayList<Biology>();
while (rs.next()) {
Biology bio = new Biology();
bio.setSerial(rs.getLong("serial"));
bio.setBiology(Biology.BiologyType.fromString(rs.getString("biology")));
bio.setName(rs.getString("description"));
bio.setDictId(rs.getLong("biology_dict_id"));
bio.setDictLabel(rs.getString("biology_dict_label"));
bio.setEntity(entity);
bio.setEntityId(entityId);
bio.setExtId(rs.getString("ext_id"));
bio.setExtRef(rs.getString("ext_ref"));
bios.add(bio);
}
cache.put(new Element(bios, entity + "#" + entityId));
rs.close();
return bios;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
;
}
}
public List<Biology> getBiologyByEntity(String entity, long entityId, String typeName) throws SQLException {
Connection conn = getConnection();
Cache cache = getCache("BiologyCache");
try {
List<Biology> value = getCacheValue(cache, entity + "#" + entityId + "#" + typeName);
if (value != null) return value;
} catch (ClassCastException e) {
}
PreparedStatement pst = conn.prepareStatement("select * from bard_biology where entity = ? and entity_id = ?");
try {
pst.setString(1, entity);
pst.setLong(2, entityId);
ResultSet rs = pst.executeQuery();
List<Biology> bios = new ArrayList<Biology>();
while (rs.next()) {
Biology bio = new Biology();
bio.setSerial(rs.getLong("serial"));
bio.setBiology(Biology.BiologyType.fromString(rs.getString("biology")));
bio.setName(rs.getString("description"));
bio.setDictId(rs.getLong("biology_dict_id"));
bio.setDictLabel(rs.getString("biology_dict_label"));
bio.setEntity(entity);
bio.setEntityId(entityId);
bio.setExtId(rs.getString("ext_id"));
bio.setExtRef(rs.getString("ext_ref"));
bios.add(bio);
}
cache.put(new Element(bios, entity + "#" + entityId + "#" + typeName));
rs.close();
return bios;
} finally {
//close resources
JDBCResourceCloser.close(pst, conn);
}
}
}