mirror of
https://github.com/idanoo/autobrr
synced 2025-07-23 00:39:13 +00:00

* feat: delete irc network in transaction * feat: use compound key for irc handlers * chore: update deps * refactor: start network * refactor: init irc handler * indexers: update network name
98 lines
2 KiB
Go
98 lines
2 KiB
Go
package database
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"fmt"
|
|
"sync"
|
|
|
|
_ "github.com/mattn/go-sqlite3"
|
|
"github.com/rs/zerolog/log"
|
|
)
|
|
|
|
type SqliteDB struct {
|
|
lock sync.RWMutex
|
|
handler *sql.DB
|
|
ctx context.Context
|
|
cancel func()
|
|
|
|
DSN string
|
|
}
|
|
|
|
func NewSqliteDB(source string) *SqliteDB {
|
|
db := &SqliteDB{
|
|
DSN: dataSourceName(source, "autobrr.db"),
|
|
}
|
|
|
|
db.ctx, db.cancel = context.WithCancel(context.Background())
|
|
|
|
return db
|
|
}
|
|
|
|
func (db *SqliteDB) Open() error {
|
|
if db.DSN == "" {
|
|
return fmt.Errorf("DSN required")
|
|
}
|
|
|
|
var err error
|
|
|
|
// open database connection
|
|
if db.handler, err = sql.Open("sqlite3", db.DSN); err != nil {
|
|
log.Fatal().Err(err).Msg("could not open db connection")
|
|
return err
|
|
}
|
|
|
|
// Set busy timeout
|
|
if _, err = db.handler.Exec(`PRAGMA busy_timeout = 5000;`); err != nil {
|
|
return fmt.Errorf("busy timeout pragma")
|
|
}
|
|
|
|
// Enable WAL. SQLite performs better with the WAL because it allows
|
|
// multiple readers to operate while data is being written.
|
|
if _, err = db.handler.Exec(`PRAGMA journal_mode = wal;`); err != nil {
|
|
return fmt.Errorf("enable wal: %w", err)
|
|
}
|
|
|
|
// Enable foreign key checks. For historical reasons, SQLite does not check
|
|
// foreign key constraints by default. There's some overhead on inserts to
|
|
// verify foreign key integrity, but it's definitely worth it.
|
|
if _, err = db.handler.Exec(`PRAGMA foreign_keys = ON;`); err != nil {
|
|
return fmt.Errorf("foreign keys pragma: %w", err)
|
|
}
|
|
|
|
// migrate db
|
|
if err = db.migrate(); err != nil {
|
|
log.Fatal().Err(err).Msg("could not migrate db")
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (db *SqliteDB) Close() error {
|
|
// cancel background context
|
|
db.cancel()
|
|
|
|
// close database
|
|
if db.handler != nil {
|
|
return db.handler.Close()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (db *SqliteDB) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error) {
|
|
tx, err := db.handler.BeginTx(ctx, opts)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &Tx{
|
|
Tx: tx,
|
|
handler: db,
|
|
}, nil
|
|
}
|
|
|
|
type Tx struct {
|
|
*sql.Tx
|
|
handler *SqliteDB
|
|
}
|