Add automated backup system with SQLite VACUUM
- Implement backup package with SQLite VACUUM INTO for safe backups - Add scheduler with configurable interval (default: 24h) - Add retention policy with automatic cleanup (default: 7 days) - Add optional gzip compression (~10x size reduction) - Add comprehensive tests for backup creation and cleanup - Integrate backup scheduler in main.go with graceful shutdown - Add backup configuration variables (BACKUP_ENABLED, BACKUP_INTERVAL, BACKUP_RETENTION_DAYS, BACKUP_PATH, BACKUP_COMPRESS) - Backups run automatically in background goroutine - Coverage: backup package 52.7%
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
package backup
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"time"
|
||||
|
||||
"apocapoc-api/internal/infrastructure/logger"
|
||||
)
|
||||
|
||||
type Scheduler struct {
|
||||
db *sql.DB
|
||||
config Config
|
||||
stopCh chan struct{}
|
||||
}
|
||||
|
||||
func NewScheduler(db *sql.DB, config Config) *Scheduler {
|
||||
return &Scheduler{
|
||||
db: db,
|
||||
config: config,
|
||||
stopCh: make(chan struct{}),
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Scheduler) Start() {
|
||||
if !s.config.Enabled {
|
||||
logger.Info().Msg("Backup scheduler is disabled")
|
||||
return
|
||||
}
|
||||
|
||||
logger.Info().
|
||||
Dur("interval", s.config.Interval).
|
||||
Int("retention_days", s.config.RetentionDays).
|
||||
Str("path", s.config.Path).
|
||||
Bool("compress", s.config.Compress).
|
||||
Msg("Starting backup scheduler")
|
||||
|
||||
go s.run()
|
||||
}
|
||||
|
||||
func (s *Scheduler) run() {
|
||||
if err := CreateBackup(s.db, s.config); err != nil {
|
||||
logger.Error().Err(err).Msg("Initial backup failed")
|
||||
}
|
||||
|
||||
if err := CleanOldBackups(s.config); err != nil {
|
||||
logger.Error().Err(err).Msg("Initial cleanup failed")
|
||||
}
|
||||
|
||||
ticker := time.NewTicker(s.config.Interval)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
logger.Debug().Msg("Running scheduled backup")
|
||||
|
||||
if err := CreateBackup(s.db, s.config); err != nil {
|
||||
logger.Error().Err(err).Msg("Scheduled backup failed")
|
||||
continue
|
||||
}
|
||||
|
||||
if err := CleanOldBackups(s.config); err != nil {
|
||||
logger.Error().Err(err).Msg("Backup cleanup failed")
|
||||
}
|
||||
|
||||
case <-s.stopCh:
|
||||
logger.Info().Msg("Backup scheduler stopped")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Scheduler) Stop() {
|
||||
if s.config.Enabled {
|
||||
close(s.stopCh)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user