diff --git a/api/src/main/java/org/openmrs/module/queue/api/dao/impl/QueueEntryDaoImpl.java b/api/src/main/java/org/openmrs/module/queue/api/dao/impl/QueueEntryDaoImpl.java index fc9f081..bca90c2 100644 --- a/api/src/main/java/org/openmrs/module/queue/api/dao/impl/QueueEntryDaoImpl.java +++ b/api/src/main/java/org/openmrs/module/queue/api/dao/impl/QueueEntryDaoImpl.java @@ -9,30 +9,22 @@ */ package org.openmrs.module.queue.api.dao.impl; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Predicate; -import javax.persistence.criteria.Root; +import javax.validation.constraints.NotNull; -import java.util.ArrayList; -import java.util.Collection; import java.util.Date; import java.util.List; import org.hibernate.Criteria; -import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.criterion.Order; import org.hibernate.criterion.Projections; import org.hibernate.criterion.Restrictions; -import org.openmrs.Patient; +import org.hibernate.query.Query; import org.openmrs.module.queue.api.dao.QueueEntryDao; import org.openmrs.module.queue.api.search.QueueEntrySearchCriteria; -import org.openmrs.module.queue.model.Queue; import org.openmrs.module.queue.model.QueueEntry; import org.springframework.beans.factory.annotation.Qualifier; -@SuppressWarnings("unchecked") public class QueueEntryDaoImpl extends AbstractBaseQueueDaoImpl implements QueueEntryDao { public QueueEntryDaoImpl(@Qualifier("sessionFactory") SessionFactory sessionFactory) { @@ -40,13 +32,17 @@ public QueueEntryDaoImpl(@Qualifier("sessionFactory") SessionFactory sessionFact } @Override + @SuppressWarnings("unchecked") public List getQueueEntries(QueueEntrySearchCriteria searchCriteria) { - Criteria c = createCriteriaFromSearchCriteria(searchCriteria); - c.addOrder(Order.desc("qe.sortWeight")); - c.addOrder(Order.asc("qe.startedAt")); - c.addOrder(Order.asc("qe.dateCreated")); - c.addOrder(Order.asc("qe.queueEntryId")); - return c.list(); + + Criteria criteria = createCriteriaFromSearchCriteria(searchCriteria); + + criteria.addOrder(Order.desc("qe.sortWeight")); + criteria.addOrder(Order.asc("qe.startedAt")); + criteria.addOrder(Order.asc("qe.dateCreated")); + criteria.addOrder(Order.asc("qe.queueEntryId")); + + return criteria.list(); } @Override @@ -57,81 +53,48 @@ public Long getCountOfQueueEntries(QueueEntrySearchCriteria searchCriteria) { } @Override - public List getOverlappingQueueEntries(QueueEntrySearchCriteria searchCriteria) { - Session session = getSessionFactory().getCurrentSession(); - CriteriaBuilder cb = session.getCriteriaBuilder(); - CriteriaQuery query = cb.createQuery(QueueEntry.class); - Root root = query.from(QueueEntry.class); - List predicates = new ArrayList<>(); - - predicates.add(cb.equal(root.get("voided"), false)); - - Collection queues = searchCriteria.getQueues(); - if (queues != null) { - if (queues.isEmpty()) { - predicates.add(root.get("queue").isNull()); - } else { - predicates.add(root.get("queue").in(searchCriteria.getQueues())); - } - } + public boolean updateIfUnmodified(QueueEntry entity, Date lastModified) { - Patient patient = searchCriteria.getPatient(); - if (patient != null) { - predicates.add(cb.equal(root.get("patient"), patient)); - } + QueueEntry existing = getCurrentSession().get(QueueEntry.class, entity.getQueueEntryId()); - Date startedAt = searchCriteria.getStartedOn(); - if (startedAt != null) { - // any queue entries that have either not ended or end after this queue entry starts - predicates.add(cb.or(root.get("endedAt").isNull(), cb.greaterThan(root.get("endedAt"), startedAt))); + if (existing == null) { + return false; } - query.where(cb.and(predicates.toArray(new Predicate[0]))); + Date existingDate = existing.getDateChanged(); + + if (existingDate != null && lastModified != null && !existingDate.equals(lastModified)) { + return false; + } - return session.createQuery(query).list(); + getCurrentSession().merge(entity); + return true; } @Override public void flushSession() { - getSessionFactory().getCurrentSession().flush(); + getCurrentSession().flush(); } @Override - public boolean updateIfUnmodified(QueueEntry queueEntry, Date expectedDateChanged) { - Session session = getSessionFactory().getCurrentSession(); - - // Evict the entity to prevent Hibernate from auto-flushing changes - session.evict(queueEntry); - - // Build conditional update query - only succeeds if dateChanged matches expected value - StringBuilder jpql = new StringBuilder(); - jpql.append("UPDATE QueueEntry qe SET "); - jpql.append("qe.endedAt = :endedAt "); - jpql.append("WHERE qe.queueEntryId = :id "); - - if (expectedDateChanged == null) { - jpql.append("AND qe.dateChanged IS NULL"); - } else { - jpql.append("AND qe.dateChanged = :expectedDateChanged"); - } + public List getOverlappingQueueEntries(@NotNull QueueEntrySearchCriteria searchCriteria) { - javax.persistence.Query query = session.createQuery(jpql.toString()); - query.setParameter("endedAt", queueEntry.getEndedAt()); - query.setParameter("id", queueEntry.getQueueEntryId()); - if (expectedDateChanged != null) { - query.setParameter("expectedDateChanged", expectedDateChanged); - } + String hql = "SELECT qe FROM QueueEntry qe " + "WHERE qe.patient = :patient " + "AND qe.queue IN (:queues) " + + "AND qe.voided = false " + "AND qe.endedAt IS NULL"; + + Query query = getCurrentSession().createQuery(hql, QueueEntry.class); - int rowsUpdated = query.executeUpdate(); - return rowsUpdated > 0; + query.setParameter("patient", searchCriteria.getPatient()); + query.setParameterList("queues", searchCriteria.getQueues()); + + return query.list(); } - /** - * Convert the given {@link QueueEntrySearchCriteria} into ORM criteria - */ private Criteria createCriteriaFromSearchCriteria(QueueEntrySearchCriteria searchCriteria) { + Criteria c = getCurrentSession().createCriteria(QueueEntry.class, "qe"); c.createAlias("queue", "q"); + includeVoidedObjects(c, searchCriteria.isIncludedVoided()); limitByCollectionProperty(c, "queue", searchCriteria.getQueues()); limitByCollectionProperty(c, "q.location", searchCriteria.getLocations()); @@ -145,20 +108,21 @@ private Criteria createCriteriaFromSearchCriteria(QueueEntrySearchCriteria searc limitByCollectionProperty(c, "qe.queueComingFrom", searchCriteria.getQueuesComingFrom()); limitToGreaterThanOrEqualToProperty(c, "qe.startedAt", searchCriteria.getStartedOnOrAfter()); limitToLessThanOrEqualToProperty(c, "qe.startedAt", searchCriteria.getStartedOnOrBefore()); - limitToEqualsProperty(c, "qe.startedAt", searchCriteria.getStartedOn()); limitToGreaterThanOrEqualToProperty(c, "qe.endedAt", searchCriteria.getEndedOnOrAfter()); limitToLessThanOrEqualToProperty(c, "qe.endedAt", searchCriteria.getEndedOnOrBefore()); - limitToEqualsProperty(c, "qe.endedAt", searchCriteria.getEndedOn()); + if (searchCriteria.getHasVisit() == Boolean.TRUE) { c.add(Restrictions.isNotNull("qe.visit")); } else if (searchCriteria.getHasVisit() == Boolean.FALSE) { c.add(Restrictions.isNull("qe.visit")); } + if (searchCriteria.getIsEnded() == Boolean.TRUE) { c.add(Restrictions.isNotNull("qe.endedAt")); } else if (searchCriteria.getIsEnded() == Boolean.FALSE) { c.add(Restrictions.isNull("qe.endedAt")); } + return c; } }