smutok/internal/store/sqlite_pendin_actions.go(view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
package store
import (
"context"
"fmt"
"strings"
)
type Action int
const (
Read Action = iota
Unread
Star
Unstar
)
func (a Action) String() string {
switch a {
case Read:
return "read"
case Unread:
return "unread"
case Star:
return "star"
case Unstar:
return "unstar"
default:
return "unsupported"
}
}
func (s *Sqlite) ChangeArticleStatus(ctx context.Context, articleID string, action Action) error {
tx, err := s.db.Begin()
if err != nil {
return err
}
defer tx.Rollback()
// update article status
var query string
switch action {
case Read:
query = `update article_statuses set is_read = 1 where article_id = ?`
case Unread:
query = `update article_statuses set is_read = 0 where article_id = ?`
case Star:
query = `update article_statuses set is_starred = 1 where article_id = ?`
case Unstar:
query = `update article_statuses set is_starred = 0 where article_id = ?`
}
e, err := tx.ExecContext(ctx, query, articleID)
if err != nil {
return err
}
if n, _ := e.RowsAffected(); n == 0 {
return ErrNotFound
}
// enqueue action
if _, err := tx.ExecContext(ctx, `insert into pending_actions (article_id, action) values (?, ?)`,
articleID, action.String()); err != nil {
return err
}
return tx.Commit()
}
func (s *Sqlite) GetPendingActions(ctx context.Context, action Action) ([]string, error) {
query := `--sql
select article_id
from pending_actions
where action = ?
order by created_at desc
limit 10`
rows, err := s.db.QueryContext(ctx, query, action.String())
if err != nil {
return nil, err
}
defer rows.Close()
var res []string
for rows.Next() {
var pa string
if serr := rows.Scan(&pa); serr != nil {
return res, serr
}
res = append(res, pa)
}
if err = rows.Err(); err != nil {
return res, err
}
return res, nil
}
func (s *Sqlite) DeletePendingActions(ctx context.Context, action Action, articleIDs []string) error {
placeholders := strings.Repeat("(?),", len(articleIDs))
placeholders = placeholders[:len(placeholders)-1]
args := make([]any, len(articleIDs)+1)
args[0] = action.String()
for i, v := range articleIDs {
args[i+1] = v
}
query := fmt.Sprintf(`--sql
delete from pending_actions
where action = ?
and article_id in (%s)
`, placeholders)
_, err := s.db.ExecContext(ctx, query, args...)
return err
}
|