ソースを参照

Make sure that items marked as removed are not shown

Frédéric Guillot 8 年 前
コミット
4fc18647ca

+ 8 - 0
server/ui/controller/category.go

@@ -13,6 +13,7 @@ import (
 	"github.com/miniflux/miniflux2/server/ui/form"
 	"github.com/miniflux/miniflux2/server/ui/form"
 )
 )
 
 
+// ShowCategories shows the page with all categories.
 func (c *Controller) ShowCategories(ctx *core.Context, request *core.Request, response *core.Response) {
 func (c *Controller) ShowCategories(ctx *core.Context, request *core.Request, response *core.Response) {
 	args, err := c.getCommonTemplateArgs(ctx)
 	args, err := c.getCommonTemplateArgs(ctx)
 	if err != nil {
 	if err != nil {
@@ -34,6 +35,7 @@ func (c *Controller) ShowCategories(ctx *core.Context, request *core.Request, re
 	}))
 	}))
 }
 }
 
 
+// ShowCategoryEntries shows all entries for the given category.
 func (c *Controller) ShowCategoryEntries(ctx *core.Context, request *core.Request, response *core.Response) {
 func (c *Controller) ShowCategoryEntries(ctx *core.Context, request *core.Request, response *core.Response) {
 	user := ctx.GetLoggedUser()
 	user := ctx.GetLoggedUser()
 	offset := request.GetQueryIntegerParam("offset", 0)
 	offset := request.GetQueryIntegerParam("offset", 0)
@@ -53,6 +55,7 @@ func (c *Controller) ShowCategoryEntries(ctx *core.Context, request *core.Reques
 	builder.WithCategoryID(category.ID)
 	builder.WithCategoryID(category.ID)
 	builder.WithOrder(model.DefaultSortingOrder)
 	builder.WithOrder(model.DefaultSortingOrder)
 	builder.WithDirection(model.DefaultSortingDirection)
 	builder.WithDirection(model.DefaultSortingDirection)
+	builder.WithoutStatus(model.EntryStatusRemoved)
 	builder.WithOffset(offset)
 	builder.WithOffset(offset)
 	builder.WithLimit(NbItemsPerPage)
 	builder.WithLimit(NbItemsPerPage)
 
 
@@ -77,6 +80,7 @@ func (c *Controller) ShowCategoryEntries(ctx *core.Context, request *core.Reques
 	}))
 	}))
 }
 }
 
 
+// CreateCategory shows the form to create a new category.
 func (c *Controller) CreateCategory(ctx *core.Context, request *core.Request, response *core.Response) {
 func (c *Controller) CreateCategory(ctx *core.Context, request *core.Request, response *core.Response) {
 	args, err := c.getCommonTemplateArgs(ctx)
 	args, err := c.getCommonTemplateArgs(ctx)
 	if err != nil {
 	if err != nil {
@@ -89,6 +93,7 @@ func (c *Controller) CreateCategory(ctx *core.Context, request *core.Request, re
 	}))
 	}))
 }
 }
 
 
