From 4dc266d3d3ce443856ec1c6b687a2c002739a0bf Mon Sep 17 00:00:00 2001 From: nkanaev Date: Thu, 18 Jun 2026 12:07:52 +0100 Subject: [PATCH] storage test fixes --- src/storage/model/model.go | 6 ++++++ src/storage/postgres/item.go | 39 ++++++++++++++++++++++++++++++++++ src/storage/sqlite/item.go | 29 +++++++++++++++++++++++++ src/storage/storage.go | 2 ++ src/storage/tests/item_test.go | 10 +++++++-- 5 files changed, 84 insertions(+), 2 deletions(-) diff --git a/src/storage/model/model.go b/src/storage/model/model.go index c127ab9..94465bd 100644 --- a/src/storage/model/model.go +++ b/src/storage/model/model.go @@ -90,6 +90,12 @@ type ItemFilter struct { Before *time.Time } +type UpdateItemParams struct { + Title *string + Status *ItemStatus + LastArrived *time.Time +} + type MarkFilter struct { FolderID *int64 FeedID *int64 diff --git a/src/storage/postgres/item.go b/src/storage/postgres/item.go index 252a57b..7eeacd2 100644 --- a/src/storage/postgres/item.go +++ b/src/storage/postgres/item.go @@ -250,6 +250,45 @@ func (s *PostgresStorage) GetItem(id int64) *model.Item { return i } +func (s *PostgresStorage) UpdateItem(id int64, params model.UpdateItemParams) bool { + sets := make([]string, 0) + args := make([]any, 0) + n := 0 + + if params.Title != nil { + n++ + sets = append(sets, fmt.Sprintf("title = $%d", n)) + args = append(args, *params.Title) + n++ + sets = append(sets, fmt.Sprintf("search = to_tsvector('simple', $%d || ' ' || coalesce((select i2.content from items i2 where i2.id = $%d), ''))", n-1, n)) + args = append(args, id) + } + if params.Status != nil { + n++ + sets = append(sets, fmt.Sprintf("status = $%d", n)) + args = append(args, *params.Status) + } + if params.LastArrived != nil { + n++ + sets = append(sets, fmt.Sprintf("last_arrived = $%d", n)) + args = append(args, *params.LastArrived) + } + if len(sets) == 0 { + return true + } + + n++ + args = append(args, id) + query := fmt.Sprintf("update items set %s where id = $%d", strings.Join(sets, ", "), n) + _, err := s.db.Exec(query, args...) + return err == nil +} + +func (s *PostgresStorage) DeleteItem(id int64) bool { + _, err := s.db.Exec(`delete from items where id = $1`, id) + return err == nil +} + func (s *PostgresStorage) UpdateItemStatus(item_id int64, status model.ItemStatus) bool { _, err := s.db.Exec(`update items set status = $2 where id = $1`, item_id, diff --git a/src/storage/sqlite/item.go b/src/storage/sqlite/item.go index fbb0762..32795e0 100644 --- a/src/storage/sqlite/item.go +++ b/src/storage/sqlite/item.go @@ -242,6 +242,35 @@ func (s *SQLiteStorage) GetItem(id int64) *model.Item { return i } +func (s *SQLiteStorage) UpdateItem(id int64, params model.UpdateItemParams) bool { + sets := make([]string, 0) + args := make([]any, 0) + if params.Title != nil { + sets = append(sets, "title = :title") + args = append(args, sql.Named("title", *params.Title)) + } + if params.Status != nil { + sets = append(sets, "status = :status") + args = append(args, sql.Named("status", *params.Status)) + } + if params.LastArrived != nil { + sets = append(sets, "last_arrived = :last_arrived") + args = append(args, sql.Named("last_arrived", *params.LastArrived)) + } + if len(sets) == 0 { + return true + } + args = append(args, sql.Named("id", id)) + query := fmt.Sprintf("update items set %s where id = :id", strings.Join(sets, ", ")) + _, err := s.db.Exec(query, args...) + return err == nil +} + +func (s *SQLiteStorage) DeleteItem(id int64) bool { + _, err := s.db.Exec(`delete from items where id = :id`, sql.Named("id", id)) + return err == nil +} + func (s *SQLiteStorage) UpdateItemStatus(item_id int64, status model.ItemStatus) bool { _, err := s.db.Exec(`update items set status = :status where id = :id`, sql.Named("status", status), diff --git a/src/storage/storage.go b/src/storage/storage.go index 47bef6b..d42d15d 100644 --- a/src/storage/storage.go +++ b/src/storage/storage.go @@ -15,6 +15,7 @@ type Storage interface { CreateFolder(title string) *model.Folder CreateItems(items []model.Item) bool DeleteFeed(feedId int64) bool + DeleteItem(id int64) bool DeleteFolder(folderId int64) bool DeleteOldItems() FeedStats() []model.FeedStat @@ -30,6 +31,7 @@ type Storage interface { UpdateFeed(feedId int64, params model.UpdateFeedParams) (bool, error) UpdateFeedState(feedID int64, params model.UpdateFeedStateParams) (bool, error) UpdateFolder(folderId int64, params model.UpdateFolderParams) (bool, error) + UpdateItem(id int64, params model.UpdateItemParams) bool UpdateItemStatus(item_id int64, status model.ItemStatus) bool UpdateSettings(params model.UpdateSettingsParams) bool } diff --git a/src/storage/tests/item_test.go b/src/storage/tests/item_test.go index d34e4ef..856c536 100644 --- a/src/storage/tests/item_test.go +++ b/src/storage/tests/item_test.go @@ -490,6 +490,11 @@ func TestSearch(t *testing.T) { }, }) + itemsByGUID := make(map[string]model.Item) + for _, item := range db.ListItems(model.ItemFilter{}, 1000, false, false) { + itemsByGUID[item.GUID] = item + } + // 1. Basic search s1 := "emergency" have := getItemGuids(db.ListItems(model.ItemFilter{Search: &s1}, 10, true, false)) @@ -531,7 +536,7 @@ func TestSearch(t *testing.T) { } // 5. Trigger: Update - db.db.Exec("update items set title = 'Updated Title' where guid = 'i1'") + db.UpdateItem(MustGet(itemsByGUID, "i1").Id, model.UpdateItemParams{Title: ptr("Updated Title")}) s7 := "Updated" have = getItemGuids(db.ListItems(model.ItemFilter{Search: &s7}, 10, true, false)) if !reflect.DeepEqual(have, []string{"i1"}) { @@ -539,7 +544,8 @@ func TestSearch(t *testing.T) { } // 6. Trigger: Delete - db.db.Exec("delete from items where guid = 'i1'") + // db.db.Exec("delete from items where guid = 'i1'") + db.DeleteItem(MustGet(itemsByGUID, "i1").Id) have = getItemGuids(db.ListItems(model.ItemFilter{Search: &s7}, 10, true, false)) if len(have) > 0 { t.Errorf("delete trigger failed: found deleted item: %v", have)