A feed generator that allows Bluesky bookmarks via DMs
1package store
2
3import (
4 "database/sql"
5 "errors"
6 "fmt"
7 "log/slog"
8 "os"
9
10 _ "github.com/glebarez/go-sqlite"
11)
12
13type Store struct {
14 db *sql.DB
15}
16
17func New(dbPath string) (*Store, error) {
18 if dbPath != ":memory:" {
19 err := createDbFile(dbPath)
20 if err != nil {
21 return nil, fmt.Errorf("create db file: %w", err)
22 }
23 }
24
25 db, err := sql.Open("sqlite", dbPath)
26 if err != nil {
27 return nil, fmt.Errorf("open database: %w", err)
28 }
29
30 err = db.Ping()
31 if err != nil {
32 return nil, fmt.Errorf("ping db: %w", err)
33 }
34
35 err = createRepliesTable(db)
36 if err != nil {
37 return nil, fmt.Errorf("creating replies table: %w", err)
38 }
39
40 err = createBookmarksTable(db)
41 if err != nil {
42 return nil, fmt.Errorf("creating bookmarks table: %w", err)
43 }
44
45 err = createOauthRequestsTable(db)
46 if err != nil {
47 return nil, fmt.Errorf("creating oauth requests table: %w", err)
48 }
49
50 return &Store{db: db}, nil
51}
52
53func (s *Store) Close() {
54 err := s.db.Close()
55 if err != nil {
56 slog.Error("failed to close db", "error", err)
57 }
58}
59
60func createDbFile(dbFilename string) error {
61 if _, err := os.Stat(dbFilename); !errors.Is(err, os.ErrNotExist) {
62 return nil
63 }
64
65 f, err := os.Create(dbFilename)
66 if err != nil {
67 return fmt.Errorf("create db file : %w", err)
68 }
69 f.Close()
70 return nil
71}