+// SaveCategory validate and save the new category into the database.
 func (c *Controller) SaveCategory(ctx *core.Context, request *core.Request, response *core.Response) {
 func (c *Controller) SaveCategory(ctx *core.Context, request *core.Request, response *core.Response) {
 	user := ctx.GetLoggedUser()
 	user := ctx.GetLoggedUser()
 	args, err := c.getCommonTemplateArgs(ctx)
 	args, err := c.getCommonTemplateArgs(ctx)
@@ -131,6 +136,7 @@ func (c *Controller) SaveCategory(ctx *core.Context, request *core.Request, resp
 	response.Redirect(ctx.GetRoute("categories"))
 	response.Redirect(ctx.GetRoute("categories"))
 }
 }
 
 
+// EditCategory shows the form to modify a category.
 func (c *Controller) EditCategory(ctx *core.Context, request *core.Request, response *core.Response) {
 func (c *Controller) EditCategory(ctx *core.Context, request *core.Request, response *core.Response) {
 	user := ctx.GetLoggedUser()
 	user := ctx.GetLoggedUser()
 
 
@@ -149,6 +155,7 @@ func (c *Controller) EditCategory(ctx *core.Context, request *core.Request, resp
 	response.Html().Render("edit_category", args)
 	response.Html().Render("edit_category", args)
 }
 }
 
 
+// UpdateCategory validate and update a category.
 func (c *Controller) UpdateCategory(ctx *core.Context, request *core.Request, response *core.Response) {
 func (c *Controller) UpdateCategory(ctx *core.Context, request *core.Request, response *core.Response) {
 	user := ctx.GetLoggedUser()
 	user := ctx.GetLoggedUser()
 
 
@@ -191,6 +198,7 @@ func (c *Controller) UpdateCategory(ctx *core.Context, request *core.Request, re
 	response.Redirect(ctx.GetRoute("categories"))
 	response.Redirect(ctx.GetRoute("categories"))
 }
 }
 
 
+// RemoveCategory delete a category from the database.
 func (c *Controller) RemoveCategory(ctx *core.Context, request *core.Request, response *core.Response) {
 func (c *Controller) RemoveCategory(ctx *core.Context, request *core.Request, response *core.Response) {
 	user := ctx.GetLoggedUser()
 	user := ctx.GetLoggedUser()
 
 

+ 14 - 3
server/ui/controller/entry.go

@@ -33,6 +33,7 @@ func (c *Controller) ShowFeedEntry(ctx *core.Context, request *core.Request, res
 	builder := c.store.GetEntryQueryBuilder(user.ID, user.Timezone)
 	builder := c.store.GetEntryQueryBuilder(user.ID, user.Timezone)
 	builder.WithFeedID(feedID)
 	builder.WithFeedID(feedID)
 	builder.WithEntryID(entryID)
 	builder.WithEntryID(entryID)
+	builder.WithoutStatus(model.EntryStatusRemoved)
 
 
 	entry, err := builder.GetEntry()
 	entry, err := builder.GetEntry()
 	if err != nil {
 	if err != nil {
@@ -52,6 +53,7 @@ func (c *Controller) ShowFeedEntry(ctx *core.Context, request *core.Request, res
 	}
 	}
 
 
 	builder = c.store.GetEntryQueryBuilder(user.ID, user.Timezone)
 	builder = c.store.GetEntryQueryBuilder(user.ID, user.Timezone)
+	builder.WithoutStatus(model.EntryStatusRemoved)
 	builder.WithFeedID(feedID)
 	builder.WithFeedID(feedID)
 	builder.WithCondition("e.id", "!=", entryID)
 	builder.WithCondition("e.id", "!=", entryID)
 	builder.WithCondition("e.published_at", "<=", entry.Date)
 	builder.WithCondition("e.published_at", "<=", entry.Date)
@@ -64,6 +66,7 @@ func (c *Controller) ShowFeedEntry(ctx *core.Context, request *core.Request, res
 	}
 	}
 
 
 	builder = c.store.GetEntryQueryBuilder(user.ID, user.Timezone)
 	builder = c.store.GetEntryQueryBuilder(user.ID, user.Timezone)
+	builder.WithoutStatus(model.EntryStatusRemoved)
 	builder.WithFeedID(feedID)
 	builder.WithFeedID(feedID)
 	builder.WithCondition("e.id", "!=", entryID)
 	builder.WithCondition("e.id", "!=", entryID)
 	builder.WithCondition("e.published_at", ">=", entry.Date)
 	builder.WithCondition("e.published_at", ">=", entry.Date)
@@ -88,8 +91,7 @@ func (c *Controller) ShowFeedEntry(ctx *core.Context, request *core.Request, res
 	if entry.Status == model.EntryStatusUnread {
 	if entry.Status == model.EntryStatusUnread {
 		err = c.store.SetEntriesStatus(user.ID, []int64{entry.ID}, model.EntryStatusRead)
 		err = c.store.SetEntriesStatus(user.ID, []int64{entry.ID}, model.EntryStatusRead)
 		if err != nil {
 		if err != nil {
-			log.Println(err)
-			response.Html().ServerError(nil)
+			response.Html().ServerError(err)
 			return
 			return
 		}
 		}
 	}
 	}
@@ -124,6 +126,7 @@ func (c *Controller) ShowCategoryEntry(ctx *core.Context, request *core.Request,
 	builder := c.store.GetEntryQueryBuilder(user.ID, user.Timezone)
 	builder := c.store.GetEntryQueryBuilder(user.ID, user.Timezone)
 	builder.WithCategoryID(categoryID)
 	builder.WithCategoryID(categoryID)
 	builder.WithEntryID(entryID)
 	builder.WithEntryID(entryID)
+	builder.WithoutStatus(model.EntryStatusRemoved)
 
 
 	entry, err := builder.GetEntry()
 	entry, err := builder.GetEntry()
 	if err != nil {
 	if err != nil {
@@ -143,6 +146,7 @@ func (c *Controller) ShowCategoryEntry(ctx *core.Context, request *core.Request,
 	}
 	}
 
 
 	builder = c.store.GetEntryQueryBuilder(user.ID, user.Timezone)
 	builder = c.store.GetEntryQueryBuilder(user.ID, user.Timezone)
+	builder.WithoutStatus(model.EntryStatusRemoved)
 	builder.WithCategoryID(categoryID)
 	builder.WithCategoryID(categoryID)
 	builder.WithCondition("e.id", "!=", entryID)
 	builder.WithCondition("e.id", "!=", entryID)
 	builder.WithCondition("e.published_at", "<=", entry.Date)
 	builder.WithCondition("e.published_at", "<=", entry.Date)
@@ -155,6 +159,7 @@ func (c *Controller) ShowCategoryEntry(ctx *core.Context, request *core.Request,
 	}
 	}
 
 
 	builder = c.store.GetEntryQueryBuilder(user.ID, user.Timezone)
 	builder = c.store.GetEntryQueryBuilder(user.ID, user.Timezone)
+	builder.WithoutStatus(model.EntryStatusRemoved)
 	builder.WithCategoryID(categoryID)
 	builder.WithCategoryID(categoryID)
 	builder.WithCondition("e.id", "!=", entryID)
 	builder.WithCondition("e.id", "!=", entryID)
 	builder.WithCondition("e.published_at", ">=", entry.Date)
 	builder.WithCondition("e.published_at", ">=", entry.Date)
@@ -208,6 +213,7 @@ func (c *Controller) ShowUnreadEntry(ctx *core.Context, request *core.Request, r
 
 
 	builder := c.store.GetEntryQueryBuilder(user.ID, user.Timezone)
 	builder := c.store.GetEntryQueryBuilder(user.ID, user.Timezone)
 	builder.WithEntryID(entryID)
 	builder.WithEntryID(entryID)
+	builder.WithoutStatus(model.EntryStatusRemoved)
 
 
 	entry, err := builder.GetEntry()
 	entry, err := builder.GetEntry()
 	if err != nil {
 	if err != nil {
@@ -227,6 +233,7 @@ func (c *Controller) ShowUnreadEntry(ctx *core.Context, request *core.Request, r
 	}
 	}
 
 
 	builder = c.store.GetEntryQueryBuilder(user.ID, user.Timezone)
 	builder = c.store.GetEntryQueryBuilder(user.ID, user.Timezone)
+	builder.WithoutStatus(model.EntryStatusRemoved)
 	builder.WithStatus(model.EntryStatusUnread)
 	builder.WithStatus(model.EntryStatusUnread)
 	builder.WithCondition("e.id", "!=", entryID)
 	builder.WithCondition("e.id", "!=", entryID)
 	builder.WithCondition("e.published_at", "<=", entry.Date)
 	builder.WithCondition("e.published_at", "<=", entry.Date)
@@ -239,6 +246,7 @@ func (c *Controller) ShowUnreadEntry(ctx *core.Context, request *core.Request, r
 	}
 	}
 
 
 	builder = c.store.GetEntryQueryBuilder(user.ID, user.Timezone)
 	builder = c.store.GetEntryQueryBuilder(user.ID, user.Timezone)
+	builder.WithoutStatus(model.EntryStatusRemoved)
 	builder.WithStatus(model.EntryStatusUnread)
 	builder.WithStatus(model.EntryStatusUnread)
 	builder.WithCondition("e.id", "!=", entryID)
 	builder.WithCondition("e.id", "!=", entryID)
 	builder.WithCondition("e.published_at", ">=", entry.Date)
 	builder.WithCondition("e.published_at", ">=", entry.Date)
@@ -292,6 +300,7 @@ func (c *Controller) ShowReadEntry(ctx *core.Context, request *core.Request, res
 
 
 	builder := c.store.GetEntryQueryBuilder(user.ID, user.Timezone)
 	builder := c.store.GetEntryQueryBuilder(user.ID, user.Timezone)
 	builder.WithEntryID(entryID)
 	builder.WithEntryID(entryID)
+	builder.WithoutStatus(model.EntryStatusRemoved)
 
 
 	entry, err := builder.GetEntry()
 	entry, err := builder.GetEntry()
 	if err != nil {
 	if err != nil {
@@ -311,6 +320,7 @@ func (c *Controller) ShowReadEntry(ctx *core.Context, request *core.Request, res
 	}
 	}
 
 
 	builder = c.store.GetEntryQueryBuilder(user.ID, user.Timezone)
 	builder = c.store.GetEntryQueryBuilder(user.ID, user.Timezone)
+	builder.WithoutStatus(model.EntryStatusRemoved)
 	builder.WithStatus(model.EntryStatusRead)
 	builder.WithStatus(model.EntryStatusRead)
 	builder.WithCondition("e.id", "!=", entryID)
 	builder.WithCondition("e.id", "!=", entryID)
 	builder.WithCondition("e.published_at", "<=", entry.Date)
 	builder.WithCondition("e.published_at", "<=", entry.Date)
@@ -323,6 +333,7 @@ func (c *Controller) ShowReadEntry(ctx *core.Context, request *core.Request, res
 	}
 	}
 
 
 	builder = c.store.GetEntryQueryBuilder(user.ID, user.Timezone)
 	builder = c.store.GetEntryQueryBuilder(user.ID, user.Timezone)
+	builder.WithoutStatus(model.EntryStatusRemoved)
 	builder.WithStatus(model.EntryStatusRead)
 	builder.WithStatus(model.EntryStatusRead)
 	builder.WithCondition("e.id", "!=", entryID)
 	builder.WithCondition("e.id", "!=", entryID)
 	builder.WithCondition("e.published_at", ">=", entry.Date)
 	builder.WithCondition("e.published_at", ">=", entry.Date)
@@ -354,7 +365,7 @@ func (c *Controller) ShowReadEntry(ctx *core.Context, request *core.Request, res
 	}))
 	}))
 }
 }
 
 
-// UpdateEntriesStatus handles Ajax request to update a list of entries.
+// UpdateEntriesStatus handles Ajax request to update the status for a list of entries.
 func (c *Controller) UpdateEntriesStatus(ctx *core.Context, request *core.Request, response *core.Response) {
 func (c *Controller) UpdateEntriesStatus(ctx *core.Context, request *core.Request, response *core.Response) {
 	user := ctx.GetLoggedUser()
 	user := ctx.GetLoggedUser()
 
 

+ 10 - 2
server/ui/controller/feed.go

@@ -6,12 +6,14 @@ package controller
 
 
 import (
 import (
 	"errors"
 	"errors"
+	"log"
+
 	"github.com/miniflux/miniflux2/model"
 	"github.com/miniflux/miniflux2/model"
 	"github.com/miniflux/miniflux2/server/core"
 	"github.com/miniflux/miniflux2/server/core"
 	"github.com/miniflux/miniflux2/server/ui/form"
 	"github.com/miniflux/miniflux2/server/ui/form"
-	"log"
 )
 )
 
 
+// ShowFeedsPage shows the page with all subscriptions.
 func (c *Controller) ShowFeedsPage(ctx *core.Context, request *core.Request, response *core.Response) {
 func (c *Controller) ShowFeedsPage(ctx *core.Context, request *core.Request, response *core.Response) {
 	user := ctx.GetLoggedUser()
 	user := ctx.GetLoggedUser()
 
 
@@ -34,6 +36,7 @@ func (c *Controller) ShowFeedsPage(ctx *core.Context, request *core.Request, res
 	}))
 	}))
 }
 }
 
 
