From 6bd9449baf8296083e9e989c84f9e1fff5d231d6 Mon Sep 17 00:00:00 2001 From: Tim Van Baak Date: Thu, 16 Jan 2025 22:02:03 -0800 Subject: [PATCH] Add deactivate command --- cmd/deactivate.go | 53 +++++++++++++++++++++++++++++++++++++++++++++++ core/db.go | 28 +++++++++++++++---------- core/db_test.go | 2 +- 3 files changed, 71 insertions(+), 12 deletions(-) create mode 100644 cmd/deactivate.go diff --git a/cmd/deactivate.go b/cmd/deactivate.go new file mode 100644 index 0000000..d5665b9 --- /dev/null +++ b/cmd/deactivate.go @@ -0,0 +1,53 @@ +package cmd + +import ( + "database/sql" + "fmt" + "log" + + "github.com/Jaculabilis/intake/core" + _ "github.com/mattn/go-sqlite3" + "github.com/spf13/cobra" +) + +var deactivateCmd = &cobra.Command{ + Use: "deactivate", + Aliases: []string{"deac"}, + Short: "Deactivate items", + Long: `Deactivate items, hiding them from feeds and marking them for deletion. + +Deactivation is idempotent.`, + Run: func(cmd *cobra.Command, args []string) { + deactivate() + }, +} + +var deacSource string +var deacItem string + +func init() { + rootCmd.AddCommand(deactivateCmd) + + deactivateCmd.Flags().StringVarP(&deacSource, "source", "s", "", "Source of the item") + deactivateCmd.MarkFlagRequired("source") + deactivateCmd.Flags().StringVarP(&deacItem, "item", "i", "", "Item id") + deactivateCmd.MarkFlagRequired("item") +} + +func deactivate() { + db, err := sql.Open("sqlite3", getDbPath()) + if err != nil { + log.Fatalf("Failed to open %s", dbPath) + } + + core.InitDatabase(db) + core.MigrateDatabase(db) + + active, err := core.DeactivateItem(db, deacSource, deacItem) + if err != nil { + log.Fatalf("Failed to deactivate item: %s", err) + } + if active { + fmt.Printf("Deactivated %s/%s\n", deacSource, deacItem) + } +} diff --git a/core/db.go b/core/db.go index ae767a6..3e344e9 100644 --- a/core/db.go +++ b/core/db.go @@ -3,6 +3,7 @@ package core import ( "database/sql" "embed" + "errors" "fmt" "log" @@ -144,23 +145,28 @@ func AddItem( return err } -func DeactivateItem(db *sql.DB, source string, id string) error { - res, err := db.Exec(` +// Deactivate an item, returning its previous active state. +func DeactivateItem(db *sql.DB, source string, id string) (bool, error) { + row := db.QueryRow(` + select active + from items + where source = ? and id = ? + `, source, id) + var active bool + err := row.Scan(&active) + if err != nil && errors.Is(err, sql.ErrNoRows) { + return false, fmt.Errorf("item %s/%s not found", source, id) + } + + _, err = db.Exec(` update items set active = 0 where source = ? and id = ? `, source, id) if err != nil { - return err + return false, err } - num, err := res.RowsAffected() - if err != nil { - return err - } - if num == 0 { - return fmt.Errorf("item %s/%s not found", source, id) - } - return nil + return active, nil } func GetActiveItems(db *sql.DB, source string) ([]Item, error) { diff --git a/core/db_test.go b/core/db_test.go index a87c666..5410ba7 100644 --- a/core/db_test.go +++ b/core/db_test.go @@ -135,7 +135,7 @@ func TestAddItem(t *testing.T) { AssertItemIs(t, items[0], "test/one/true/////0") AssertItemIs(t, items[1], "test/two/true/title/author/body/link/123456") - if err = DeactivateItem(db, "test", "one"); err != nil { + if _, err = DeactivateItem(db, "test", "one"); err != nil { t.Fatal(err) } items, err = GetActiveItems(db, "test")