package store import ( "database/sql" "errors" "fmt" "github.com/google/uuid" ) // CreateBackup inserts a new backup metadata record. func (s *Store) CreateBackup(b Backup) (Backup, error) { if b.ID == "" { b.ID = uuid.New().String() } b.CreatedAt = Now() _, err := s.db.Exec( `INSERT INTO backups (id, filename, size_bytes, backup_type, created_at) VALUES (?, ?, ?, ?, ?)`, b.ID, b.Filename, b.SizeBytes, b.BackupType, b.CreatedAt, ) if err != nil { return Backup{}, fmt.Errorf("insert backup: %w", err) } return b, nil } // GetBackup returns a backup by ID. func (s *Store) GetBackup(id string) (Backup, error) { var b Backup err := s.db.QueryRow( `SELECT id, filename, size_bytes, backup_type, created_at FROM backups WHERE id = ?`, id, ).Scan(&b.ID, &b.Filename, &b.SizeBytes, &b.BackupType, &b.CreatedAt) if errors.Is(err, sql.ErrNoRows) { return Backup{}, fmt.Errorf("backup %s: %w", id, ErrNotFound) } if err != nil { return Backup{}, fmt.Errorf("query backup: %w", err) } return b, nil } // ListBackups returns all backups ordered by creation date descending. func (s *Store) ListBackups() ([]Backup, error) { rows, err := s.db.Query( `SELECT id, filename, size_bytes, backup_type, created_at FROM backups ORDER BY created_at DESC`, ) if err != nil { return nil, fmt.Errorf("query backups: %w", err) } defer rows.Close() var backups []Backup for rows.Next() { var b Backup if err := rows.Scan(&b.ID, &b.Filename, &b.SizeBytes, &b.BackupType, &b.CreatedAt); err != nil { return nil, fmt.Errorf("scan backup: %w", err) } backups = append(backups, b) } return backups, rows.Err() } // DeleteBackup removes a backup metadata record by ID. func (s *Store) DeleteBackup(id string) error { _, err := s.db.Exec(`DELETE FROM backups WHERE id = ?`, id) if err != nil { return fmt.Errorf("delete backup: %w", err) } return nil } // CountBackups returns the total number of backup records. func (s *Store) CountBackups() (int, error) { var count int err := s.db.QueryRow(`SELECT COUNT(*) FROM backups`).Scan(&count) if err != nil { return 0, fmt.Errorf("count backups: %w", err) } return count, nil } // GetOldestBackups returns the N oldest backups (for pruning). func (s *Store) GetOldestBackups(limit int) ([]Backup, error) { rows, err := s.db.Query( `SELECT id, filename, size_bytes, backup_type, created_at FROM backups ORDER BY created_at ASC LIMIT ?`, limit, ) if err != nil { return nil, fmt.Errorf("query oldest backups: %w", err) } defer rows.Close() var backups []Backup for rows.Next() { var b Backup if err := rows.Scan(&b.ID, &b.Filename, &b.SizeBytes, &b.BackupType, &b.CreatedAt); err != nil { return nil, fmt.Errorf("scan backup: %w", err) } backups = append(backups, b) } return backups, rows.Err() }