+// ShowFeedEntries shows all entries for the given feed.
 func (c *Controller) ShowFeedEntries(ctx *core.Context, request *core.Request, response *core.Response) {
 func (c *Controller) ShowFeedEntries(ctx *core.Context, request *core.Request, response *core.Response) {
 	user := ctx.GetLoggedUser()
 	user := ctx.GetLoggedUser()
 	offset := request.GetQueryIntegerParam("offset", 0)
 	offset := request.GetQueryIntegerParam("offset", 0)
@@ -51,6 +54,7 @@ func (c *Controller) ShowFeedEntries(ctx *core.Context, request *core.Request, r
 
 
 	builder := c.store.GetEntryQueryBuilder(user.ID, user.Timezone)
 	builder := c.store.GetEntryQueryBuilder(user.ID, user.Timezone)
 	builder.WithFeedID(feed.ID)
 	builder.WithFeedID(feed.ID)
+	builder.WithoutStatus(model.EntryStatusRemoved)
 	builder.WithOrder(model.DefaultSortingOrder)
 	builder.WithOrder(model.DefaultSortingOrder)
 	builder.WithDirection(model.DefaultSortingDirection)
 	builder.WithDirection(model.DefaultSortingDirection)
 	builder.WithOffset(offset)
 	builder.WithOffset(offset)
@@ -77,6 +81,7 @@ func (c *Controller) ShowFeedEntries(ctx *core.Context, request *core.Request, r
 	}))
 	}))
 }
 }
 
 
