public void testTranslateQuerySpecificClassPlus() throws Exception {
    Query expected = new Query();
    QueryClass qc = new QueryClass(Item.class);
    expected.addFrom(qc);
    expected.addToSelect(qc);
    ConstraintSet cs = new ConstraintSet(ConstraintOp.AND);
    QueryField qf2 = new QueryField(qc, "identifier");
    SimpleConstraint sc2 =
        new SimpleConstraint(qf2, ConstraintOp.EQUALS, new QueryValue("fish_42"));
    cs.addConstraint(sc2);
    QueryField qf1 = new QueryField(qc, "className");
    SimpleConstraint sc1 =
        new SimpleConstraint(qf1, ConstraintOp.EQUALS, new QueryValue("Department"));
    cs.addConstraint(sc1);
    expected.setConstraint(cs);

    Query original = new Query();
    QueryClass qc2 = new QueryClass(Department.class);
    original.addFrom(qc2);
    original.addToSelect(qc2);
    QueryField qf3 = new QueryField(qc2, "id");
    SimpleConstraint sc3 =
        new SimpleConstraint(qf3, ConstraintOp.EQUALS, new QueryValue(new Integer(42)));
    original.setConstraint(sc3);

    assertEquals(expected, translator.translateQuery(original));
  }
  /**
   * Retrieve the publications to be updated
   *
   * @param os The ObjectStore to read from
   * @return a List of publications
   */
  protected List<Publication> getPublications(ObjectStore os) {
    Query q = new Query();
    QueryClass qc = new QueryClass(Publication.class);
    q.addFrom(qc);
    q.addToSelect(qc);

    ConstraintSet cs = new ConstraintSet(ConstraintOp.OR);

    SimpleConstraint scTitle =
        new SimpleConstraint(new QueryField(qc, "title"), ConstraintOp.IS_NULL);
    cs.addConstraint(scTitle);

    SimpleConstraint scYear =
        new SimpleConstraint(new QueryField(qc, "year"), ConstraintOp.IS_NULL);
    cs.addConstraint(scYear);

    SimpleConstraint scFirstAuthor =
        new SimpleConstraint(new QueryField(qc, "firstAuthor"), ConstraintOp.IS_NULL);
    cs.addConstraint(scFirstAuthor);

    q.setConstraint(cs);

    @SuppressWarnings("unchecked")
    List<Publication> retval = (List<Publication>) ((List) os.executeSingleton(q));
    return retval;
  }
  /** Test that transactions can be aborted */
  public void testAbortTransactions() throws Exception {
    Address address1 = new Address();
    address1.setAddress("Address 3");
    Address address2 = new Address();
    address2.setAddress("Address 4");

    Query q = new Query();
    QueryClass qcAddress = new QueryClass(Address.class);
    QueryField qf = new QueryField(qcAddress, "address");
    ConstraintSet cs1 = new ConstraintSet(ConstraintOp.OR);
    cs1.addConstraint(new SimpleConstraint(qf, ConstraintOp.MATCHES, new QueryValue("Address%")));
    q.addToSelect(qcAddress);
    q.addFrom(qcAddress);
    q.addToOrderBy(qf);
    q.setConstraint(cs1);

    Results res = writer.execute(q);
    assertEquals(res.toString(), 0, res.size());

    res = realOs.execute(q);
    assertEquals(res.toString(), 0, res.size());

    writer.beginTransaction();
    assertTrue(writer.isInTransaction());

    writer.store(address1);
    writer.store(address2);

    // TODO: These lines now fail, because we do not allow querying on writers with uncommitted
    // data. The writer should relax this restriction.
    res = writer.execute(q);
    assertEquals(2, res.size());

    res = realOs.execute(q);
    assertEquals(res.toString(), 0, res.size());

    writer.abortTransaction();
    assertFalse(writer.isInTransaction());

    // Should be nothing there unless we commit

    res = writer.execute(q);
    assertEquals(res.toString(), 0, res.size());

    res = realOs.execute(q);
    assertEquals(res.toString(), 0, res.size());
  }
