mirror of
https://github.com/TeamPiped/Piped-Backend.git
synced 2024-08-14 23:51:41 +00:00
Replace native query with criteria api for feeds (#190)
This commit is contained in:
parent
166e14cf71
commit
498849ec6b
2 changed files with 54 additions and 63 deletions
|
@ -49,6 +49,7 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
|
|
||||||
import javax.persistence.criteria.CriteriaBuilder;
|
import javax.persistence.criteria.CriteriaBuilder;
|
||||||
import javax.persistence.criteria.CriteriaQuery;
|
import javax.persistence.criteria.CriteriaQuery;
|
||||||
|
import javax.persistence.criteria.JoinType;
|
||||||
import javax.persistence.criteria.Root;
|
import javax.persistence.criteria.Root;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
@ -728,26 +729,34 @@ public class ResponseHelper {
|
||||||
|
|
||||||
if (user != null) {
|
if (user != null) {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
CriteriaBuilder cb = s.getCriteriaBuilder();
|
||||||
List<Object[]> queryResults = s.createNativeQuery(
|
|
||||||
"select Video.*, Channel.* from videos as Video left join channels as Channel on Video.uploader_id = Channel.uploader_id inner join users_subscribed on users_subscribed.channel = Channel.uploader_id where users_subscribed.subscriber = :user")
|
|
||||||
.setParameter("user", user.getId()).addEntity("Video", Video.class)
|
|
||||||
.addEntity("Channel", me.kavin.piped.utils.obj.db.Channel.class).getResultList();
|
|
||||||
|
|
||||||
List<FeedItem> feedItems = new ObjectArrayList<>();
|
// Get all videos from subscribed channels, with channel info
|
||||||
|
CriteriaQuery<Video> criteria = cb.createQuery(Video.class);
|
||||||
|
criteria.distinct(true);
|
||||||
|
var root = criteria.from(Video.class);
|
||||||
|
var userRoot = criteria.from(User.class);
|
||||||
|
root.fetch("channel", JoinType.LEFT);
|
||||||
|
|
||||||
queryResults.forEach(obj -> {
|
criteria.select(root)
|
||||||
Video video = (Video) obj[0];
|
.where(cb.and(
|
||||||
me.kavin.piped.utils.obj.db.Channel channel = (me.kavin.piped.utils.obj.db.Channel) obj[1];
|
cb.isMember(root.get("channel"), userRoot.<Collection<String>>get("subscribed_ids")),
|
||||||
|
cb.equal(userRoot.get("id"), user.getId())
|
||||||
|
))
|
||||||
|
.orderBy(cb.desc(root.get("uploaded")));
|
||||||
|
|
||||||
feedItems.add(new FeedItem("/watch?v=" + video.getId(), video.getTitle(),
|
List<StreamItem> feedItems = new ObjectArrayList<>();
|
||||||
rewriteURL(video.getThumbnail()), "/channel/" + channel.getUploaderId(), channel.getUploader(),
|
|
||||||
rewriteURL(channel.getUploaderAvatar()), video.getViews(), video.getDuration(),
|
for (Video video : s.createQuery(criteria).list()) {
|
||||||
|
var channel = video.getChannel();
|
||||||
|
|
||||||
|
feedItems.add(new StreamItem("/watch?v=" + video.getId(), video.getTitle(),
|
||||||
|
rewriteURL(video.getThumbnail()), channel.getUploader(), "/channel/" + channel.getUploaderId(),
|
||||||
|
rewriteURL(channel.getUploaderAvatar()), null, null, video.getDuration(), video.getViews(),
|
||||||
video.getUploaded(), channel.isVerified()));
|
video.getUploaded(), channel.isVerified()));
|
||||||
|
}
|
||||||
|
|
||||||
});
|
feedItems.sort(Comparator.<StreamItem>comparingLong(o -> o.uploaded).reversed());
|
||||||
|
|
||||||
feedItems.sort(Comparator.<FeedItem>comparingLong(o -> o.uploaded).reversed());
|
|
||||||
|
|
||||||
s.close();
|
s.close();
|
||||||
|
|
||||||
|
@ -776,40 +785,46 @@ public class ResponseHelper {
|
||||||
feed.setUri(Constants.FRONTEND_URL + "/feed");
|
feed.setUri(Constants.FRONTEND_URL + "/feed");
|
||||||
feed.setPublishedDate(new Date());
|
feed.setPublishedDate(new Date());
|
||||||
|
|
||||||
if (user.getSubscribed() != null && !user.getSubscribed().isEmpty()) {
|
CriteriaBuilder cb = s.getCriteriaBuilder();
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
// Get all videos from subscribed channels, with channel info
|
||||||
List<Object[]> queryResults = s.createNativeQuery(
|
CriteriaQuery<Video> criteria = cb.createQuery(Video.class);
|
||||||
"select Video.*, Channel.* from videos as Video left join channels as Channel on Video.uploader_id = Channel.uploader_id inner join users_subscribed on users_subscribed.channel = Channel.uploader_id where users_subscribed.subscriber = :user")
|
criteria.distinct(true);
|
||||||
.setParameter("user", user.getId()).addEntity("Video", Video.class)
|
var root = criteria.from(Video.class);
|
||||||
.addEntity("Channel", me.kavin.piped.utils.obj.db.Channel.class).getResultList();
|
var userRoot = criteria.from(User.class);
|
||||||
|
root.fetch("channel", JoinType.LEFT);
|
||||||
|
|
||||||
queryResults.sort(Comparator.<Object[]>comparingLong(o -> ((Video) (o)[0]).getUploaded()).reversed());
|
criteria.select(root)
|
||||||
|
.where(cb.and(
|
||||||
|
cb.isMember(root.get("channel"), userRoot.<Collection<String>>get("subscribed_ids")),
|
||||||
|
cb.equal(userRoot.get("id"), user.getId())
|
||||||
|
))
|
||||||
|
.orderBy(cb.desc(root.get("uploaded")));
|
||||||
|
|
||||||
final List<SyndEntry> entries = new ObjectArrayList<>();
|
List<Video> videos = s.createQuery(criteria).list();
|
||||||
|
|
||||||
for (Object[] result : queryResults) {
|
final List<SyndEntry> entries = new ObjectArrayList<>();
|
||||||
Video video = (Video) result[0];
|
|
||||||
me.kavin.piped.utils.obj.db.Channel channel = (me.kavin.piped.utils.obj.db.Channel) result[1];
|
|
||||||
SyndEntry entry = new SyndEntryImpl();
|
|
||||||
|
|
||||||
SyndPerson person = new SyndPersonImpl();
|
for (Video video : videos) {
|
||||||
person.setName(channel.getUploader());
|
var channel = video.getChannel();
|
||||||
person.setUri(Constants.FRONTEND_URL + "/channel/" + channel.getUploaderId());
|
SyndEntry entry = new SyndEntryImpl();
|
||||||
|
|
||||||
entry.setAuthors(Collections.singletonList(person));
|
SyndPerson person = new SyndPersonImpl();
|
||||||
|
person.setName(channel.getUploader());
|
||||||
|
person.setUri(Constants.FRONTEND_URL + "/channel/" + channel.getUploaderId());
|
||||||
|
|
||||||
entry.setLink(Constants.FRONTEND_URL + "/watch?v=" + video.getId());
|
entry.setAuthors(Collections.singletonList(person));
|
||||||
entry.setUri(Constants.FRONTEND_URL + "/watch?v=" + video.getId());
|
|
||||||
entry.setTitle(video.getTitle());
|
|
||||||
entry.setPublishedDate(new Date(video.getUploaded()));
|
|
||||||
entries.add(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
feed.setEntries(entries);
|
|
||||||
|
|
||||||
|
entry.setLink(Constants.FRONTEND_URL + "/watch?v=" + video.getId());
|
||||||
|
entry.setUri(Constants.FRONTEND_URL + "/watch?v=" + video.getId());
|
||||||
|
entry.setTitle(video.getTitle());
|
||||||
|
entry.setPublishedDate(new Date(video.getUploaded()));
|
||||||
|
entries.add(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
feed.setEntries(entries);
|
||||||
|
|
||||||
|
|
||||||
s.close();
|
s.close();
|
||||||
|
|
||||||
return new SyndFeedOutput().outputString(feed).getBytes(UTF_8);
|
return new SyndFeedOutput().outputString(feed).getBytes(UTF_8);
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
package me.kavin.piped.utils.obj;
|
|
||||||
|
|
||||||
public class FeedItem {
|
|
||||||
|
|
||||||
public String url, title, thumbnail, uploaderUrl, uploaderName, uploaderAvatar;
|
|
||||||
|
|
||||||
public long views, duration, uploaded;
|
|
||||||
|
|
||||||
public boolean uploaderVerified;
|
|
||||||
|
|
||||||
public FeedItem(String url, String title, String thumbnail, String uploaderUrl, String uploaderName,
|
|
||||||
String uploaderAvatar, long views, long duration, long uploaded, boolean uploaderVerified) {
|
|
||||||
this.url = url;
|
|
||||||
this.title = title;
|
|
||||||
this.thumbnail = thumbnail;
|
|
||||||
this.uploaderUrl = uploaderUrl;
|
|
||||||
this.uploaderName = uploaderName;
|
|
||||||
this.uploaderAvatar = uploaderAvatar;
|
|
||||||
this.views = views;
|
|
||||||
this.duration = duration;
|
|
||||||
this.uploaded = uploaded;
|
|
||||||
this.uploaderVerified = uploaderVerified;
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue