an app.bsky.* indexer
1package main
2
3import (
4 "fmt"
5 "log"
6 "log/slog"
7 "os"
8 "time"
9
10 "gorm.io/driver/sqlite"
11 "gorm.io/gorm"
12 "gorm.io/gorm/logger"
13)
14
15func NewDatabase(path string) *gorm.DB {
16 sl := slog.With("source", "database")
17 l := logger.New(
18 log.New(os.Stdout, "\r\n", log.LstdFlags),
19 logger.Config{
20 SlowThreshold: time.Second,
21 Colorful: false,
22 },
23 )
24 db, err := gorm.Open(sqlite.Open(path), &gorm.Config{
25 Logger: l,
26 })
27 if err != nil {
28 sl.Error("failed to open database", "err", err)
29 }
30 db.Exec("PRAGMA journal_mode=WAL")
31 return db
32}
33
34func (b *Backend) CleanlyClose() error {
35 closeDb := func(db *gorm.DB) error {
36 if err := db.Exec("PRAGMA wal_checkpoint(TRUNCATE)").Error; err != nil {
37 return fmt.Errorf("failed checkpointing the WAL: %w", err)
38 }
39 rawDb, err := db.DB()
40 if err != nil {
41 return fmt.Errorf("failed getting underlying DB connection: %w", err)
42 }
43 if err := rawDb.Close(); err != nil {
44 return fmt.Errorf("failed closing underlying DB connection: %w", err)
45 }
46 return nil
47 }
48
49 if err := closeDb(b.state); err != nil {
50 return fmt.Errorf("failed to close state database: %w", err)
51 }
52
53 if err := closeDb(b.data); err != nil {
54 return fmt.Errorf("failed to close content database: %w", err)
55 }
56
57 return nil
58}