Exemple #4
0
 /**
  * Add a contains constraint to Query (q) built with the query class and attribute given in input
  *
  * @param query The query to add a reference to.
  * @param qc The class the reference belongs to.
  * @param attribute the name of the field of the class.
  * @param attributePath Another similarly named field - I wish it had been documented!
  * @return The query class of the attributePath.
  */
 protected QueryClass addReference(
     final Query query, final QueryClass qc, String attribute, String attributePath) {
   ConstraintSet cs = (ConstraintSet) query.getConstraint();
   QueryReference qr = null;
   String type = "";
   boolean useSubClass = false;
   if (WidgetConfigUtil.isPathContainingSubClass(os.getModel(), attribute)) {
     useSubClass = true;
     type = attribute.substring(attribute.indexOf("[") + 1, attribute.indexOf("]"));
     attribute = attribute.substring(0, attribute.indexOf("["));
   }
   QueryClass qcTmp = null;
   try {
     qr = new QueryObjectReference(qc, attribute);
     if (useSubClass) {
       try {
         qcTmp = new QueryClass(Class.forName(os.getModel().getPackageName() + "." + type));
       } catch (ClassNotFoundException cnfe) {
         LOG.error("The type " + type + " doesn't exist in the model.");
       }
     } else {
       qcTmp = new QueryClass(qr.getType());
     }
   } catch (IllegalArgumentException e) {
     // Not a reference - try collection instead
     qr = new QueryCollectionReference(qc, attribute);
     if (useSubClass) {
       try {
         qcTmp = new QueryClass(Class.forName(os.getModel().getPackageName() + "." + type));
       } catch (ClassNotFoundException cnfe) {
         LOG.error("The type " + type + " doesn't exist in the model.");
       }
     } else {
       qcTmp = new QueryClass(TypeUtil.getElementType(qc.getType(), attribute));
     }
   }
   QueryClass ret;
   if (!queryClassInQuery.containsKey(attributePath)) {
     ret = qcTmp;
     query.addFrom(ret);
     cs.addConstraint(new ContainsConstraint(qr, ConstraintOp.CONTAINS, ret));
     queryClassInQuery.put(attributePath, ret);
   } else {
     ret = queryClassInQuery.get(attributePath);
   }
   return ret;
 }
  /** Test that transactions do actually commit and that isInTransaction() works. */
  public void testCommitTransactions() throws Exception {
    Address address1 = new Address();
    address1.setAddress("Address 1");
    Address address2 = new Address();
    address2.setAddress("Address 2");

    Query q = new Query();
    QueryClass qcAddress = new QueryClass(Address.class);
    QueryField qf = new QueryField(qcAddress, "address");
    ConstraintSet cs1 = new ConstraintSet(ConstraintOp.OR);
    cs1.addConstraint(new SimpleConstraint(qf, ConstraintOp.MATCHES, new QueryValue("Address%")));
    q.addToSelect(qcAddress);
    q.addFrom(qcAddress);
    q.addToOrderBy(qf);
    q.setConstraint(cs1);

    try {
      writer.beginTransaction();
      assertTrue(writer.isInTransaction());

      writer.store(address1);
      writer.store(address2);

      // Should be nothing in OS until we commit
      Results res = realOs.execute(q);
      assertEquals(0, res.size());

      // However, they should be in the WRITER.
      // TODO: These lines now fail, because we do not allow querying on writers with uncommitted
      // data. The writer should relax this restriction.
      res = writer.execute(q);
      assertEquals(2, res.size());

      writer.commitTransaction();
      assertFalse(writer.isInTransaction());
      res = realOs.execute(q);
      assertEquals(2, res.size());
      assertEquals(address1, (Address) ((ResultsRow) res.get(0)).get(0));
      assertEquals(address2, (Address) ((ResultsRow) res.get(1)).get(0));

    } finally {
      writer.delete(address1);
      writer.delete(address2);
    }
  }
  /** @return query to get all parent so terms */
  protected Query getAllParents() {
    Query q = new Query();
    q.setDistinct(false);

    QueryClass qcFeature =
        new QueryClass(model.getClassDescriptorByName("SequenceFeature").getType());
    q.addToSelect(qcFeature);
    q.addFrom(qcFeature);

    QueryClass qcSOTerm = new QueryClass(OntologyTerm.class);
    q.addToSelect(qcSOTerm);
    q.addFrom(qcSOTerm);
    q.addToOrderBy(qcSOTerm);

    ConstraintSet cs = new ConstraintSet(ConstraintOp.AND);

    QueryObjectReference ref1 = new QueryObjectReference(qcFeature, "sequenceOntologyTerm");
    cs.addConstraint(new ContainsConstraint(ref1, ConstraintOp.CONTAINS, qcSOTerm));

    // Set the constraint of the query
    q.setConstraint(cs);

    return q;
  }
  /** The method to run all the queries. */
  @SuppressWarnings("rawtypes")
  private void queryExecutor() {

    // Use spanOverlapFullResultMap to store the data in the session
    @SuppressWarnings("unchecked")
    Map<String, Map<GenomicRegion, List<SpanQueryResultRow>>> spanOverlapFullResultMap =
        (Map<String, Map<GenomicRegion, List<SpanQueryResultRow>>>)
            request.getSession().getAttribute("spanOverlapFullResultMap");

    if (spanOverlapFullResultMap == null) {
      spanOverlapFullResultMap =
          new HashMap<String, Map<GenomicRegion, List<SpanQueryResultRow>>>();
    }

    Map<GenomicRegion, List<SpanQueryResultRow>> spanOverlapResultDisplayMap =
        Collections.synchronizedMap(new LinkedHashMap<GenomicRegion, List<SpanQueryResultRow>>());

    // GBrowse track
    @SuppressWarnings("unchecked")
    Map<String, Map<GenomicRegion, LinkedHashMap<String, LinkedHashSet<GBrowseTrackInfo>>>>
        gbrowseFullTrackMap =
            (HashMap<
                    String,
                    Map<GenomicRegion, LinkedHashMap<String, LinkedHashSet<GBrowseTrackInfo>>>>)
                request.getSession().getAttribute("gbrowseFullTrackMap");

    if (gbrowseFullTrackMap == null) {
      gbrowseFullTrackMap =
          new HashMap<
              String, Map<GenomicRegion, LinkedHashMap<String, LinkedHashSet<GBrowseTrackInfo>>>>();
    }

    Map<GenomicRegion, LinkedHashMap<String, LinkedHashSet<GBrowseTrackInfo>>> gbrowseTrackMap =
        Collections.synchronizedMap(
            new LinkedHashMap<
                GenomicRegion, LinkedHashMap<String, LinkedHashSet<GBrowseTrackInfo>>>());

    if (!spanOverlapFullResultMap.containsKey(spanUUIDString)) {
      spanOverlapFullResultMap.put(spanUUIDString, spanOverlapResultDisplayMap);
      request.getSession().setAttribute("spanOverlapFullResultMap", spanOverlapFullResultMap);

      gbrowseFullTrackMap.put(spanUUIDString, gbrowseTrackMap);
      request.getSession().setAttribute("gbrowseFullTrackMap", gbrowseFullTrackMap);

      try {
        Query q;
        for (GenomicRegion aSpan : spanList) {
          q = new Query();
          q.setDistinct(true);

          String chrPID = aSpan.getChr();
          Integer start = aSpan.getStart();
          Integer end = aSpan.getEnd();

          /*
          >>>>> TEST CODE <<<<<
          LOG.info("OrgName: " + orgName);
          LOG.info("chrPID: " + chrPID);
          LOG.info("start: " + start);
          LOG.info("end: " + end);
          LOG.info("FeatureTypes: " + ftKeys);
          LOG.info("Submissions: " + subKeys);
          >>>>> TEST CODE <<<<<
          */

          // DB tables
          QueryClass qcOrg = new QueryClass(Organism.class);
          QueryClass qcChr = new QueryClass(Chromosome.class);
          QueryClass qcFeature = new QueryClass(SequenceFeature.class);
          QueryClass qcLoc = new QueryClass(Location.class);
          QueryClass qcSubmission = new QueryClass(Submission.class);

          QueryField qfOrgName = new QueryField(qcOrg, "shortName");
          QueryField qfChrPID = new QueryField(qcChr, "primaryIdentifier");
          QueryField qfFeaturePID = new QueryField(qcFeature, "primaryIdentifier");
          QueryField qfFeatureId = new QueryField(qcFeature, "id");
          QueryField qfFeatureClass = new QueryField(qcFeature, "class");
          QueryField qfSubmissionTitle = new QueryField(qcSubmission, "title");
          QueryField qfSubmissionDCCid = new QueryField(qcSubmission, "DCCid");
          QueryField qfChr = new QueryField(qcChr, "primaryIdentifier");
          QueryField qfLocStart = new QueryField(qcLoc, "start");
          QueryField qfLocEnd = new QueryField(qcLoc, "end");

          q.addToSelect(qfFeatureId);
          q.addToSelect(qfFeaturePID);
          q.addToSelect(qfFeatureClass);
          q.addToSelect(qfChr);
          q.addToSelect(qfLocStart);
          q.addToSelect(qfLocEnd);
          q.addToSelect(qfSubmissionDCCid);
          q.addToSelect(qfSubmissionTitle);

          q.addFrom(qcChr);
          q.addFrom(qcOrg);
          q.addFrom(qcFeature);
          q.addFrom(qcLoc);
          q.addFrom(qcSubmission);

          q.addToOrderBy(qfLocStart, "ascending");

          ConstraintSet constraints = new ConstraintSet(ConstraintOp.AND);

          q.setConstraint(constraints);

          // SequenceFeature.organism = Organism
          QueryObjectReference organism = new QueryObjectReference(qcFeature, "organism");
          ContainsConstraint ccOrg = new ContainsConstraint(organism, ConstraintOp.CONTAINS, qcOrg);
          constraints.addConstraint(ccOrg);

          // Organism.name = orgName
          SimpleConstraint scOrg =
              new SimpleConstraint(qfOrgName, ConstraintOp.EQUALS, new QueryValue(orgName));
          constraints.addConstraint(scOrg);

          // Location.feature = SequenceFeature
          QueryObjectReference locSubject = new QueryObjectReference(qcLoc, "feature");
          ContainsConstraint ccLocSubject =
              new ContainsConstraint(locSubject, ConstraintOp.CONTAINS, qcFeature);
          constraints.addConstraint(ccLocSubject);

          // Location.locatedOn = Chromosome
          QueryObjectReference locObject = new QueryObjectReference(qcLoc, "locatedOn");
          ContainsConstraint ccLocObject =
              new ContainsConstraint(locObject, ConstraintOp.CONTAINS, qcChr);
          constraints.addConstraint(ccLocObject);

          // Chromosome.primaryIdentifier = chrPID
          SimpleConstraint scChr =
              new SimpleConstraint(qfChrPID, ConstraintOp.EQUALS, new QueryValue(chrPID));
          constraints.addConstraint(scChr);

          // SequenceFeature.submissions = Submission
          QueryCollectionReference submission =
              new QueryCollectionReference(qcFeature, "submissions");
          ContainsConstraint ccSubmission =
              new ContainsConstraint(submission, ConstraintOp.CONTAINS, qcSubmission);
          constraints.addConstraint(ccSubmission);

          // SequenceFeature.class in a list
          constraints.addConstraint(new BagConstraint(qfFeatureClass, ConstraintOp.IN, ftKeys));
          // Submission.CCDid in a list
          constraints.addConstraint(new BagConstraint(qfSubmissionDCCid, ConstraintOp.IN, subKeys));

          OverlapRange overlapInput =
              new OverlapRange(new QueryValue(start), new QueryValue(end), locObject);
          OverlapRange overlapFeature =
              new OverlapRange(
                  new QueryField(qcLoc, "start"), new QueryField(qcLoc, "end"), locObject);
          OverlapConstraint oc =
              new OverlapConstraint(overlapInput, ConstraintOp.OVERLAPS, overlapFeature);
          constraints.addConstraint(oc);

          Results results = im.getObjectStore().execute(q);

          /*
          >>>>> TEST CODE <<<<<
          LOG.info("Query: " + q.toString());
          LOG.info("Result Size: " + results.size());
          LOG.info("Result >>>>> " + results);
          >>>>> TEST CODE <<<<<
          */

          List<SpanQueryResultRow> spanResults = new ArrayList<SpanQueryResultRow>();
          if (results == null || results.isEmpty()) {
            spanOverlapResultDisplayMap.put(aSpan, null);
            gbrowseTrackMap.put(aSpan, null);
          } else {
            for (Iterator<?> iter = results.iterator(); iter.hasNext(); ) {
              ResultsRow<?> row = (ResultsRow<?>) iter.next();

              SpanQueryResultRow aRow = new SpanQueryResultRow();
              aRow.setFeatureId((Integer) row.get(0));
              aRow.setFeaturePID((String) row.get(1));
              aRow.setFeatureClass(((Class) row.get(2)).getSimpleName());
              aRow.setChr((String) row.get(3));
              aRow.setStart((Integer) row.get(4));
              aRow.setEnd((Integer) row.get(5));
              aRow.setSubDCCid((String) row.get(6));
              aRow.setSubTitle((String) row.get(7));

              spanResults.add(aRow);
            }
            spanOverlapResultDisplayMap.put(aSpan, spanResults);
            gbrowseTrackMap.put(aSpan, getSubGbrowseTrack(spanResults)); // Gbrowse
          }
        }

      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  }
 /**
  * Fetches equivalent objects for a particular primary key.
  *
  * @param pk the PrimaryKey
  * @param cld the ClassDescriptor of the PrimaryKey
  * @param results a Map to hold results that are to be added to the cache
  * @param objectsForCld a List of objects relevant to this PrimaryKey
  * @param fetchedObjectIds a Set to hold ids of objects that are fetched, to prefetch from the
  *     data tracker later
  * @throws ObjectStoreException if something goes wrong
  */
 protected void doPk(
     PrimaryKey pk,
     ClassDescriptor cld,
     Map<InterMineObject, Set<InterMineObject>> results,
     List<InterMineObject> objectsForCld,
     Set<Integer> fetchedObjectIds)
     throws ObjectStoreException {
   Iterator<InterMineObject> objectsForCldIter = objectsForCld.iterator();
   while (objectsForCldIter.hasNext()) {
     int objCount = 0;
     int origObjCount = 0;
     Query q = new Query();
     QueryClass qc = new QueryClass(cld.getType());
     q.addFrom(qc);
     q.addToSelect(qc);
     ConstraintSet cs = new ConstraintSet(ConstraintOp.AND);
     q.setConstraint(cs);
     Map<String, Set<Object>> fieldNameToValues = new HashMap<String, Set<Object>>();
     for (String fieldName : pk.getFieldNames()) {
       try {
         QueryField qf = new QueryField(qc, fieldName);
         q.addToSelect(qf);
         Set<Object> values = new HashSet<Object>();
         fieldNameToValues.put(fieldName, values);
         cs.addConstraint(new BagConstraint(qf, ConstraintOp.IN, values));
       } catch (IllegalArgumentException e) {
         QueryForeignKey qf = new QueryForeignKey(qc, fieldName);
         q.addToSelect(qf);
         Set<Object> values = new HashSet<Object>();
         fieldNameToValues.put(fieldName, values);
         cs.addConstraint(new BagConstraint(qf, ConstraintOp.IN, values));
       }
     }
     // Now make a map from the primary key values to source objects
     Map<List<Object>, InterMineObject> keysToSourceObjects =
         new HashMap<List<Object>, InterMineObject>();
     while (objectsForCldIter.hasNext() && (objCount < 500)) {
       InterMineObject object = objectsForCldIter.next();
       origObjCount++;
       try {
         if (DataLoaderHelper.objectPrimaryKeyNotNull(model, object, cld, pk, source, idMap)) {
           List<Collection<Object>> values = new ArrayList<Collection<Object>>();
           boolean skipObject = false;
           Map<String, Set<Object>> fieldsValues = new HashMap<String, Set<Object>>();
           for (String fieldName : pk.getFieldNames()) {
             try {
               Object value = object.getFieldProxy(fieldName);
               Set<Object> fieldValues;
               if (value instanceof InterMineObject) {
                 Integer id = idMap.get(((InterMineObject) value).getId());
                 if (id == null) {
                   Set<InterMineObject> eqs = results.get(value);
                   if (eqs == null) {
                     value = object.getFieldValue(fieldName);
                     eqs = queryEquivalentObjects((InterMineObject) value, source);
                   }
                   fieldValues = new HashSet<Object>();
                   for (InterMineObject obj : eqs) {
                     fieldValues.add(obj.getId());
                   }
                 } else {
                   fieldValues = Collections.singleton((Object) id);
                 }
               } else {
                 fieldValues = Collections.singleton(value);
               }
               values.add(fieldValues);
               fieldsValues.put(fieldName, fieldValues);
               for (Object fieldValue : fieldValues) {
                 long time = System.currentTimeMillis();
                 boolean pkQueryFruitless =
                     hints.pkQueryFruitless(cld.getType(), fieldName, fieldValue);
                 String summaryName = Util.getFriendlyName(cld.getType()) + "." + fieldName;
                 if (!savedTimes.containsKey(summaryName)) {
                   savedTimes.put(summaryName, new Long(System.currentTimeMillis() - time));
                   savedCounts.put(summaryName, new Integer(0));
                 }
                 if (pkQueryFruitless) {
                   skipObject = true;
                 }
               }
             } catch (IllegalAccessException e) {
               throw new RuntimeException(e);
             }
           }
           if (!skipObject) {
             objCount++;
             for (String fieldName : pk.getFieldNames()) {
               fieldNameToValues.get(fieldName).addAll(fieldsValues.get(fieldName));
             }
             for (List<Object> valueSet : CollectionUtil.fanOutCombinations(values)) {
               if (keysToSourceObjects.containsKey(valueSet)) {
                 throw new ObjectStoreException(
                     "Duplicate objects found for pk "
                         + cld.getName()
                         + "."
                         + pk.getName()
                         + ": "
                         + object);
               }
               keysToSourceObjects.put(valueSet, object);
             }
           }
         }
       } catch (MetaDataException e) {
         throw new ObjectStoreException(e);
       }
     }
     // Prune BagConstraints using the hints system.
     // boolean emptyQuery = false;
     // Iterator<String> fieldNameIter = pk.getFieldNames().iterator();
     // while (fieldNameIter.hasNext() && (!emptyQuery)) {
     //    String fieldName = fieldNameIter.next();
     //    Set values = fieldNameToValues.get(fieldName);
     // Iterator valueIter = values.iterator();
     // while (valueIter.hasNext()) {
     //    if (hints.pkQueryFruitless(cld.getType(), fieldName, valueIter.next())) {
     //        valueIter.remove();
     //    }
     // }
     //    if (values.isEmpty()) {
     //        emptyQuery = true;
     //    }
     // }
     if (objCount > 0) {
       // Iterate through query, and add objects to results
       // long time = System.currentTimeMillis();
       int matches = 0;
       Results res = lookupOs.execute(q, 2000, false, false, false);
       @SuppressWarnings("unchecked")
       List<ResultsRow<Object>> tmpRes = (List) res;
       for (ResultsRow<Object> row : tmpRes) {
         List<Object> values = new ArrayList<Object>();
         for (int i = 1; i <= pk.getFieldNames().size(); i++) {
           values.add(row.get(i));
         }
         Set<InterMineObject> set = results.get(keysToSourceObjects.get(values));
         if (set != null) {
           set.add((InterMineObject) row.get(0));
           matches++;
         }
         fetchedObjectIds.add(((InterMineObject) row.get(0)).getId());
       }
       // LOG.info("Fetched " + res.size() + " equivalent objects for " + objCount
       //        + " objects in " + (System.currentTimeMillis() - time) + " ms for "
       //        + cld.getName() + "." + pk.getName());
     }
   }
 }
  /** {@inheritDoc} */
  public Query getQuery(String action, List<String> keys) {

    // classes for FROM clause
    QueryClass qcDisease = new QueryClass(Disease.class);
    QueryClass qcGene = new QueryClass(Gene.class);
    QueryClass qcPub = new QueryClass(Publication.class);

    // fields for SELECT clause
    QueryField qfDiseaseName = new QueryField(qcDisease, "diseaseId");
    QueryField qfGeneId = new QueryField(qcGene, "id");
    QueryField qfGeneName = new QueryField(qcGene, "primaryIdentifier");
    QueryField qfId = new QueryField(qcPub, "pubMedId");
    QueryField qfPubTitle = new QueryField(qcPub, "title");

    // constraints
    ConstraintSet cs = new ConstraintSet(ConstraintOp.AND);

    // constrain genes to be in list
    if (!action.startsWith("population")) {
      cs.addConstraint(new BagConstraint(qfGeneId, ConstraintOp.IN, bag.getOsb()));
    }

    // disease.publication = publication
    QueryCollectionReference qcr = new QueryCollectionReference(qcGene, "diseases");
    cs.addConstraint(new ContainsConstraint(qcr, ConstraintOp.CONTAINS, qcDisease));

    QueryCollectionReference fin =
        new QueryCollectionReference(qcDisease, "associatedPublications");
    cs.addConstraint(new ContainsConstraint(fin, ConstraintOp.CONTAINS, qcPub));

    Query q = new Query();
    q.setDistinct(true);

    // from statement
    q.addFrom(qcGene);
    q.addFrom(qcDisease);
    q.addFrom(qcPub);

    // add constraints to query
    q.setConstraint(cs);

    // needed for the 'not analysed' number
    if ("analysed".equals(action)) {
      q.addToSelect(qfGeneId);
      // export query
      // needed for export button on widget
    } else if ("export".equals(action)) {

      q.addToSelect(qfId);
      q.addToSelect(qfGeneName);
      q.addToOrderBy(qfId);

      // total queries
      // needed for enrichment calculations
    } else if (action.endsWith("Total")) {
      q.addToSelect(qfGeneId);
      Query subQ = q;
      q = new Query();
      q.addFrom(subQ);
      q.addToSelect(new QueryFunction()); // disease count

      // needed for enrichment calculations
    } else {

      q.addToSelect(qfId);
      q.addToGroupBy(qfId);
      q.addToSelect(new QueryFunction()); // disease count
      if ("sample".equals(action)) {
        q.addToSelect(qfPubTitle);
        q.addToGroupBy(qfPubTitle);
      }
    }
    return q;
  }
  /**
   * Read the UTRs collection of MRNA then set the fivePrimeUTR and threePrimeUTR fields with the
   * corresponding UTRs.
   *
   * @throws Exception if anything goes wrong
   */
  public void createUtrRefs() throws Exception {
    long startTime = System.currentTimeMillis();
    Query q = new Query();
    q.setDistinct(false);

    QueryClass qcMRNA = new QueryClass(model.getClassDescriptorByName("MRNA").getType());
    q.addFrom(qcMRNA);
    q.addToSelect(qcMRNA);
    q.addToOrderBy(qcMRNA);

    QueryClass qcUTR = new QueryClass(model.getClassDescriptorByName("UTR").getType());
    q.addFrom(qcUTR);
    q.addToSelect(qcUTR);
    q.addToOrderBy(qcUTR);

    QueryCollectionReference mrnaUtrsRef = new QueryCollectionReference(qcMRNA, "UTRs");
    ContainsConstraint mrnaUtrsConstraint =
        new ContainsConstraint(mrnaUtrsRef, ConstraintOp.CONTAINS, qcUTR);

    QueryObjectReference fivePrimeRef = new QueryObjectReference(qcMRNA, "fivePrimeUTR");
    ContainsConstraint fivePrimeNullConstraint =
        new ContainsConstraint(fivePrimeRef, ConstraintOp.IS_NULL);
    QueryObjectReference threePrimeRef = new QueryObjectReference(qcMRNA, "threePrimeUTR");
    ContainsConstraint threePrimeNullConstraint =
        new ContainsConstraint(threePrimeRef, ConstraintOp.IS_NULL);

    ConstraintSet cs = new ConstraintSet(ConstraintOp.AND);
    cs.addConstraint(mrnaUtrsConstraint);
    cs.addConstraint(fivePrimeNullConstraint);
    cs.addConstraint(threePrimeNullConstraint);

    q.setConstraint(cs);

    ObjectStore os = osw.getObjectStore();

    ((ObjectStoreInterMineImpl) os).precompute(q, Constants.PRECOMPUTE_CATEGORY);
    Results res = os.execute(q, 500, true, true, true);

    int count = 0;
    InterMineObject lastMRNA = null;

    InterMineObject fivePrimeUTR = null;
    InterMineObject threePrimeUTR = null;

    osw.beginTransaction();

    Class<? extends FastPathObject> fivePrimeUTRCls =
        model.getClassDescriptorByName("FivePrimeUTR").getType();

    Iterator<?> resIter = res.iterator();
    while (resIter.hasNext()) {
      ResultsRow<?> rr = (ResultsRow<?>) resIter.next();
      InterMineObject mrna = (InterMineObject) rr.get(0);
      InterMineObject utr = (InterMineObject) rr.get(1);

      if (lastMRNA != null && !mrna.getId().equals(lastMRNA.getId())) {
        // clone so we don't change the ObjectStore cache
        InterMineObject tempMRNA = PostProcessUtil.cloneInterMineObject(lastMRNA);
        if (fivePrimeUTR != null) {
          tempMRNA.setFieldValue("fivePrimeUTR", fivePrimeUTR);
          fivePrimeUTR = null;
        }
        if (threePrimeUTR != null) {
          tempMRNA.setFieldValue("threePrimeUTR", threePrimeUTR);
          threePrimeUTR = null;
        }
        osw.store(tempMRNA);
        count++;
      }

      if (DynamicUtil.isInstance(utr, fivePrimeUTRCls)) {
        fivePrimeUTR = utr;
      } else {
        threePrimeUTR = utr;
      }

      lastMRNA = mrna;
    }

    if (lastMRNA != null) {
      // clone so we don't change the ObjectStore cache
      InterMineObject tempMRNA = PostProcessUtil.cloneInterMineObject(lastMRNA);
      tempMRNA.setFieldValue("fivePrimeUTR", fivePrimeUTR);
      tempMRNA.setFieldValue("threePrimeUTR", threePrimeUTR);
      osw.store(tempMRNA);
      count++;
    }
    LOG.info(
        "Stored MRNA "
            + count
            + " times ("
            + count * 2
            + " fields set)"
            + " - took "
            + (System.currentTimeMillis() - startTime)
            + " ms.");
    osw.commitTransaction();

    // now ANALYSE tables relating to class that has been altered - may be rows added
    // to indirection tables
    if (osw instanceof ObjectStoreWriterInterMineImpl) {
      ClassDescriptor cld = model.getClassDescriptorByName("MRNA");
      DatabaseUtil.analyse(((ObjectStoreWriterInterMineImpl) osw).getDatabase(), cld, false);
    }
  }