package com.commafeed.backend.dao; import java.util.Date; import java.util.List; import javax.ejb.Stateless; import javax.persistence.TypedQuery; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.JoinType; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; import javax.persistence.criteria.SetJoin; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.lang.StringUtils; import com.commafeed.backend.model.Feed; import com.commafeed.backend.model.FeedSubscription; import com.commafeed.backend.model.FeedSubscription_; import com.commafeed.backend.model.Feed_; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; @Stateless public class FeedDAO extends GenericDAO { private List getUpdatablePredicates(Root root, Date threshold) { Predicate hasSubscriptions = builder.isNotEmpty(root .get(Feed_.subscriptions)); Predicate neverUpdated = builder.isNull(root.get(Feed_.lastUpdated)); Predicate updatedBeforeThreshold = builder.lessThan( root.get(Feed_.lastUpdated), threshold); Predicate disabledDateIsNull = builder.isNull(root .get(Feed_.disabledUntil)); Predicate disabledDateIsInPast = builder.lessThan( root.get(Feed_.disabledUntil), new Date()); return Lists.newArrayList(hasSubscriptions, builder.or(neverUpdated, updatedBeforeThreshold), builder.or(disabledDateIsNull, disabledDateIsInPast)); } public Long getUpdatableCount(Date threshold) { CriteriaQuery query = builder.createQuery(Long.class); Root root = query.from(getType()); query.select(builder.count(root)); query.where(getUpdatablePredicates(root, threshold).toArray(new Predicate[0])); TypedQuery q = em.createQuery(query); return q.getSingleResult(); } public List findNextUpdatable(int count, Date threshold) { CriteriaQuery query = builder.createQuery(getType()); Root root = query.from(getType()); query.where(getUpdatablePredicates(root, threshold).toArray(new Predicate[0])); query.orderBy(builder.asc(root.get(Feed_.lastUpdated))); TypedQuery q = em.createQuery(query); q.setMaxResults(count); return q.getResultList(); } public Feed findByUrl(String url) { List feeds = findByField(Feed_.urlHash, DigestUtils.sha1Hex(url)); Feed feed = Iterables.getFirst(feeds, null); if (feed != null && StringUtils.equals(url, feed.getUrl())) { return feed; } return null; } public Feed findByIdWithEntries(Long feedId, int offset, int limit) { CriteriaQuery query = builder.createQuery(getType()); Root root = query.from(getType()); query.where(builder.equal(root.get(Feed_.id), feedId)); root.fetch(Feed_.entries, JoinType.LEFT); TypedQuery q = em.createQuery(query); limit(q, offset, limit); return q.getSingleResult(); } public List findByTopic(String topic) { return findByField(Feed_.pushTopicHash, DigestUtils.sha1Hex(topic)); } public int deleteWithoutSubscriptions(int max) { CriteriaQuery query = builder.createQuery(getType()); Root root = query.from(getType()); SetJoin join = root.join(Feed_.subscriptions, JoinType.LEFT); query.where(builder.isNull(join.get(FeedSubscription_.id))); TypedQuery q = em.createQuery(query); q.setMaxResults(max); List list = q.getResultList(); int deleted = list.size(); delete(list); return deleted; } }