Add offset and limit parameters to item queries

This commit is contained in:
Tim Van Baak 2025-02-07 07:07:11 -08:00
parent 8125275936
commit 3874abf8bd
9 changed files with 47 additions and 32 deletions

View File

@ -53,20 +53,27 @@ func feed(
} }
if showInactive { if showInactive {
items, err = core.GetAllItemsForSource(db, source) items, err = core.GetAllItemsForSource(db, source, 0, core.DefaultFeedLimit)
} else { } else {
items, err = core.GetActiveItemsForSource(db, source) items, err = core.GetActiveItemsForSource(db, source, 0, core.DefaultFeedLimit)
} }
if err != nil { if err != nil {
log.Fatalf("error: failed to fetch items from %s:, %v", source, err) log.Fatalf("error: failed to fetch items from %s:, %v", source, err)
} }
} else if channel != "" { } else if channel != "" {
log.Fatal("error: unimplemented") if showInactive {
items, err = core.GetAllItemsForChannel(db, channel, 0, core.DefaultFeedLimit)
} else {
items, err = core.GetActiveItemsForChannel(db, channel, 0, core.DefaultFeedLimit)
}
if err != nil {
log.Fatalf("error: failed to fetch items from %s:, %v", channel, err)
}
} else { } else {
if showInactive { if showInactive {
items, err = core.GetAllItems(db) items, err = core.GetAllItems(db, 0, core.DefaultFeedLimit)
} else { } else {
items, err = core.GetAllActiveItems(db) items, err = core.GetAllActiveItems(db, 0, core.DefaultFeedLimit)
} }
if err != nil { if err != nil {
log.Fatalf("error: failed to fetch items: %v", err) log.Fatalf("error: failed to fetch items: %v", err)

View File

@ -61,14 +61,14 @@ func TestChannel(t *testing.T) {
t.Fatalf("expected 1 active items in channel, got %d: %v", counts["channel"], err) t.Fatalf("expected 1 active items in channel, got %d: %v", counts["channel"], err)
} }
items, err := GetAllItemsForChannel(db, "channel") items, err := GetAllItemsForChannel(db, "channel", 0, -1)
if err != nil { if err != nil {
t.Fatalf("failed to get all items in channel: %v", err) t.Fatalf("failed to get all items in channel: %v", err)
} }
if len(items) != 2 || items[0].Id != "a" || items[1].Id != "b" { if len(items) != 2 || items[0].Id != "a" || items[1].Id != "b" {
t.Fatalf("expected two items, got %d: %v", len(items), items) t.Fatalf("expected two items, got %d: %v", len(items), items)
} }
items, err = GetActiveItemsForChannel(db, "channel") items, err = GetActiveItemsForChannel(db, "channel", 0, -1)
if err != nil { if err != nil {
t.Fatalf("failed to get all items in channel: %v", err) t.Fatalf("failed to get all items in channel: %v", err)
} }

View File

@ -99,7 +99,7 @@ func TestDeleteSourceCascade(t *testing.T) {
t.Fatalf("failed to add items: %v", err) t.Fatalf("failed to add items: %v", err)
} }
items, err := GetAllActiveItems(db) items, err := GetAllActiveItems(db, 0, -1)
if err != nil { if err != nil {
t.Fatalf("failed to get active items: %v", err) t.Fatalf("failed to get active items: %v", err)
} }
@ -110,7 +110,7 @@ func TestDeleteSourceCascade(t *testing.T) {
if err := DeleteSource(db, "source1"); err != nil { if err := DeleteSource(db, "source1"); err != nil {
t.Fatal(err) t.Fatal(err)
} }
items, err = GetAllActiveItems(db) items, err = GetAllActiveItems(db, 0, -1)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@ -192,7 +192,9 @@ func GetItem(db DB, source string, id string) (Item, error) {
return items[0], nil return items[0], nil
} }
func GetAllActiveItems(db DB) ([]Item, error) { var DefaultFeedLimit = 100
func GetAllActiveItems(db DB, offset int, limit int) ([]Item, error) {
now := int(time.Now().Unix()) // TODO pass this value in now := int(time.Now().Unix()) // TODO pass this value in
return getItems(db, ` return getItems(db, `
select select
@ -201,19 +203,21 @@ func GetAllActiveItems(db DB) ([]Item, error) {
where active <> 0 where active <> 0
and (tts = 0 or created + tts < ?) and (tts = 0 or created + tts < ?)
order by case when time = 0 then created else time end, id order by case when time = 0 then created else time end, id
`, now) limit ? offset ?
`, now, limit, offset)
} }
func GetAllItems(db DB) ([]Item, error) { func GetAllItems(db DB, offset int, limit int) ([]Item, error) {
return getItems(db, ` return getItems(db, `
select select
source, id, created, active, title, author, body, link, time, ttl, ttd, tts, json(action) source, id, created, active, title, author, body, link, time, ttl, ttd, tts, json(action)
from items from items
order by case when time = 0 then created else time end, id order by case when time = 0 then created else time end, id
`) limit ? offset ?
`, limit, offset)
} }
func GetActiveItemsForSource(db DB, source string) ([]Item, error) { func GetActiveItemsForSource(db DB, source string, offset int, limit int) ([]Item, error) {
now := int(time.Now().Unix()) // TODO pass this value in now := int(time.Now().Unix()) // TODO pass this value in
return getItems(db, ` return getItems(db, `
select select
@ -224,10 +228,11 @@ func GetActiveItemsForSource(db DB, source string) ([]Item, error) {
and active <> 0 and active <> 0
and (tts = 0 or created + tts < ?) and (tts = 0 or created + tts < ?)
order by case when time = 0 then created else time end, id order by case when time = 0 then created else time end, id
`, source, now) limit ? offset ?
`, source, now, limit, offset)
} }
func GetAllItemsForSource(db DB, source string) ([]Item, error) { func GetAllItemsForSource(db DB, source string, offset int, limit int) ([]Item, error) {
return getItems(db, ` return getItems(db, `
select select
source, id, created, active, title, author, body, link, time, ttl, ttd, tts, json(action) source, id, created, active, title, author, body, link, time, ttl, ttd, tts, json(action)
@ -235,10 +240,11 @@ func GetAllItemsForSource(db DB, source string) ([]Item, error) {
where where
source = ? source = ?
order by case when time = 0 then created else time end, id order by case when time = 0 then created else time end, id
`, source) limit ? offset ?
`, source, limit, offset)
} }
func GetActiveItemsForChannel(db DB, channel string) ([]Item, error) { func GetActiveItemsForChannel(db DB, channel string, offset int, limit int) ([]Item, error) {
now := int(time.Now().Unix()) // TODO pass this value in now := int(time.Now().Unix()) // TODO pass this value in
return getItems(db, ` return getItems(db, `
select select
@ -250,10 +256,11 @@ func GetActiveItemsForChannel(db DB, channel string) ([]Item, error) {
and i.active <> 0 and i.active <> 0
and (i.tts = 0 or i.created + i.tts < ?) and (i.tts = 0 or i.created + i.tts < ?)
order by case when i.time = 0 then i.created else i.time end, i.id order by case when i.time = 0 then i.created else i.time end, i.id
`, channel, now) limit ? offset ?
`, channel, now, limit, offset)
} }
func GetAllItemsForChannel(db DB, channel string) ([]Item, error) { func GetAllItemsForChannel(db DB, channel string, offset int, limit int) ([]Item, error) {
return getItems(db, ` return getItems(db, `
select select
i.source, i.id, i.created, i.active, i.title, i.author, i.body, i.link, i.time, i.ttl, i.ttd, i.tts, json(i.action) i.source, i.id, i.created, i.active, i.title, i.author, i.body, i.link, i.time, i.ttl, i.ttd, i.tts, json(i.action)
@ -262,5 +269,6 @@ func GetAllItemsForChannel(db DB, channel string) ([]Item, error) {
where where
c.name = ? c.name = ?
order by case when i.time = 0 then i.created else i.time end, i.id order by case when i.time = 0 then i.created else i.time end, i.id
`, channel) limit ? offset ?
`, channel, limit, offset)
} }

View File

@ -37,7 +37,7 @@ func TestAddItem(t *testing.T) {
}); err != nil { }); err != nil {
t.Fatalf("failed to add items: %v", err) t.Fatalf("failed to add items: %v", err)
} }
items, err := GetActiveItemsForSource(db, "test") items, err := GetActiveItemsForSource(db, "test", 0, -1)
if err != nil { if err != nil {
t.Fatalf("failed to get active items: %v", err) t.Fatalf("failed to get active items: %v", err)
} }
@ -51,7 +51,7 @@ func TestAddItem(t *testing.T) {
if _, err = DeactivateItem(db, "test", "one"); err != nil { if _, err = DeactivateItem(db, "test", "one"); err != nil {
t.Fatal(err) t.Fatal(err)
} }
items, err = GetActiveItemsForSource(db, "test") items, err = GetActiveItemsForSource(db, "test", 0, -1)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -59,7 +59,7 @@ func TestAddItem(t *testing.T) {
t.Fatal("should get one item") t.Fatal("should get one item")
} }
items, err = GetAllItemsForSource(db, "test") items, err = GetAllItemsForSource(db, "test", 0, -1)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -83,7 +83,7 @@ func TestAddItem(t *testing.T) {
t.Fatal("expected no deletion") t.Fatal("expected no deletion")
} }
items, err = GetAllItemsForSource(db, "test") items, err = GetAllItemsForSource(db, "test", 0, -1)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@ -142,8 +142,8 @@ func updateWithFetchedItemsTx(
items []Item, items []Item,
now time.Time, now time.Time,
) (int, int, error) { ) (int, int, error) {
// Get the existing items // Get all existing items
existingItems, err := GetAllItemsForSource(db, source) existingItems, err := GetAllItemsForSource(db, source, 0, -1)
if err != nil { if err != nil {
return 0, 0, err return 0, 0, err
} }

View File

@ -124,7 +124,7 @@ func TestUpdateSourceTransaction(t *testing.T) {
} }
// Failure should not add b // Failure should not add b
items, err := GetAllItemsForSource(db, "s") items, err := GetAllItemsForSource(db, "s", 0, -1)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@ -14,9 +14,9 @@ func (env *Env) getChannel(writer http.ResponseWriter, req *http.Request) {
var err error var err error
inactive := req.URL.Query().Get("inactive") == "1" inactive := req.URL.Query().Get("inactive") == "1"
if inactive { if inactive {
items, err = core.GetAllItemsForChannel(env.db, channel) items, err = core.GetAllItemsForChannel(env.db, channel, 0, core.DefaultFeedLimit)
} else { } else {
items, err = core.GetActiveItemsForChannel(env.db, channel) items, err = core.GetActiveItemsForChannel(env.db, channel, 0, core.DefaultFeedLimit)
} }
if err != nil { if err != nil {
http.Error(writer, err.Error(), 500) http.Error(writer, err.Error(), 500)

View File

@ -18,9 +18,9 @@ func (env *Env) getSource(writer http.ResponseWriter, req *http.Request) {
var err error var err error
inactive := req.URL.Query().Get("inactive") == "1" inactive := req.URL.Query().Get("inactive") == "1"
if inactive { if inactive {
items, err = core.GetAllItemsForSource(env.db, source) items, err = core.GetAllItemsForSource(env.db, source, 0, core.DefaultFeedLimit)
} else { } else {
items, err = core.GetActiveItemsForSource(env.db, source) items, err = core.GetActiveItemsForSource(env.db, source, 0, core.DefaultFeedLimit)
} }
if err != nil { if err != nil {
http.Error(writer, err.Error(), 500) http.Error(writer, err.Error(), 500)