mirror of
https://github.com/Athou/commafeed.git
synced 2026-03-21 21:37:29 +00:00
less database calls
This commit is contained in:
@@ -17,6 +17,7 @@ import javax.persistence.criteria.Root;
|
|||||||
import org.apache.commons.lang3.ObjectUtils;
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
import org.apache.commons.lang3.time.DateUtils;
|
import org.apache.commons.lang3.time.DateUtils;
|
||||||
import org.hibernate.Criteria;
|
import org.hibernate.Criteria;
|
||||||
|
import org.hibernate.criterion.CriteriaSpecification;
|
||||||
import org.hibernate.criterion.Disjunction;
|
import org.hibernate.criterion.Disjunction;
|
||||||
import org.hibernate.criterion.MatchMode;
|
import org.hibernate.criterion.MatchMode;
|
||||||
import org.hibernate.criterion.Order;
|
import org.hibernate.criterion.Order;
|
||||||
@@ -50,17 +51,23 @@ public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
|
|||||||
protected static Logger log = LoggerFactory
|
protected static Logger log = LoggerFactory
|
||||||
.getLogger(FeedEntryStatusDAO.class);
|
.getLogger(FeedEntryStatusDAO.class);
|
||||||
|
|
||||||
private static final Comparator<FeedEntry> ENTRY_COMPARATOR_DESC = new Comparator<FeedEntry>() {
|
private static final String ALIAS_STATUS = "status";
|
||||||
|
private static final String ALIAS_ENTRY = "entry";
|
||||||
|
private static final String ALIAS_FFE = "ffe";
|
||||||
|
|
||||||
|
private static final Comparator<FeedEntryStatus> STATUS_COMPARATOR_DESC = new Comparator<FeedEntryStatus>() {
|
||||||
@Override
|
@Override
|
||||||
public int compare(FeedEntry o1, FeedEntry o2) {
|
public int compare(FeedEntryStatus o1, FeedEntryStatus o2) {
|
||||||
return ObjectUtils.compare(o2.getUpdated(), o1.getUpdated());
|
return ObjectUtils.compare(o2.getEntryUpdated(),
|
||||||
|
o1.getEntryUpdated());
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final Comparator<FeedEntry> ENTRY_COMPARATOR_ASC = new Comparator<FeedEntry>() {
|
private static final Comparator<FeedEntryStatus> STATUS_COMPARATOR_ASC = new Comparator<FeedEntryStatus>() {
|
||||||
@Override
|
@Override
|
||||||
public int compare(FeedEntry o1, FeedEntry o2) {
|
public int compare(FeedEntryStatus o1, FeedEntryStatus o2) {
|
||||||
return ObjectUtils.compare(o1.getUpdated(), o2.getUpdated());
|
return ObjectUtils.compare(o1.getEntryUpdated(),
|
||||||
|
o2.getEntryUpdated());
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -80,6 +87,12 @@ public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
|
|||||||
|
|
||||||
List<FeedEntryStatus> statuses = em.createQuery(query).getResultList();
|
List<FeedEntryStatus> statuses = em.createQuery(query).getResultList();
|
||||||
FeedEntryStatus status = Iterables.getFirst(statuses, null);
|
FeedEntryStatus status = Iterables.getFirst(statuses, null);
|
||||||
|
|
||||||
|
return handleStatus(status, sub, entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
private FeedEntryStatus handleStatus(FeedEntryStatus status,
|
||||||
|
FeedSubscription sub, FeedEntry entry) {
|
||||||
if (status == null) {
|
if (status == null) {
|
||||||
Date unreadThreshold = getUnreadThreshold();
|
Date unreadThreshold = getUnreadThreshold();
|
||||||
boolean read = unreadThreshold == null ? false : entry
|
boolean read = unreadThreshold == null ? false : entry
|
||||||
@@ -120,13 +133,12 @@ public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
|
|||||||
|
|
||||||
private Criteria buildSearchCriteria(FeedSubscription sub,
|
private Criteria buildSearchCriteria(FeedSubscription sub,
|
||||||
boolean unreadOnly, String keywords, Date newerThan, int offset,
|
boolean unreadOnly, String keywords, Date newerThan, int offset,
|
||||||
int limit, ReadingOrder order, boolean includeContent,
|
int limit, ReadingOrder order, boolean includeContent, Date last) {
|
||||||
FeedEntry last) {
|
|
||||||
Criteria criteria = getSession().createCriteria(FeedEntry.class,
|
Criteria criteria = getSession().createCriteria(FeedEntry.class,
|
||||||
"entry");
|
ALIAS_ENTRY);
|
||||||
|
|
||||||
Criteria ffeJoin = criteria.createCriteria(
|
Criteria ffeJoin = criteria.createCriteria(
|
||||||
FeedEntry_.feedRelationships.getName(), "ffe",
|
FeedEntry_.feedRelationships.getName(), ALIAS_FFE,
|
||||||
JoinType.INNER_JOIN);
|
JoinType.INNER_JOIN);
|
||||||
ffeJoin.add(Restrictions.eq(FeedFeedEntry_.feed.getName(),
|
ffeJoin.add(Restrictions.eq(FeedFeedEntry_.feed.getName(),
|
||||||
sub.getFeed()));
|
sub.getFeed()));
|
||||||
@@ -153,7 +165,7 @@ public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
|
|||||||
|
|
||||||
if (unreadOnly) {
|
if (unreadOnly) {
|
||||||
Criteria statusJoin = criteria.createCriteria(FeedEntry_.statuses
|
Criteria statusJoin = criteria.createCriteria(FeedEntry_.statuses
|
||||||
.getName(), "status", JoinType.LEFT_OUTER_JOIN,
|
.getName(), ALIAS_STATUS, JoinType.LEFT_OUTER_JOIN,
|
||||||
Restrictions.eq(FeedEntryStatus_.subscription.getName(),
|
Restrictions.eq(FeedEntryStatus_.subscription.getName(),
|
||||||
sub));
|
sub));
|
||||||
|
|
||||||
@@ -173,12 +185,10 @@ public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
|
|||||||
if (last != null) {
|
if (last != null) {
|
||||||
if (order == ReadingOrder.desc) {
|
if (order == ReadingOrder.desc) {
|
||||||
ffeJoin.add(Restrictions.gt(
|
ffeJoin.add(Restrictions.gt(
|
||||||
FeedFeedEntry_.entryUpdated.getName(),
|
FeedFeedEntry_.entryUpdated.getName(), last));
|
||||||
last.getUpdated()));
|
|
||||||
} else {
|
} else {
|
||||||
ffeJoin.add(Restrictions.lt(
|
ffeJoin.add(Restrictions.lt(
|
||||||
FeedFeedEntry_.entryUpdated.getName(),
|
FeedFeedEntry_.entryUpdated.getName(), last));
|
||||||
last.getUpdated()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,38 +221,38 @@ public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
|
|||||||
ReadingOrder order, boolean includeContent) {
|
ReadingOrder order, boolean includeContent) {
|
||||||
|
|
||||||
int capacity = offset + limit;
|
int capacity = offset + limit;
|
||||||
Comparator<FeedEntry> comparator = order == ReadingOrder.desc ? ENTRY_COMPARATOR_DESC
|
Comparator<FeedEntryStatus> comparator = order == ReadingOrder.desc ? STATUS_COMPARATOR_DESC
|
||||||
: ENTRY_COMPARATOR_ASC;
|
: STATUS_COMPARATOR_ASC;
|
||||||
FixedSizeSortedSet<FeedEntry> set = new FixedSizeSortedSet<FeedEntry>(
|
FixedSizeSortedSet<FeedEntryStatus> set = new FixedSizeSortedSet<FeedEntryStatus>(
|
||||||
capacity < 0 ? Integer.MAX_VALUE : capacity, comparator);
|
capacity < 0 ? Integer.MAX_VALUE : capacity, comparator);
|
||||||
for (FeedSubscription sub : subscriptions) {
|
for (FeedSubscription sub : subscriptions) {
|
||||||
FeedEntry last = (order != null && set.isFull()) ? set.last()
|
Date last = (order != null && set.isFull()) ? set.last()
|
||||||
: null;
|
.getEntryUpdated() : null;
|
||||||
Criteria criteria = buildSearchCriteria(sub, unreadOnly, keywords,
|
Criteria criteria = buildSearchCriteria(sub, unreadOnly, keywords,
|
||||||
newerThan, -1, limit, order, includeContent, last);
|
newerThan, -1, limit, order, includeContent, last);
|
||||||
|
criteria.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
|
||||||
List<FeedEntry> list = criteria.list();
|
List<Map<String, Object>> list = criteria.list();
|
||||||
for (FeedEntry entry : list) {
|
for (Map<String, Object> map : list) {
|
||||||
|
FeedEntryStatus status = (FeedEntryStatus) map
|
||||||
|
.get(ALIAS_STATUS);
|
||||||
|
FeedEntry entry = (FeedEntry) map.get(ALIAS_ENTRY);
|
||||||
entry.setSubscription(sub);
|
entry.setSubscription(sub);
|
||||||
|
|
||||||
|
status = handleStatus(status, sub, entry);
|
||||||
|
|
||||||
|
status.setEntry(entry);
|
||||||
|
set.add(status);
|
||||||
}
|
}
|
||||||
set.addAll(list);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List<FeedEntry> entries = set.asList();
|
List<FeedEntryStatus> statuses = set.asList();
|
||||||
int size = entries.size();
|
int size = statuses.size();
|
||||||
if (size < offset) {
|
if (size < offset) {
|
||||||
return Lists.newArrayList();
|
return Lists.newArrayList();
|
||||||
}
|
}
|
||||||
|
|
||||||
entries = entries.subList(Math.max(offset, 0), size);
|
statuses = statuses.subList(Math.max(offset, 0), size);
|
||||||
|
return lazyLoadContent(includeContent, statuses);
|
||||||
List<FeedEntryStatus> results = Lists.newArrayList();
|
|
||||||
for (FeedEntry entry : entries) {
|
|
||||||
FeedSubscription subscription = entry.getSubscription();
|
|
||||||
results.add(getStatus(subscription, entry));
|
|
||||||
}
|
|
||||||
|
|
||||||
return lazyLoadContent(includeContent, results);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Date getUnreadThreshold() {
|
private Date getUnreadThreshold() {
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ public class FeedEntryService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FeedEntryStatus status = feedEntryStatusDAO.getStatus(sub, entry);
|
FeedEntryStatus status = feedEntryStatusDAO.getStatus(sub, entry);
|
||||||
|
|
||||||
status.setRead(read);
|
status.setRead(read);
|
||||||
feedEntryStatusDAO.saveOrUpdate(status);
|
feedEntryStatusDAO.saveOrUpdate(status);
|
||||||
}
|
}
|
||||||
@@ -57,7 +56,6 @@ public class FeedEntryService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FeedEntryStatus status = feedEntryStatusDAO.getStatus(sub, entry);
|
FeedEntryStatus status = feedEntryStatusDAO.getStatus(sub, entry);
|
||||||
|
|
||||||
status.setStarred(starred);
|
status.setStarred(starred);
|
||||||
feedEntryStatusDAO.saveOrUpdate(status);
|
feedEntryStatusDAO.saveOrUpdate(status);
|
||||||
|
|
||||||
|
|||||||
@@ -9,4 +9,8 @@
|
|||||||
<query>delete from FeedEntryStatus s where s.entryInserted < :date and s.starred = false</query>
|
<query>delete from FeedEntryStatus s where s.entryInserted < :date and s.starred = false</query>
|
||||||
</named-query>
|
</named-query>
|
||||||
|
|
||||||
|
<named-query name="EntryStatus.existing">
|
||||||
|
<query>select new com.commafeed.backend.dao.FeedEntryDAO$EntryWithFeed(e, f) FROM FeedEntry e LEFT JOIN e.feedRelationships f WITH f.feed.id = :feedId where e.guidHash = :guidHash and e.url = :url</query>
|
||||||
|
</named-query>
|
||||||
|
|
||||||
</entity-mappings>
|
</entity-mappings>
|
||||||
Reference in New Issue
Block a user