From 3874abf8bdfee210d409833f251cde44ea66a792 Mon Sep 17 00:00:00 2001 From: Tim Van Baak Date: Fri, 7 Feb 2025 07:07:11 -0800 Subject: [PATCH] Add offset and limit parameters to item queries --- cmd/feed.go | 17 ++++++++++++----- core/channel_test.go | 4 ++-- core/db_test.go | 4 ++-- core/items.go | 32 ++++++++++++++++++++------------ core/items_test.go | 8 ++++---- core/source.go | 4 ++-- core/source_test.go | 2 +- web/channel.go | 4 ++-- web/source.go | 4 ++-- 9 files changed, 47 insertions(+), 32 deletions(-) diff --git a/cmd/feed.go b/cmd/feed.go index 2763af1..b914189 100644 --- a/cmd/feed.go +++ b/cmd/feed.go @@ -53,20 +53,27 @@ func feed( } if showInactive { - items, err = core.GetAllItemsForSource(db, source) + items, err = core.GetAllItemsForSource(db, source, 0, core.DefaultFeedLimit) } else { - items, err = core.GetActiveItemsForSource(db, source) + items, err = core.GetActiveItemsForSource(db, source, 0, core.DefaultFeedLimit) } if err != nil { log.Fatalf("error: failed to fetch items from %s:, %v", source, err) } } 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 { if showInactive { - items, err = core.GetAllItems(db) + items, err = core.GetAllItems(db, 0, core.DefaultFeedLimit) } else { - items, err = core.GetAllActiveItems(db) + items, err = core.GetAllActiveItems(db, 0, core.DefaultFeedLimit) } if err != nil { log.Fatalf("error: failed to fetch items: %v", err) diff --git a/core/channel_test.go b/core/channel_test.go index 3814ae8..2cc3b09 100644 --- a/core/channel_test.go +++ b/core/channel_test.go @@ -61,14 +61,14 @@ func TestChannel(t *testing.T) { 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 { t.Fatalf("failed to get all items in channel: %v", err) } if len(items) != 2 || items[0].Id != "a" || items[1].Id != "b" { 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 { t.Fatalf("failed to get all items in channel: %v", err) } diff --git a/core/db_test.go b/core/db_test.go index 7dda336..e8d31b5 100644 --- a/core/db_test.go +++ b/core/db_test.go @@ -99,7 +99,7 @@ func TestDeleteSourceCascade(t *testing.T) { t.Fatalf("failed to add items: %v", err) } - items, err := GetAllActiveItems(db) + items, err := GetAllActiveItems(db, 0, -1) if err != nil { 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 { t.Fatal(err) } - items, err = GetAllActiveItems(db) + items, err = GetAllActiveItems(db, 0, -1) if err != nil { t.Fatal(err) } diff --git a/core/items.go b/core/items.go index ba1b40f..7a0a1f5 100644 --- a/core/items.go +++ b/core/items.go @@ -192,7 +192,9 @@ func GetItem(db DB, source string, id string) (Item, error) { 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 return getItems(db, ` select @@ -201,19 +203,21 @@ func GetAllActiveItems(db DB) ([]Item, error) { where active <> 0 and (tts = 0 or created + tts < ?) 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, ` select source, id, created, active, title, author, body, link, time, ttl, ttd, tts, json(action) from items 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 return getItems(db, ` select @@ -224,10 +228,11 @@ func GetActiveItemsForSource(db DB, source string) ([]Item, error) { and active <> 0 and (tts = 0 or created + tts < ?) 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, ` select 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 source = ? 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 return getItems(db, ` select @@ -250,10 +256,11 @@ func GetActiveItemsForChannel(db DB, channel string) ([]Item, error) { and i.active <> 0 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 - `, 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, ` 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) @@ -262,5 +269,6 @@ func GetAllItemsForChannel(db DB, channel string) ([]Item, error) { where c.name = ? order by case when i.time = 0 then i.created else i.time end, i.id - `, channel) + limit ? offset ? + `, channel, limit, offset) } diff --git a/core/items_test.go b/core/items_test.go index 9e1128b..295f541 100644 --- a/core/items_test.go +++ b/core/items_test.go @@ -37,7 +37,7 @@ func TestAddItem(t *testing.T) { }); err != nil { t.Fatalf("failed to add items: %v", err) } - items, err := GetActiveItemsForSource(db, "test") + items, err := GetActiveItemsForSource(db, "test", 0, -1) if err != nil { 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 { t.Fatal(err) } - items, err = GetActiveItemsForSource(db, "test") + items, err = GetActiveItemsForSource(db, "test", 0, -1) if err != nil { t.Fatal(err) } @@ -59,7 +59,7 @@ func TestAddItem(t *testing.T) { t.Fatal("should get one item") } - items, err = GetAllItemsForSource(db, "test") + items, err = GetAllItemsForSource(db, "test", 0, -1) if err != nil { t.Fatal(err) } @@ -83,7 +83,7 @@ func TestAddItem(t *testing.T) { t.Fatal("expected no deletion") } - items, err = GetAllItemsForSource(db, "test") + items, err = GetAllItemsForSource(db, "test", 0, -1) if err != nil { t.Fatal(err) } diff --git a/core/source.go b/core/source.go index a738d4c..d29e068 100644 --- a/core/source.go +++ b/core/source.go @@ -142,8 +142,8 @@ func updateWithFetchedItemsTx( items []Item, now time.Time, ) (int, int, error) { - // Get the existing items - existingItems, err := GetAllItemsForSource(db, source) + // Get all existing items + existingItems, err := GetAllItemsForSource(db, source, 0, -1) if err != nil { return 0, 0, err } diff --git a/core/source_test.go b/core/source_test.go index 9d30e83..eb1812a 100644 --- a/core/source_test.go +++ b/core/source_test.go @@ -124,7 +124,7 @@ func TestUpdateSourceTransaction(t *testing.T) { } // Failure should not add b - items, err := GetAllItemsForSource(db, "s") + items, err := GetAllItemsForSource(db, "s", 0, -1) if err != nil { t.Fatal(err) } diff --git a/web/channel.go b/web/channel.go index fa7a615..724c7ed 100644 --- a/web/channel.go +++ b/web/channel.go @@ -14,9 +14,9 @@ func (env *Env) getChannel(writer http.ResponseWriter, req *http.Request) { var err error inactive := req.URL.Query().Get("inactive") == "1" if inactive { - items, err = core.GetAllItemsForChannel(env.db, channel) + items, err = core.GetAllItemsForChannel(env.db, channel, 0, core.DefaultFeedLimit) } else { - items, err = core.GetActiveItemsForChannel(env.db, channel) + items, err = core.GetActiveItemsForChannel(env.db, channel, 0, core.DefaultFeedLimit) } if err != nil { http.Error(writer, err.Error(), 500) diff --git a/web/source.go b/web/source.go index f35e0b2..11ad133 100644 --- a/web/source.go +++ b/web/source.go @@ -18,9 +18,9 @@ func (env *Env) getSource(writer http.ResponseWriter, req *http.Request) { var err error inactive := req.URL.Query().Get("inactive") == "1" if inactive { - items, err = core.GetAllItemsForSource(env.db, source) + items, err = core.GetAllItemsForSource(env.db, source, 0, core.DefaultFeedLimit) } else { - items, err = core.GetActiveItemsForSource(env.db, source) + items, err = core.GetActiveItemsForSource(env.db, source, 0, core.DefaultFeedLimit) } if err != nil { http.Error(writer, err.Error(), 500)