mirror of
https://github.com/idanoo/autobrr
synced 2025-07-23 16:59:12 +00:00

* add db seed/reset functionality * speculative db migration support * update postgresSchema * refactor: only migrate data, no schema * implement transaction in db migration function * refactor db:seed and db:reset added transaction to both and updated help message * change table order * skip on foreign key constraint violations * skip feed_cache * set constraints to null * fix seed and reset * simplify migrate func This version of the function should behave similarly to the previous version, but with less repetition and by relying on PostgreSQL's automatic transaction handling, which starts a new transaction for each separate statement when not in a transaction block. Also, it prepares the insert statement only once for each table, which can significantly improve performance when there are many rows to insert. * fixed release_action_status * refactor db:seed and db:reset * minor adjustment to const usage * fixed usage examples * refactor seed/migrate * refactor(database): seed and convert * refactor(database): make tables list sorted a-z * chore(deps): go mod tidy * refactor(database): convert improve log output --------- Co-authored-by: ze0s <ze0s@riseup.net>
82 lines
1.7 KiB
Go
82 lines
1.7 KiB
Go
package tools
|
|
|
|
import (
|
|
"database/sql"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
|
|
_ "modernc.org/sqlite"
|
|
)
|
|
|
|
type Seeder interface {
|
|
Reset() error
|
|
Seed() error
|
|
}
|
|
|
|
type SQLiteSeeder struct {
|
|
dbPath string
|
|
seedFile string
|
|
}
|
|
|
|
func NewSQLiteSeeder(dbPath, seedFile string) *SQLiteSeeder {
|
|
return &SQLiteSeeder{
|
|
dbPath: dbPath,
|
|
seedFile: seedFile,
|
|
}
|
|
}
|
|
|
|
func (s *SQLiteSeeder) Reset() error {
|
|
db, err := sql.Open("sqlite", s.dbPath)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to open %s database: %v", "sqlite", err)
|
|
}
|
|
defer db.Close()
|
|
|
|
tables := GetTables()
|
|
|
|
for _, table := range tables {
|
|
if err := s.resetTable(db, table); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *SQLiteSeeder) resetTable(db *sql.DB, table string) error {
|
|
if _, err := db.Exec("DELETE FROM ?", table); err != nil {
|
|
return fmt.Errorf("failed to delete rows from table %s: %v", table, err)
|
|
}
|
|
|
|
// Update sqlite_sequence, ignore errors for missing sqlite_sequence entry
|
|
if _, err := db.Exec("UPDATE sqlite_sequence SET seq = 0 WHERE name = ?", table); err != nil {
|
|
if !strings.Contains(err.Error(), "no such table") {
|
|
return fmt.Errorf("failed to reset primary key sequence for table %s: %v", table, err)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *SQLiteSeeder) Seed() error {
|
|
sqlFile, err := os.ReadFile(s.seedFile)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to read SQL file: %v", err)
|
|
}
|
|
|
|
db, err := sql.Open("sqlite", s.dbPath)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to open %s database: %v", "sqlite", err)
|
|
}
|
|
defer db.Close()
|
|
|
|
sqlCommands := strings.Split(string(sqlFile), ";")
|
|
for _, cmd := range sqlCommands {
|
|
if _, err := db.Exec(cmd); err != nil {
|
|
return fmt.Errorf("failed to execute SQL command: %v", err)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|