forked from Archives/Athou_commafeed
added on-demand database cleanup (date is hardcoded for the moment)
This commit is contained in:
29
src/main/java/com/commafeed/backend/DatabaseCleaner.java
Normal file
29
src/main/java/com/commafeed/backend/DatabaseCleaner.java
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package com.commafeed.backend;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import javax.ejb.Stateless;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import com.commafeed.backend.dao.FeedEntryDAO;
|
||||||
|
import com.commafeed.backend.model.FeedEntry;
|
||||||
|
|
||||||
|
@Stateless
|
||||||
|
public class DatabaseCleaner {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
FeedEntryDAO feedEntryDAO;
|
||||||
|
|
||||||
|
public void cleanOlderThan(long value, TimeUnit unit) {
|
||||||
|
Calendar cal = Calendar.getInstance();
|
||||||
|
cal.add(Calendar.MINUTE, -1 * (int) unit.toMinutes(value));
|
||||||
|
|
||||||
|
List<FeedEntry> entries = feedEntryDAO.findByInserted(cal.getTime());
|
||||||
|
for (FeedEntry entry : entries) {
|
||||||
|
feedEntryDAO.delete(entry.getStatuses());
|
||||||
|
}
|
||||||
|
feedEntryDAO.delete(entries);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -90,6 +90,6 @@ public class FeedDAO extends GenericDAO<Feed> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List<Feed> findByTopic(String topic) {
|
public List<Feed> findByTopic(String topic) {
|
||||||
return findByField(Feed_.pushTopic, topic);
|
return findByField(Feed_.pushTopicHash, DigestUtils.sha1Hex(topic));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.commafeed.backend.dao;
|
package com.commafeed.backend.dao;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.ejb.Stateless;
|
import javax.ejb.Stateless;
|
||||||
@@ -55,6 +56,14 @@ public class FeedEntryDAO extends GenericDAO<FeedEntry> {
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<FeedEntry> findByInserted(Date olderThan) {
|
||||||
|
CriteriaQuery<FeedEntry> query = builder.createQuery(getType());
|
||||||
|
Root<FeedEntry> root = query.from(getType());
|
||||||
|
|
||||||
|
query.where(builder.lessThan(root.get(FeedEntry_.inserted), olderThan));
|
||||||
|
return em.createQuery(query).getResultList();
|
||||||
|
}
|
||||||
|
|
||||||
public List<FeedEntry> findByFeed(Feed feed, int offset, int limit) {
|
public List<FeedEntry> findByFeed(Feed feed, int offset, int limit) {
|
||||||
CriteriaQuery<FeedEntry> query = builder.createQuery(getType());
|
CriteriaQuery<FeedEntry> query = builder.createQuery(getType());
|
||||||
Root<FeedEntry> root = query.from(getType());
|
Root<FeedEntry> root = query.from(getType());
|
||||||
|
|||||||
@@ -50,15 +50,15 @@ public abstract class GenericDAO<T extends AbstractModel> {
|
|||||||
saveOrUpdate(Arrays.asList(models));
|
saveOrUpdate(Arrays.asList(models));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete(T object) {
|
public void delete(AbstractModel object) {
|
||||||
if (object != null) {
|
if (object != null) {
|
||||||
object = em.merge(object);
|
object = em.merge(object);
|
||||||
em.remove(object);
|
em.remove(object);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete(List<T> objects) {
|
public void delete(Collection<? extends AbstractModel> objects) {
|
||||||
for (T object : objects) {
|
for (AbstractModel object : objects) {
|
||||||
delete(object);
|
delete(object);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import java.util.List;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import org.apache.commons.codec.digest.DigestUtils;
|
||||||
import org.apache.commons.lang.mutable.MutableBoolean;
|
import org.apache.commons.lang.mutable.MutableBoolean;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -164,6 +165,7 @@ public class FeedRefreshWorker {
|
|||||||
log.debug("feed {} has pubsub info: {}", feed.getUrl(), topic);
|
log.debug("feed {} has pubsub info: {}", feed.getUrl(), topic);
|
||||||
feed.setPushHub(hub);
|
feed.setPushHub(hub);
|
||||||
feed.setPushTopic(topic);
|
feed.setPushTopic(topic);
|
||||||
|
feed.setPushTopicHash(DigestUtils.sha1Hex(topic));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,14 +11,10 @@ import javax.persistence.Table;
|
|||||||
import javax.persistence.Temporal;
|
import javax.persistence.Temporal;
|
||||||
import javax.persistence.TemporalType;
|
import javax.persistence.TemporalType;
|
||||||
|
|
||||||
import org.hibernate.annotations.Index;
|
|
||||||
|
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "FEEDS")
|
@Table(name = "FEEDS")
|
||||||
@org.hibernate.annotations.Table(appliesTo = "FEEDS", indexes = { @Index(name = "disabled_lastupdated_index", columnNames = {
|
|
||||||
"disabledUntil", "lastUpdated" }), })
|
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public class Feed extends AbstractModel {
|
public class Feed extends AbstractModel {
|
||||||
|
|
||||||
@@ -29,7 +25,6 @@ public class Feed extends AbstractModel {
|
|||||||
private String url;
|
private String url;
|
||||||
|
|
||||||
@Column(length = 40, nullable = false)
|
@Column(length = 40, nullable = false)
|
||||||
@Index(name = "urlHash_index")
|
|
||||||
private String urlHash;
|
private String urlHash;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -42,7 +37,6 @@ public class Feed extends AbstractModel {
|
|||||||
* Last time we tried to fetch the feed
|
* Last time we tried to fetch the feed
|
||||||
*/
|
*/
|
||||||
@Temporal(TemporalType.TIMESTAMP)
|
@Temporal(TemporalType.TIMESTAMP)
|
||||||
@Index(name = "lastupdated_index")
|
|
||||||
private Date lastUpdated;
|
private Date lastUpdated;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -78,7 +72,6 @@ public class Feed extends AbstractModel {
|
|||||||
* feed refresh is disabled until this date
|
* feed refresh is disabled until this date
|
||||||
*/
|
*/
|
||||||
@Temporal(TemporalType.TIMESTAMP)
|
@Temporal(TemporalType.TIMESTAMP)
|
||||||
@Index(name = "disableduntil_index")
|
|
||||||
private Date disabledUntil;
|
private Date disabledUntil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -120,9 +113,11 @@ public class Feed extends AbstractModel {
|
|||||||
* detected topic for pubsubhubbub
|
* detected topic for pubsubhubbub
|
||||||
*/
|
*/
|
||||||
@Column(length = 2048)
|
@Column(length = 2048)
|
||||||
@Index(name = "topic_index")
|
|
||||||
private String pushTopic;
|
private String pushTopic;
|
||||||
|
|
||||||
|
@Column(name = "push_topic_hash", length = 2048)
|
||||||
|
private String pushTopicHash;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* last time we subscribed for that topic on that hub
|
* last time we subscribed for that topic on that hub
|
||||||
*/
|
*/
|
||||||
@@ -289,4 +284,12 @@ public class Feed extends AbstractModel {
|
|||||||
this.lastEntryDate = lastEntryDate;
|
this.lastEntryDate = lastEntryDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getPushTopicHash() {
|
||||||
|
return pushTopicHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPushTopicHash(String pushTopicHash) {
|
||||||
|
this.pushTopicHash = pushTopicHash;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,9 +15,6 @@ import javax.persistence.OneToOne;
|
|||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
import javax.persistence.Temporal;
|
import javax.persistence.Temporal;
|
||||||
import javax.persistence.TemporalType;
|
import javax.persistence.TemporalType;
|
||||||
import javax.persistence.Transient;
|
|
||||||
|
|
||||||
import org.hibernate.annotations.Index;
|
|
||||||
|
|
||||||
import com.google.api.client.util.Sets;
|
import com.google.api.client.util.Sets;
|
||||||
|
|
||||||
@@ -30,7 +27,6 @@ public class FeedEntry extends AbstractModel {
|
|||||||
private String guid;
|
private String guid;
|
||||||
|
|
||||||
@Column(length = 40, nullable = false)
|
@Column(length = 40, nullable = false)
|
||||||
@Index(name = "guidHash_index")
|
|
||||||
private String guidHash;
|
private String guidHash;
|
||||||
|
|
||||||
@ManyToMany
|
@ManyToMany
|
||||||
@@ -44,15 +40,13 @@ public class FeedEntry extends AbstractModel {
|
|||||||
@Column(length = 2048)
|
@Column(length = 2048)
|
||||||
private String url;
|
private String url;
|
||||||
|
|
||||||
//@Column(length = 128)
|
@Column(name = "author", length = 128)
|
||||||
@Transient
|
|
||||||
private String author;
|
private String author;
|
||||||
|
|
||||||
@Temporal(TemporalType.TIMESTAMP)
|
@Temporal(TemporalType.TIMESTAMP)
|
||||||
private Date inserted;
|
private Date inserted;
|
||||||
|
|
||||||
@Temporal(TemporalType.TIMESTAMP)
|
@Temporal(TemporalType.TIMESTAMP)
|
||||||
@Index(name = "updated_index")
|
|
||||||
private Date updated;
|
private Date updated;
|
||||||
|
|
||||||
@OneToMany(mappedBy = "entry")
|
@OneToMany(mappedBy = "entry")
|
||||||
|
|||||||
@@ -11,8 +11,6 @@ import javax.persistence.Table;
|
|||||||
import javax.persistence.Temporal;
|
import javax.persistence.Temporal;
|
||||||
import javax.persistence.TemporalType;
|
import javax.persistence.TemporalType;
|
||||||
|
|
||||||
import org.hibernate.annotations.Index;
|
|
||||||
|
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@@ -21,11 +19,9 @@ import com.google.common.collect.Sets;
|
|||||||
public class User extends AbstractModel {
|
public class User extends AbstractModel {
|
||||||
|
|
||||||
@Column(length = 32, nullable = false, unique = true)
|
@Column(length = 32, nullable = false, unique = true)
|
||||||
@Index(name = "username_index")
|
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
@Column(length = 255, unique = true)
|
@Column(length = 255, unique = true)
|
||||||
@Index(name = "useremail_index")
|
|
||||||
private String email;
|
private String email;
|
||||||
|
|
||||||
@Column(length = 256, nullable = false)
|
@Column(length = 256, nullable = false)
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import org.apache.wicket.protocol.http.servlet.ServletWebResponse;
|
|||||||
import org.apache.wicket.request.cycle.RequestCycle;
|
import org.apache.wicket.request.cycle.RequestCycle;
|
||||||
import org.apache.wicket.util.crypt.Base64;
|
import org.apache.wicket.util.crypt.Base64;
|
||||||
|
|
||||||
|
import com.commafeed.backend.DatabaseCleaner;
|
||||||
import com.commafeed.backend.MetricsBean;
|
import com.commafeed.backend.MetricsBean;
|
||||||
import com.commafeed.backend.StartupBean;
|
import com.commafeed.backend.StartupBean;
|
||||||
import com.commafeed.backend.dao.FeedCategoryDAO;
|
import com.commafeed.backend.dao.FeedCategoryDAO;
|
||||||
@@ -124,6 +125,9 @@ public abstract class AbstractREST {
|
|||||||
@Inject
|
@Inject
|
||||||
FaviconFetcher faviconFetcher;
|
FaviconFetcher faviconFetcher;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
DatabaseCleaner cleaner;
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void init() {
|
public void init() {
|
||||||
CommaFeedApplication app = CommaFeedApplication.get();
|
CommaFeedApplication app = CommaFeedApplication.get();
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.commafeed.frontend.rest.resources;
|
|||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.ws.rs.DefaultValue;
|
import javax.ws.rs.DefaultValue;
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
@@ -189,4 +190,12 @@ public class AdminREST extends AbstractResourceREST {
|
|||||||
|
|
||||||
return Response.ok(map).build();
|
return Response.ok(map).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Path("/cleanup")
|
||||||
|
@GET
|
||||||
|
public Response cleanup() {
|
||||||
|
cleaner.cleanOlderThan(30, TimeUnit.DAYS);
|
||||||
|
return Response.ok("ok").build();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -187,5 +187,27 @@
|
|||||||
<dropTable tableName="FEEDPUSHINFOS" />
|
<dropTable tableName="FEEDPUSHINFOS" />
|
||||||
</changeSet>
|
</changeSet>
|
||||||
|
|
||||||
|
<changeSet author="athou" id="add-topic-hash">
|
||||||
|
<addColumn tableName="FEEDS">
|
||||||
|
<column name="push_topic_hash" type="VARCHAR(40)" />
|
||||||
|
</addColumn>
|
||||||
|
|
||||||
|
<createIndex tableName="FEEDS" indexName="push_topic_hash_index">
|
||||||
|
<column name="push_topic_hash"></column>
|
||||||
|
</createIndex>
|
||||||
|
</changeSet>
|
||||||
|
|
||||||
|
<changeSet author="athou" id="add-author">
|
||||||
|
<addColumn tableName="FEEDENTRIES">
|
||||||
|
<column name="author" type="VARCHAR(128)" />
|
||||||
|
</addColumn>
|
||||||
|
</changeSet>
|
||||||
|
|
||||||
|
<changeSet author="athou" id="add-inserted-index">
|
||||||
|
<createIndex tableName="FEEDENTRIES" indexName="inserted_index">
|
||||||
|
<column name="inserted"></column>
|
||||||
|
</createIndex>
|
||||||
|
</changeSet>
|
||||||
|
|
||||||
|
|
||||||
</databaseChangeLog>
|
</databaseChangeLog>
|
||||||
|
|||||||
Reference in New Issue
Block a user