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 |
package store
import (
"context"
"fmt"
)
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"
}
}
var changeArticleStatusQuery = map[Action]string{
Read: `update article_statuses set is_read = 1 where article_id = ?`,
Unread: `update article_statuses set is_read = 0 where article_id = ?`,
Star: `update article_statuses set is_starred = 1 where article_id = ?`,
Unstar: `update article_statuses set is_starred = 0 where article_id = ?`,
}
func (s *Sqlite) ChangeArticleStatus(ctx context.Context, articleID string, action Action) error {
tx, err := s.db.BeginTx(ctx, nil)
if err != nil {
return err
}
defer tx.Rollback()
// update article status
e, err := tx.ExecContext(ctx, changeArticleStatusQuery[action], 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 20`
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, args := buildPlaceholdersAndArgs(articleIDs, action.String())
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
}
|