mirror of
https://github.com/Athou/commafeed.git
synced 2026-03-21 21:37:29 +00:00
split client and server into maven modules
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
package com.commafeed.backend.dao;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.hibernate.SessionFactory;
|
||||
|
||||
import com.commafeed.backend.model.FeedCategory;
|
||||
import com.commafeed.backend.model.QFeedCategory;
|
||||
import com.commafeed.backend.model.QUser;
|
||||
import com.commafeed.backend.model.User;
|
||||
import com.querydsl.core.types.Predicate;
|
||||
|
||||
@Singleton
|
||||
public class FeedCategoryDAO extends GenericDAO<FeedCategory> {
|
||||
|
||||
private QFeedCategory category = QFeedCategory.feedCategory;
|
||||
|
||||
@Inject
|
||||
public FeedCategoryDAO(SessionFactory sessionFactory) {
|
||||
super(sessionFactory);
|
||||
}
|
||||
|
||||
public List<FeedCategory> findAll(User user) {
|
||||
return query().selectFrom(category).where(category.user.eq(user)).join(category.user, QUser.user).fetchJoin().fetch();
|
||||
}
|
||||
|
||||
public FeedCategory findById(User user, Long id) {
|
||||
return query().selectFrom(category).where(category.user.eq(user), category.id.eq(id)).fetchOne();
|
||||
}
|
||||
|
||||
public FeedCategory findByName(User user, String name, FeedCategory parent) {
|
||||
Predicate parentPredicate = null;
|
||||
if (parent == null) {
|
||||
parentPredicate = category.parent.isNull();
|
||||
} else {
|
||||
parentPredicate = category.parent.eq(parent);
|
||||
}
|
||||
return query().selectFrom(category).where(category.user.eq(user), category.name.eq(name), parentPredicate).fetchOne();
|
||||
}
|
||||
|
||||
public List<FeedCategory> findByParent(User user, FeedCategory parent) {
|
||||
Predicate parentPredicate = null;
|
||||
if (parent == null) {
|
||||
parentPredicate = category.parent.isNull();
|
||||
} else {
|
||||
parentPredicate = category.parent.eq(parent);
|
||||
}
|
||||
return query().selectFrom(category).where(category.user.eq(user), parentPredicate).fetch();
|
||||
}
|
||||
|
||||
public List<FeedCategory> findAllChildrenCategories(User user, FeedCategory parent) {
|
||||
return findAll(user).stream().filter(c -> isChild(c, parent)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private boolean isChild(FeedCategory child, FeedCategory parent) {
|
||||
if (parent == null) {
|
||||
return true;
|
||||
}
|
||||
boolean isChild = false;
|
||||
while (child != null) {
|
||||
if (Objects.equals(child.getId(), parent.getId())) {
|
||||
isChild = true;
|
||||
break;
|
||||
}
|
||||
child = child.getParent();
|
||||
}
|
||||
return isChild;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.commafeed.backend.dao;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.hibernate.SessionFactory;
|
||||
|
||||
import com.commafeed.backend.model.Feed;
|
||||
import com.commafeed.backend.model.QFeed;
|
||||
import com.commafeed.backend.model.QFeedSubscription;
|
||||
import com.commafeed.backend.model.QUser;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.querydsl.jpa.JPAExpressions;
|
||||
import com.querydsl.jpa.JPQLQuery;
|
||||
|
||||
@Singleton
|
||||
public class FeedDAO extends GenericDAO<Feed> {
|
||||
|
||||
private final QFeed feed = QFeed.feed;
|
||||
|
||||
@Inject
|
||||
public FeedDAO(SessionFactory sessionFactory) {
|
||||
super(sessionFactory);
|
||||
}
|
||||
|
||||
public List<Feed> findNextUpdatable(int count, Date lastLoginThreshold) {
|
||||
JPQLQuery<Feed> query = query().selectFrom(feed);
|
||||
query.where(feed.disabledUntil.isNull().or(feed.disabledUntil.lt(new Date())));
|
||||
|
||||
if (lastLoginThreshold != null) {
|
||||
QFeedSubscription subs = QFeedSubscription.feedSubscription;
|
||||
QUser user = QUser.user;
|
||||
|
||||
query.join(feed.subscriptions, subs).join(subs.user, user).where(user.lastLogin.gt(lastLoginThreshold));
|
||||
}
|
||||
|
||||
return query.orderBy(feed.disabledUntil.asc()).limit(count).fetch();
|
||||
}
|
||||
|
||||
public Feed findByUrl(String normalizedUrl) {
|
||||
List<Feed> feeds = query().selectFrom(feed).where(feed.normalizedUrlHash.eq(DigestUtils.sha1Hex(normalizedUrl))).fetch();
|
||||
Feed feed = Iterables.getFirst(feeds, null);
|
||||
if (feed != null && StringUtils.equals(normalizedUrl, feed.getNormalizedUrl())) {
|
||||
return feed;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<Feed> findByTopic(String topic) {
|
||||
return query().selectFrom(feed).where(feed.pushTopicHash.eq(DigestUtils.sha1Hex(topic))).fetch();
|
||||
}
|
||||
|
||||
public List<Feed> findWithoutSubscriptions(int max) {
|
||||
QFeedSubscription sub = QFeedSubscription.feedSubscription;
|
||||
return query().selectFrom(feed).where(JPAExpressions.selectOne().from(sub).where(sub.feed.eq(feed)).notExists()).limit(max).fetch();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.commafeed.backend.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.hibernate.SessionFactory;
|
||||
|
||||
import com.commafeed.backend.model.FeedEntryContent;
|
||||
import com.commafeed.backend.model.QFeedEntry;
|
||||
import com.commafeed.backend.model.QFeedEntryContent;
|
||||
import com.querydsl.jpa.JPAExpressions;
|
||||
import com.querydsl.jpa.JPQLQuery;
|
||||
|
||||
@Singleton
|
||||
public class FeedEntryContentDAO extends GenericDAO<FeedEntryContent> {
|
||||
|
||||
private final QFeedEntryContent content = QFeedEntryContent.feedEntryContent;
|
||||
private final QFeedEntry entry = QFeedEntry.feedEntry;
|
||||
|
||||
@Inject
|
||||
public FeedEntryContentDAO(SessionFactory sessionFactory) {
|
||||
super(sessionFactory);
|
||||
}
|
||||
|
||||
public List<FeedEntryContent> findExisting(String contentHash, String titleHash) {
|
||||
return query().select(content).from(content).where(content.contentHash.eq(contentHash), content.titleHash.eq(titleHash)).fetch();
|
||||
}
|
||||
|
||||
public int deleteWithoutEntries(int max) {
|
||||
|
||||
JPQLQuery<Integer> subQuery = JPAExpressions.selectOne().from(entry).where(entry.content.id.eq(content.id));
|
||||
List<FeedEntryContent> list = query().selectFrom(content).where(subQuery.notExists()).limit(max).fetch();
|
||||
|
||||
int deleted = list.size();
|
||||
delete(list);
|
||||
return deleted;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.commafeed.backend.dao;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.hibernate.SessionFactory;
|
||||
|
||||
import com.commafeed.backend.model.Feed;
|
||||
import com.commafeed.backend.model.FeedEntry;
|
||||
import com.commafeed.backend.model.QFeedEntry;
|
||||
import com.querydsl.core.Tuple;
|
||||
import com.querydsl.core.types.dsl.NumberExpression;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@Singleton
|
||||
public class FeedEntryDAO extends GenericDAO<FeedEntry> {
|
||||
|
||||
private QFeedEntry entry = QFeedEntry.feedEntry;
|
||||
|
||||
@Inject
|
||||
public FeedEntryDAO(SessionFactory sessionFactory) {
|
||||
super(sessionFactory);
|
||||
}
|
||||
|
||||
public Long findExisting(String guid, Feed feed) {
|
||||
return query().select(entry.id)
|
||||
.from(entry)
|
||||
.where(entry.guidHash.eq(DigestUtils.sha1Hex(guid)), entry.feed.eq(feed))
|
||||
.limit(1)
|
||||
.fetchOne();
|
||||
}
|
||||
|
||||
public List<FeedCapacity> findFeedsExceedingCapacity(long maxCapacity, long max) {
|
||||
NumberExpression<Long> count = entry.id.count();
|
||||
List<Tuple> tuples = query().select(entry.feed.id, count)
|
||||
.from(entry)
|
||||
.groupBy(entry.feed)
|
||||
.having(count.gt(maxCapacity))
|
||||
.limit(max)
|
||||
.fetch();
|
||||
return tuples.stream().map(t -> new FeedCapacity(t.get(entry.feed.id), t.get(count))).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public int delete(Long feedId, long max) {
|
||||
|
||||
List<FeedEntry> list = query().selectFrom(entry).where(entry.feed.id.eq(feedId)).limit(max).fetch();
|
||||
return delete(list);
|
||||
}
|
||||
|
||||
public int deleteOldEntries(Long feedId, long max) {
|
||||
List<FeedEntry> list = query().selectFrom(entry).where(entry.feed.id.eq(feedId)).orderBy(entry.updated.asc()).limit(max).fetch();
|
||||
return delete(list);
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public static class FeedCapacity {
|
||||
private Long id;
|
||||
private Long capacity;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,277 @@
|
||||
package com.commafeed.backend.dao;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.builder.CompareToBuilder;
|
||||
import org.hibernate.SessionFactory;
|
||||
|
||||
import com.commafeed.CommaFeedConfiguration;
|
||||
import com.commafeed.backend.FixedSizeSortedSet;
|
||||
import com.commafeed.backend.feed.FeedEntryKeyword;
|
||||
import com.commafeed.backend.feed.FeedEntryKeyword.Mode;
|
||||
import com.commafeed.backend.model.FeedEntry;
|
||||
import com.commafeed.backend.model.FeedEntryContent;
|
||||
import com.commafeed.backend.model.FeedEntryStatus;
|
||||
import com.commafeed.backend.model.FeedEntryTag;
|
||||
import com.commafeed.backend.model.FeedSubscription;
|
||||
import com.commafeed.backend.model.Models;
|
||||
import com.commafeed.backend.model.QFeedEntry;
|
||||
import com.commafeed.backend.model.QFeedEntryContent;
|
||||
import com.commafeed.backend.model.QFeedEntryStatus;
|
||||
import com.commafeed.backend.model.QFeedEntryTag;
|
||||
import com.commafeed.backend.model.User;
|
||||
import com.commafeed.backend.model.UserSettings.ReadingOrder;
|
||||
import com.commafeed.frontend.model.UnreadCount;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Ordering;
|
||||
import com.querydsl.core.BooleanBuilder;
|
||||
import com.querydsl.core.Tuple;
|
||||
import com.querydsl.jpa.impl.JPAQuery;
|
||||
|
||||
@Singleton
|
||||
public class FeedEntryStatusDAO extends GenericDAO<FeedEntryStatus> {
|
||||
|
||||
private static final Comparator<FeedEntryStatus> STATUS_COMPARATOR_DESC = new Comparator<FeedEntryStatus>() {
|
||||
@Override
|
||||
public int compare(FeedEntryStatus o1, FeedEntryStatus o2) {
|
||||
CompareToBuilder builder = new CompareToBuilder();
|
||||
builder.append(o2.getEntryUpdated(), o1.getEntryUpdated());
|
||||
builder.append(o2.getId(), o1.getId());
|
||||
return builder.toComparison();
|
||||
}
|
||||
};
|
||||
|
||||
private static final Comparator<FeedEntryStatus> STATUS_COMPARATOR_ASC = Ordering.from(STATUS_COMPARATOR_DESC).reverse();
|
||||
|
||||
private final FeedEntryDAO feedEntryDAO;
|
||||
private final FeedEntryTagDAO feedEntryTagDAO;
|
||||
private final CommaFeedConfiguration config;
|
||||
|
||||
private final QFeedEntryStatus status = QFeedEntryStatus.feedEntryStatus;
|
||||
private final QFeedEntry entry = QFeedEntry.feedEntry;
|
||||
private final QFeedEntryContent content = QFeedEntryContent.feedEntryContent;
|
||||
private final QFeedEntryTag entryTag = QFeedEntryTag.feedEntryTag;
|
||||
|
||||
@Inject
|
||||
public FeedEntryStatusDAO(SessionFactory sessionFactory, FeedEntryDAO feedEntryDAO, FeedEntryTagDAO feedEntryTagDAO,
|
||||
CommaFeedConfiguration config) {
|
||||
super(sessionFactory);
|
||||
this.feedEntryDAO = feedEntryDAO;
|
||||
this.feedEntryTagDAO = feedEntryTagDAO;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
public FeedEntryStatus getStatus(User user, FeedSubscription sub, FeedEntry entry) {
|
||||
List<FeedEntryStatus> statuses = query().selectFrom(status).where(status.entry.eq(entry), status.subscription.eq(sub)).fetch();
|
||||
FeedEntryStatus status = Iterables.getFirst(statuses, null);
|
||||
return handleStatus(user, status, sub, entry);
|
||||
}
|
||||
|
||||
private FeedEntryStatus handleStatus(User user, FeedEntryStatus status, FeedSubscription sub, FeedEntry entry) {
|
||||
if (status == null) {
|
||||
Date unreadThreshold = config.getApplicationSettings().getUnreadThreshold();
|
||||
boolean read = unreadThreshold == null ? false : entry.getUpdated().before(unreadThreshold);
|
||||
status = new FeedEntryStatus(user, sub, entry);
|
||||
status.setRead(read);
|
||||
status.setMarkable(!read);
|
||||
} else {
|
||||
status.setMarkable(true);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
private FeedEntryStatus fetchTags(User user, FeedEntryStatus status) {
|
||||
List<FeedEntryTag> tags = feedEntryTagDAO.findByEntry(user, status.getEntry());
|
||||
status.setTags(tags);
|
||||
return status;
|
||||
}
|
||||
|
||||
public List<FeedEntryStatus> findStarred(User user, Date newerThan, int offset, int limit, ReadingOrder order, boolean includeContent) {
|
||||
JPAQuery<FeedEntryStatus> query = query().selectFrom(status).where(status.user.eq(user), status.starred.isTrue());
|
||||
if (newerThan != null) {
|
||||
query.where(status.entryInserted.gt(newerThan));
|
||||
}
|
||||
|
||||
if (order == ReadingOrder.asc) {
|
||||
query.orderBy(status.entryUpdated.asc(), status.id.asc());
|
||||
} else {
|
||||
query.orderBy(status.entryUpdated.desc(), status.id.desc());
|
||||
}
|
||||
|
||||
query.offset(offset).limit(limit);
|
||||
setTimeout(query, config.getApplicationSettings().getQueryTimeout());
|
||||
|
||||
List<FeedEntryStatus> statuses = query.fetch();
|
||||
for (FeedEntryStatus status : statuses) {
|
||||
status = handleStatus(user, status, status.getSubscription(), status.getEntry());
|
||||
fetchTags(user, status);
|
||||
}
|
||||
return lazyLoadContent(includeContent, statuses);
|
||||
}
|
||||
|
||||
private JPAQuery<FeedEntry> buildQuery(User user, FeedSubscription sub, boolean unreadOnly, List<FeedEntryKeyword> keywords,
|
||||
Date newerThan, int offset, int limit, ReadingOrder order, FeedEntryStatus last, String tag) {
|
||||
|
||||
JPAQuery<FeedEntry> query = query().selectFrom(entry).where(entry.feed.eq(sub.getFeed()));
|
||||
|
||||
if (CollectionUtils.isNotEmpty(keywords)) {
|
||||
query.join(entry.content, content);
|
||||
|
||||
for (FeedEntryKeyword keyword : keywords) {
|
||||
BooleanBuilder or = new BooleanBuilder();
|
||||
or.or(content.content.containsIgnoreCase(keyword.getKeyword()));
|
||||
or.or(content.title.containsIgnoreCase(keyword.getKeyword()));
|
||||
if (keyword.getMode() == Mode.EXCLUDE) {
|
||||
or.not();
|
||||
}
|
||||
query.where(or);
|
||||
}
|
||||
}
|
||||
query.leftJoin(entry.statuses, status).on(status.subscription.id.eq(sub.getId()));
|
||||
|
||||
if (unreadOnly && tag == null) {
|
||||
BooleanBuilder or = new BooleanBuilder();
|
||||
or.or(status.read.isNull());
|
||||
or.or(status.read.isFalse());
|
||||
query.where(or);
|
||||
|
||||
Date unreadThreshold = config.getApplicationSettings().getUnreadThreshold();
|
||||
if (unreadThreshold != null) {
|
||||
query.where(entry.updated.goe(unreadThreshold));
|
||||
}
|
||||
}
|
||||
|
||||
if (tag != null) {
|
||||
BooleanBuilder and = new BooleanBuilder();
|
||||
and.and(entryTag.user.id.eq(user.getId()));
|
||||
and.and(entryTag.name.eq(tag));
|
||||
query.join(entry.tags, entryTag).on(and);
|
||||
}
|
||||
|
||||
if (newerThan != null) {
|
||||
query.where(entry.inserted.goe(newerThan));
|
||||
}
|
||||
|
||||
if (last != null) {
|
||||
if (order == ReadingOrder.desc) {
|
||||
query.where(entry.updated.gt(last.getEntryUpdated()));
|
||||
} else {
|
||||
query.where(entry.updated.lt(last.getEntryUpdated()));
|
||||
}
|
||||
}
|
||||
|
||||
if (order != null) {
|
||||
if (order == ReadingOrder.asc) {
|
||||
query.orderBy(entry.updated.asc(), entry.id.asc());
|
||||
} else {
|
||||
query.orderBy(entry.updated.desc(), entry.id.desc());
|
||||
}
|
||||
}
|
||||
|
||||
if (offset > -1) {
|
||||
query.offset(offset);
|
||||
}
|
||||
|
||||
if (limit > -1) {
|
||||
query.limit(limit);
|
||||
}
|
||||
|
||||
setTimeout(query, config.getApplicationSettings().getQueryTimeout());
|
||||
return query;
|
||||
}
|
||||
|
||||
public List<FeedEntryStatus> findBySubscriptions(User user, List<FeedSubscription> subs, boolean unreadOnly,
|
||||
List<FeedEntryKeyword> keywords, Date newerThan, int offset, int limit, ReadingOrder order, boolean includeContent,
|
||||
boolean onlyIds, String tag) {
|
||||
int capacity = offset + limit;
|
||||
|
||||
Comparator<FeedEntryStatus> comparator = order == ReadingOrder.desc ? STATUS_COMPARATOR_DESC : STATUS_COMPARATOR_ASC;
|
||||
|
||||
FixedSizeSortedSet<FeedEntryStatus> set = new FixedSizeSortedSet<>(capacity, comparator);
|
||||
for (FeedSubscription sub : subs) {
|
||||
FeedEntryStatus last = (order != null && set.isFull()) ? set.last() : null;
|
||||
JPAQuery<FeedEntry> query = buildQuery(user, sub, unreadOnly, keywords, newerThan, -1, capacity, order, last, tag);
|
||||
List<Tuple> tuples = query.select(entry.id, entry.updated, status.id, entry.content.title).fetch();
|
||||
|
||||
for (Tuple tuple : tuples) {
|
||||
Long id = tuple.get(entry.id);
|
||||
Date updated = tuple.get(entry.updated);
|
||||
Long statusId = tuple.get(status.id);
|
||||
|
||||
FeedEntryContent content = new FeedEntryContent();
|
||||
content.setTitle(tuple.get(entry.content.title));
|
||||
|
||||
FeedEntry entry = new FeedEntry();
|
||||
entry.setId(id);
|
||||
entry.setUpdated(updated);
|
||||
entry.setContent(content);
|
||||
|
||||
FeedEntryStatus status = new FeedEntryStatus();
|
||||
status.setId(statusId);
|
||||
status.setEntryUpdated(updated);
|
||||
status.setEntry(entry);
|
||||
status.setSubscription(sub);
|
||||
|
||||
set.add(status);
|
||||
}
|
||||
}
|
||||
|
||||
List<FeedEntryStatus> placeholders = set.asList();
|
||||
int size = placeholders.size();
|
||||
if (size < offset) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
placeholders = placeholders.subList(Math.max(offset, 0), size);
|
||||
|
||||
List<FeedEntryStatus> statuses = null;
|
||||
if (onlyIds) {
|
||||
statuses = placeholders;
|
||||
} else {
|
||||
statuses = new ArrayList<>();
|
||||
for (FeedEntryStatus placeholder : placeholders) {
|
||||
Long statusId = placeholder.getId();
|
||||
FeedEntry entry = feedEntryDAO.findById(placeholder.getEntry().getId());
|
||||
FeedEntryStatus status = handleStatus(user, statusId == null ? null : findById(statusId), placeholder.getSubscription(),
|
||||
entry);
|
||||
status = fetchTags(user, status);
|
||||
statuses.add(status);
|
||||
}
|
||||
statuses = lazyLoadContent(includeContent, statuses);
|
||||
}
|
||||
return statuses;
|
||||
}
|
||||
|
||||
public UnreadCount getUnreadCount(User user, FeedSubscription subscription) {
|
||||
UnreadCount uc = null;
|
||||
JPAQuery<FeedEntry> query = buildQuery(user, subscription, true, null, null, -1, -1, null, null, null);
|
||||
List<Tuple> tuples = query.select(entry.count(), entry.updated.max()).fetch();
|
||||
for (Tuple tuple : tuples) {
|
||||
Long count = tuple.get(entry.count());
|
||||
Date updated = tuple.get(entry.updated.max());
|
||||
uc = new UnreadCount(subscription.getId(), count, updated);
|
||||
}
|
||||
return uc;
|
||||
}
|
||||
|
||||
private List<FeedEntryStatus> lazyLoadContent(boolean includeContent, List<FeedEntryStatus> results) {
|
||||
if (includeContent) {
|
||||
for (FeedEntryStatus status : results) {
|
||||
Models.initialize(status.getSubscription().getFeed());
|
||||
Models.initialize(status.getEntry().getContent());
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
public List<FeedEntryStatus> getOldStatuses(Date olderThan, int limit) {
|
||||
return query().selectFrom(status).where(status.entryInserted.lt(olderThan), status.starred.isFalse()).limit(limit).fetch();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.commafeed.backend.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.hibernate.SessionFactory;
|
||||
|
||||
import com.commafeed.backend.model.FeedEntry;
|
||||
import com.commafeed.backend.model.FeedEntryTag;
|
||||
import com.commafeed.backend.model.QFeedEntryTag;
|
||||
import com.commafeed.backend.model.User;
|
||||
|
||||
@Singleton
|
||||
public class FeedEntryTagDAO extends GenericDAO<FeedEntryTag> {
|
||||
|
||||
private QFeedEntryTag tag = QFeedEntryTag.feedEntryTag;
|
||||
|
||||
@Inject
|
||||
public FeedEntryTagDAO(SessionFactory sessionFactory) {
|
||||
super(sessionFactory);
|
||||
}
|
||||
|
||||
public List<String> findByUser(User user) {
|
||||
return query().selectDistinct(tag.name).from(tag).where(tag.user.eq(user)).fetch();
|
||||
}
|
||||
|
||||
public List<FeedEntryTag> findByEntry(User user, FeedEntry entry) {
|
||||
return query().selectFrom(tag).where(tag.user.eq(user), tag.entry.eq(entry)).fetch();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package com.commafeed.backend.dao;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.hibernate.SessionFactory;
|
||||
|
||||
import com.commafeed.backend.model.Feed;
|
||||
import com.commafeed.backend.model.FeedCategory;
|
||||
import com.commafeed.backend.model.FeedSubscription;
|
||||
import com.commafeed.backend.model.Models;
|
||||
import com.commafeed.backend.model.QFeedSubscription;
|
||||
import com.commafeed.backend.model.User;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.querydsl.jpa.JPQLQuery;
|
||||
|
||||
@Singleton
|
||||
public class FeedSubscriptionDAO extends GenericDAO<FeedSubscription> {
|
||||
|
||||
private QFeedSubscription sub = QFeedSubscription.feedSubscription;
|
||||
|
||||
@Inject
|
||||
public FeedSubscriptionDAO(SessionFactory sessionFactory) {
|
||||
super(sessionFactory);
|
||||
}
|
||||
|
||||
public FeedSubscription findById(User user, Long id) {
|
||||
List<FeedSubscription> subs = query().selectFrom(sub)
|
||||
.where(sub.user.eq(user), sub.id.eq(id))
|
||||
.leftJoin(sub.feed)
|
||||
.fetchJoin()
|
||||
.leftJoin(sub.category)
|
||||
.fetchJoin()
|
||||
.fetch();
|
||||
return initRelations(Iterables.getFirst(subs, null));
|
||||
}
|
||||
|
||||
public List<FeedSubscription> findByFeed(Feed feed) {
|
||||
return query().selectFrom(sub).where(sub.feed.eq(feed)).fetch();
|
||||
}
|
||||
|
||||
public FeedSubscription findByFeed(User user, Feed feed) {
|
||||
List<FeedSubscription> subs = query().selectFrom(sub).where(sub.user.eq(user), sub.feed.eq(feed)).fetch();
|
||||
return initRelations(Iterables.getFirst(subs, null));
|
||||
}
|
||||
|
||||
public List<FeedSubscription> findAll(User user) {
|
||||
List<FeedSubscription> subs = query().selectFrom(sub)
|
||||
.where(sub.user.eq(user))
|
||||
.leftJoin(sub.feed)
|
||||
.fetchJoin()
|
||||
.leftJoin(sub.category)
|
||||
.fetchJoin()
|
||||
.fetch();
|
||||
return initRelations(subs);
|
||||
}
|
||||
|
||||
public List<FeedSubscription> findByCategory(User user, FeedCategory category) {
|
||||
JPQLQuery<FeedSubscription> query = query().selectFrom(sub).where(sub.user.eq(user));
|
||||
if (category == null) {
|
||||
query.where(sub.category.isNull());
|
||||
} else {
|
||||
query.where(sub.category.eq(category));
|
||||
}
|
||||
return initRelations(query.fetch());
|
||||
}
|
||||
|
||||
public List<FeedSubscription> findByCategories(User user, List<FeedCategory> categories) {
|
||||
Set<Long> categoryIds = categories.stream().map(c -> c.getId()).collect(Collectors.toSet());
|
||||
return findAll(user).stream()
|
||||
.filter(s -> s.getCategory() != null && categoryIds.contains(s.getCategory().getId()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<FeedSubscription> initRelations(List<FeedSubscription> list) {
|
||||
list.forEach(s -> initRelations(s));
|
||||
return list;
|
||||
}
|
||||
|
||||
private FeedSubscription initRelations(FeedSubscription sub) {
|
||||
if (sub != null) {
|
||||
Models.initialize(sub.getFeed());
|
||||
Models.initialize(sub.getCategory());
|
||||
}
|
||||
return sub;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.commafeed.backend.dao;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.hibernate.annotations.QueryHints;
|
||||
|
||||
import com.commafeed.backend.model.AbstractModel;
|
||||
import com.querydsl.jpa.impl.JPAQuery;
|
||||
import com.querydsl.jpa.impl.JPAQueryFactory;
|
||||
|
||||
import io.dropwizard.hibernate.AbstractDAO;
|
||||
|
||||
public abstract class GenericDAO<T extends AbstractModel> extends AbstractDAO<T> {
|
||||
|
||||
private JPAQueryFactory factory;
|
||||
|
||||
protected GenericDAO(SessionFactory sessionFactory) {
|
||||
super(sessionFactory);
|
||||
this.factory = new JPAQueryFactory(() -> currentSession());
|
||||
}
|
||||
|
||||
protected JPAQueryFactory query() {
|
||||
return factory;
|
||||
}
|
||||
|
||||
public void saveOrUpdate(T model) {
|
||||
persist(model);
|
||||
}
|
||||
|
||||
public void saveOrUpdate(Collection<T> models) {
|
||||
models.forEach(m -> persist(m));
|
||||
}
|
||||
|
||||
public void update(T model) {
|
||||
currentSession().merge(model);
|
||||
}
|
||||
|
||||
public T findById(Long id) {
|
||||
return get(id);
|
||||
}
|
||||
|
||||
public void delete(T object) {
|
||||
if (object != null) {
|
||||
currentSession().delete(object);
|
||||
}
|
||||
}
|
||||
|
||||
public int delete(Collection<T> objects) {
|
||||
objects.forEach(o -> delete(o));
|
||||
return objects.size();
|
||||
}
|
||||
|
||||
protected void setTimeout(JPAQuery<?> query, int timeoutMs) {
|
||||
if (timeoutMs > 0) {
|
||||
query.setHint(QueryHints.TIMEOUT_JPA, timeoutMs);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.commafeed.backend.dao;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.context.internal.ManagedSessionContext;
|
||||
|
||||
public class UnitOfWork {
|
||||
|
||||
public static void run(SessionFactory sessionFactory, SessionRunner sessionRunner) {
|
||||
call(sessionFactory, () -> {
|
||||
sessionRunner.runInSession();
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
public static <T> T call(SessionFactory sessionFactory, SessionRunnerReturningValue<T> sessionRunner) {
|
||||
final Session session = sessionFactory.openSession();
|
||||
if (ManagedSessionContext.hasBind(sessionFactory)) {
|
||||
throw new IllegalStateException("Already in a unit of work!");
|
||||
}
|
||||
T t = null;
|
||||
try {
|
||||
ManagedSessionContext.bind(session);
|
||||
session.beginTransaction();
|
||||
try {
|
||||
t = sessionRunner.runInSession();
|
||||
commitTransaction(session);
|
||||
} catch (Exception e) {
|
||||
rollbackTransaction(session);
|
||||
UnitOfWork.<RuntimeException> rethrow(e);
|
||||
}
|
||||
} finally {
|
||||
session.close();
|
||||
ManagedSessionContext.unbind(sessionFactory);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
private static void rollbackTransaction(Session session) {
|
||||
final Transaction txn = session.getTransaction();
|
||||
if (txn != null && txn.isActive()) {
|
||||
txn.rollback();
|
||||
}
|
||||
}
|
||||
|
||||
private static void commitTransaction(Session session) {
|
||||
final Transaction txn = session.getTransaction();
|
||||
if (txn != null && txn.isActive()) {
|
||||
txn.commit();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <E extends Exception> void rethrow(Exception e) throws E {
|
||||
throw (E) e;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface SessionRunner {
|
||||
void runInSession();
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface SessionRunnerReturningValue<T> {
|
||||
T runInSession();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.commafeed.backend.dao;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.hibernate.SessionFactory;
|
||||
|
||||
import com.commafeed.backend.model.QUser;
|
||||
import com.commafeed.backend.model.User;
|
||||
|
||||
@Singleton
|
||||
public class UserDAO extends GenericDAO<User> {
|
||||
|
||||
private QUser user = QUser.user;
|
||||
|
||||
@Inject
|
||||
public UserDAO(SessionFactory sessionFactory) {
|
||||
super(sessionFactory);
|
||||
}
|
||||
|
||||
public User findByName(String name) {
|
||||
return query().selectFrom(user).where(user.name.equalsIgnoreCase(name)).fetchOne();
|
||||
}
|
||||
|
||||
public User findByApiKey(String key) {
|
||||
return query().selectFrom(user).where(user.apiKey.equalsIgnoreCase(key)).fetchOne();
|
||||
}
|
||||
|
||||
public User findByEmail(String email) {
|
||||
return query().selectFrom(user).where(user.email.equalsIgnoreCase(email)).fetchOne();
|
||||
}
|
||||
|
||||
public long count() {
|
||||
return query().selectFrom(user).fetchCount();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.commafeed.backend.dao;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.hibernate.SessionFactory;
|
||||
|
||||
import com.commafeed.backend.model.QUserRole;
|
||||
import com.commafeed.backend.model.User;
|
||||
import com.commafeed.backend.model.UserRole;
|
||||
import com.commafeed.backend.model.UserRole.Role;
|
||||
|
||||
@Singleton
|
||||
public class UserRoleDAO extends GenericDAO<UserRole> {
|
||||
|
||||
private QUserRole role = QUserRole.userRole;
|
||||
|
||||
@Inject
|
||||
public UserRoleDAO(SessionFactory sessionFactory) {
|
||||
super(sessionFactory);
|
||||
}
|
||||
|
||||
public List<UserRole> findAll() {
|
||||
return query().selectFrom(role).leftJoin(role.user).fetchJoin().distinct().fetch();
|
||||
}
|
||||
|
||||
public List<UserRole> findAll(User user) {
|
||||
return query().selectFrom(role).where(role.user.eq(user)).distinct().fetch();
|
||||
}
|
||||
|
||||
public Set<Role> findRoles(User user) {
|
||||
return findAll(user).stream().map(r -> r.getRole()).collect(Collectors.toSet());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.commafeed.backend.dao;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.hibernate.SessionFactory;
|
||||
|
||||
import com.commafeed.backend.model.QUserSettings;
|
||||
import com.commafeed.backend.model.User;
|
||||
import com.commafeed.backend.model.UserSettings;
|
||||
|
||||
@Singleton
|
||||
public class UserSettingsDAO extends GenericDAO<UserSettings> {
|
||||
|
||||
private QUserSettings settings = QUserSettings.userSettings;
|
||||
|
||||
@Inject
|
||||
public UserSettingsDAO(SessionFactory sessionFactory) {
|
||||
super(sessionFactory);
|
||||
}
|
||||
|
||||
public UserSettings findByUser(User user) {
|
||||
return query().selectFrom(settings).where(settings.user.eq(user)).fetchFirst();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user