A URL shortener service that uses ATProto to allow self hosting and ensuring the user owns their data
at main 1.3 kB view raw
1package database 2 3import ( 4 "database/sql" 5 "errors" 6 "fmt" 7 "log/slog" 8 "os" 9 10 _ "github.com/glebarez/go-sqlite" 11) 12 13type DB struct { 14 db *sql.DB 15} 16 17func New(dbPath string) (*DB, 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 = createOauthRequestsTable(db) 36 if err != nil { 37 return nil, fmt.Errorf("creating oauth requests table: %w", err) 38 } 39 40 err = createOauthSessionsTable(db) 41 if err != nil { 42 return nil, fmt.Errorf("creating oauth sessions table: %w", err) 43 } 44 45 err = createURLsTable(db) 46 if err != nil { 47 return nil, fmt.Errorf("creating status table: %w", err) 48 } 49 50 return &DB{db: db}, nil 51} 52 53func (d *DB) Close() { 54 err := d.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}