package db import ( "database/sql" "errors" "fmt" "github.com/bluesky-social/indigo/atproto/syntax" "tangled.org/core/knotfeed" ) func (d *DB) LoadFeedCursor(knot string) (knotfeed.Cursor, error) { var seq int64 var token string err := d.QueryRow( `select seq, feed from feed_cursors where knot = ?`, knot, ).Scan(&seq, &token) if errors.Is(err, sql.ErrNoRows) { return knotfeed.Cursor{}, nil } if err != nil { return knotfeed.Cursor{}, err } feed, err := knotfeed.ParseFeed(token) if err != nil { return knotfeed.Cursor{}, fmt.Errorf("feed cursor for %s: %w", knot, err) } return knotfeed.NewCursor(feed, seq), nil } func (d *DB) StoreFeedCursor(knot string, cursor knotfeed.Cursor) error { _, err := d.Exec( `insert into feed_cursors (knot, seq, feed) values (?, ?, ?) on conflict(knot) do update set seq = excluded.seq, feed = excluded.feed`, knot, cursor.Seq(), cursor.Feed().Token(), ) return err } func (d *DB) FeedRefSha(repoDid syntax.DID, rkey syntax.RecordKey) (knotfeed.ObjectID, bool, error) { var raw string err := d.QueryRow( `select sha from feed_refs where repo_did = ? and rkey = ?`, repoDid.String(), rkey.String(), ).Scan(&raw) if errors.Is(err, sql.ErrNoRows) { return knotfeed.ObjectID{}, false, nil } if err != nil { return knotfeed.ObjectID{}, false, err } sha, ok := knotfeed.ParseObjectID(raw) if !ok { return knotfeed.ObjectID{}, false, fmt.Errorf("ref state for %s at %s stored sha %q", repoDid, rkey, raw) } return sha, true, nil } func (d *DB) PutFeedRef(repoDid syntax.DID, rkey syntax.RecordKey, sha knotfeed.ObjectID) error { _, err := d.Exec( `insert into feed_refs (repo_did, rkey, sha) values (?, ?, ?) on conflict(repo_did, rkey) do update set sha = excluded.sha`, repoDid.String(), rkey.String(), sha.String(), ) return err } func (d *DB) DeleteFeedRef(repoDid syntax.DID, rkey syntax.RecordKey) error { _, err := d.Exec( `delete from feed_refs where repo_did = ? and rkey = ?`, repoDid.String(), rkey.String(), ) return err } func (d *DB) DeleteFeedRefsByRepoDid(repoDid syntax.DID) error { _, err := d.Exec(`delete from feed_refs where repo_did = ?`, repoDid.String()) return err }