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}