+// EditFeed shows the form to modify a subscription.
 func (c *Controller) EditFeed(ctx *core.Context, request *core.Request, response *core.Response) {
 func (c *Controller) EditFeed(ctx *core.Context, request *core.Request, response *core.Response) {
 	user := ctx.GetLoggedUser()
 	user := ctx.GetLoggedUser()
 
 
@@ -94,6 +99,7 @@ func (c *Controller) EditFeed(ctx *core.Context, request *core.Request, response
 	response.Html().Render("edit_feed", args)
 	response.Html().Render("edit_feed", args)
 }
 }
 
 
+// UpdateFeed update a subscription and redirect to the feed entries page.
 func (c *Controller) UpdateFeed(ctx *core.Context, request *core.Request, response *core.Response) {
 func (c *Controller) UpdateFeed(ctx *core.Context, request *core.Request, response *core.Response) {
 	user := ctx.GetLoggedUser()
 	user := ctx.GetLoggedUser()
 
 
@@ -125,9 +131,10 @@ func (c *Controller) UpdateFeed(ctx *core.Context, request *core.Request, respon
 		return
 		return
 	}
 	}
 
 
-	response.Redirect(ctx.GetRoute("feeds"))
+	response.Redirect(ctx.GetRoute("feedEntries", "feedID", feed.ID))
 }
 }
 
 
+// RemoveFeed delete a subscription from the database and redirect to the list of feeds page.
 func (c *Controller) RemoveFeed(ctx *core.Context, request *core.Request, response *core.Response) {
 func (c *Controller) RemoveFeed(ctx *core.Context, request *core.Request, response *core.Response) {
 	feedID, err := request.GetIntegerParam("feedID")
 	feedID, err := request.GetIntegerParam("feedID")
 	if err != nil {
 	if err != nil {
@@ -144,6 +151,7 @@ func (c *Controller) RemoveFeed(ctx *core.Context, request *core.Request, respon
 	response.Redirect(ctx.GetRoute("feeds"))
 	response.Redirect(ctx.GetRoute("feeds"))
 }
 }
 
 
+// RefreshFeed refresh a subscription and redirect to the feed entries page.
 func (c *Controller) RefreshFeed(ctx *core.Context, request *core.Request, response *core.Response) {
 func (c *Controller) RefreshFeed(ctx *core.Context, request *core.Request, response *core.Response) {
 	feedID, err := request.GetIntegerParam("feedID")
 	feedID, err := request.GetIntegerParam("feedID")
 	if err != nil {
 	if err != nil {

+ 1 - 0
server/ui/controller/unread.go

@@ -9,6 +9,7 @@ import (
 	"github.com/miniflux/miniflux2/server/core"
 	"github.com/miniflux/miniflux2/server/core"
 )
 )
 
 
+// ShowUnreadPage render the page with all unread entries.
 func (c *Controller) ShowUnreadPage(ctx *core.Context, request *core.Request, response *core.Response) {
 func (c *Controller) ShowUnreadPage(ctx *core.Context, request *core.Request, response *core.Response) {
 	user := ctx.GetLoggedUser()
 	user := ctx.GetLoggedUser()
 	offset := request.GetQueryIntegerParam("offset", 0)
 	offset := request.GetQueryIntegerParam("offset", 0)

+ 29 - 24
storage/entry_query_builder.go

@@ -6,12 +6,14 @@ package storage
 
 
 import (
 import (
 	"fmt"
 	"fmt"
-	"github.com/miniflux/miniflux2/helper"
-	"github.com/miniflux/miniflux2/model"
 	"strings"
 	"strings"
 	"time"
 	"time"
+
+	"github.com/miniflux/miniflux2/helper"
+	"github.com/miniflux/miniflux2/model"
 )
 )
 
 
+// EntryQueryBuilder builds a SQL query to fetch entries.
 type EntryQueryBuilder struct {
 type EntryQueryBuilder struct {
 	store      *Storage
 	store      *Storage
 	feedID     int64
 	feedID     int64
@@ -19,73 +21,78 @@ type EntryQueryBuilder struct {
 	timezone   string
 	timezone   string
 	categoryID int64
 	categoryID int64
 	status     string
 	status     string
+	notStatus  string
 	order      string
 	order      string
 	direction  string
 	direction  string
 	limit      int
 	limit      int
 	offset     int
 	offset     int
 	entryID    int64
 	entryID    int64
-	gtEntryID  int64
-	ltEntryID  int64
 	conditions []string
 	conditions []string
 	args       []interface{}
 	args       []interface{}
 }
 }
 
 
+// WithCondition defines a new condition.
 func (e *EntryQueryBuilder) WithCondition(column, operator string, value interface{}) *EntryQueryBuilder {
 func (e *EntryQueryBuilder) WithCondition(column, operator string, value interface{}) *EntryQueryBuilder {
 	e.args = append(e.args, value)
 	e.args = append(e.args, value)
 	e.conditions = append(e.conditions, fmt.Sprintf("%s %s $%d", column, operator, len(e.args)+1))
 	e.conditions = append(e.conditions, fmt.Sprintf("%s %s $%d", column, operator, len(e.args)+1))
 	return e
 	return e
 }
 }
 
 
+// WithEntryID set the entryID.
 func (e *EntryQueryBuilder) WithEntryID(entryID int64) *EntryQueryBuilder {
 func (e *EntryQueryBuilder) WithEntryID(entryID int64) *EntryQueryBuilder {
 	e.entryID = entryID
 	e.entryID = entryID
 	return e
 	return e
 }
 }
 
 
-func (e *EntryQueryBuilder) WithEntryIDGreaterThan(entryID int64) *EntryQueryBuilder {
-	e.gtEntryID = entryID
-	return e
-}
-
-func (e *EntryQueryBuilder) WithEntryIDLowerThan(entryID int64) *EntryQueryBuilder {
-	e.ltEntryID = entryID
-	return e
-}
-
+// WithFeedID set the feedID.
 func (e *EntryQueryBuilder) WithFeedID(feedID int64) *EntryQueryBuilder {
 func (e *EntryQueryBuilder) WithFeedID(feedID int64) *EntryQueryBuilder {
 	e.feedID = feedID
 	e.feedID = feedID
 	return e
 	return e
 }
 }
 
 
+// WithCategoryID set the categoryID.
 func (e *EntryQueryBuilder) WithCategoryID(categoryID int64) *EntryQueryBuilder {
 func (e *EntryQueryBuilder) WithCategoryID(categoryID int64) *EntryQueryBuilder {
 	e.categoryID = categoryID
 	e.categoryID = categoryID
 	return e
 	return e
 }
 }
 
 
+// WithStatus set the entry status.
 func (e *EntryQueryBuilder) WithStatus(status string) *EntryQueryBuilder {
 func (e *EntryQueryBuilder) WithStatus(status string) *EntryQueryBuilder {
 	e.status = status
 	e.status = status
 	return e
 	return e
 }
 }
 
 
+// WithoutStatus set the entry status that should not be returned.
+func (e *EntryQueryBuilder) WithoutStatus(status string) *EntryQueryBuilder {
+	e.notStatus = status
+	return e
+}
+
+// WithOrder set the sorting order.
 func (e *EntryQueryBuilder) WithOrder(order string) *EntryQueryBuilder {
 func (e *EntryQueryBuilder) WithOrder(order string) *EntryQueryBuilder {
 	e.order = order
 	e.order = order
 	return e
 	return e
 }
 }
 
 
+// WithDirection set the sorting direction.
 func (e *EntryQueryBuilder) WithDirection(direction string) *EntryQueryBuilder {
 func (e *EntryQueryBuilder) WithDirection(direction string) *EntryQueryBuilder {
 	e.direction = direction
 	e.direction = direction
 	return e
 	return e
 }
 }
 
 
+// WithLimit set the limit.
 func (e *EntryQueryBuilder) WithLimit(limit int) *EntryQueryBuilder {
 func (e *EntryQueryBuilder) WithLimit(limit int) *EntryQueryBuilder {
 	e.limit = limit
 	e.limit = limit
 	return e
 	return e
 }
 }
 
 
+// WithOffset set the offset.
 func (e *EntryQueryBuilder) WithOffset(offset int) *EntryQueryBuilder {
 func (e *EntryQueryBuilder) WithOffset(offset int) *EntryQueryBuilder {
 	e.offset = offset
 	e.offset = offset
 	return e
 	return e
 }
 }
 
 
+// CountEntries count the number of entries that match the condition.
 func (e *EntryQueryBuilder) CountEntries() (count int, err error) {
 func (e *EntryQueryBuilder) CountEntries() (count int, err error) {
 	defer helper.ExecutionTime(
 	defer helper.ExecutionTime(
 		time.Now(),
 		time.Now(),
@@ -102,6 +109,7 @@ func (e *EntryQueryBuilder) CountEntries() (count int, err error) {
 	return count, nil
 	return count, nil
 }
 }
 
 
+// GetEntry returns a single entry that match the condition.
 func (e *EntryQueryBuilder) GetEntry() (*model.Entry, error) {
 func (e *EntryQueryBuilder) GetEntry() (*model.Entry, error) {
 	e.limit = 1
 	e.limit = 1
 	entries, err := e.GetEntries()
 	entries, err := e.GetEntries()
@@ -121,6 +129,7 @@ func (e *EntryQueryBuilder) GetEntry() (*model.Entry, error) {
 	return entries[0], nil
 	return entries[0], nil
 }
 }
 
 
+// GetEntries returns a list of entries that match the condition.
 func (e *EntryQueryBuilder) GetEntries() (model.Entries, error) {
 func (e *EntryQueryBuilder) GetEntries() (model.Entries, error) {
 	debugStr := "[EntryQueryBuilder:GetEntries] userID=%d, feedID=%d, categoryID=%d, status=%s, order=%s, direction=%s, offset=%d, limit=%d"
 	debugStr := "[EntryQueryBuilder:GetEntries] userID=%d, feedID=%d, categoryID=%d, status=%s, order=%s, direction=%s, offset=%d, limit=%d"
 	defer helper.ExecutionTime(time.Now(), fmt.Sprintf(debugStr, e.userID, e.feedID, e.categoryID, e.status, e.order, e.direction, e.offset, e.limit))
 	defer helper.ExecutionTime(time.Now(), fmt.Sprintf(debugStr, e.userID, e.feedID, e.categoryID, e.status, e.order, e.direction, e.offset, e.limit))
@@ -219,21 +228,16 @@ func (e *EntryQueryBuilder) buildCondition() ([]interface{}, string) {
 		args = append(args, e.entryID)
 		args = append(args, e.entryID)
 	}
 	}
 
 
-	if e.gtEntryID != 0 {
-		conditions = append(conditions, fmt.Sprintf("e.id > $%d", len(args)+1))
-		args = append(args, e.gtEntryID)
-	}
-
-	if e.ltEntryID != 0 {
-		conditions = append(conditions, fmt.Sprintf("e.id < $%d", len(args)+1))
-		args = append(args, e.ltEntryID)
-	}
-
 	if e.status != "" {
 	if e.status != "" {
 		conditions = append(conditions, fmt.Sprintf("e.status=$%d", len(args)+1))
 		conditions = append(conditions, fmt.Sprintf("e.status=$%d", len(args)+1))
 		args = append(args, e.status)
 		args = append(args, e.status)
 	}
 	}
 
 
+	if e.notStatus != "" {
+		conditions = append(conditions, fmt.Sprintf("e.status != $%d", len(args)+1))
+		args = append(args, e.notStatus)
+	}
+
 	return args, strings.Join(conditions, " AND ")
 	return args, strings.Join(conditions, " AND ")
 }
 }
 
 
@@ -259,6 +263,7 @@ func (e *EntryQueryBuilder) buildSorting() string {
 	return strings.Join(queries, " ")
 	return strings.Join(queries, " ")
 }
 }
 
 
+// NewEntryQueryBuilder returns a new EntryQueryBuilder.
 func NewEntryQueryBuilder(store *Storage, userID int64, timezone string) *EntryQueryBuilder {
 func NewEntryQueryBuilder(store *Storage, userID int64, timezone string) *EntryQueryBuilder {
 	return &EntryQueryBuilder{
 	return &EntryQueryBuilder{
 		store:    store,
 		store:    store,