package store import ( "context" "database/sql" "fmt" "time" "provisioning/internal/model" ) type Images struct { DB *sql.DB } func (s *Images) Create(ctx context.Context, img model.Image) (int64, error) { res, err := s.DB.ExecContext(ctx, ` INSERT INTO images(name, kind, version, kernel_path, initrd_path, is_default) VALUES(?,?,?,?,?,?) `, img.Name, img.Kind, img.Version, img.KernelPath, img.InitrdPath, boolToInt(img.IsDefault)) if err != nil { return 0, fmt.Errorf("insert image: %w", err) } return res.LastInsertId() } func (s *Images) List(ctx context.Context) ([]model.Image, error) { rows, err := s.DB.QueryContext(ctx, `SELECT id, name, kind, version, kernel_path, initrd_path, is_default, created_at FROM images ORDER BY name`) if err != nil { return nil, fmt.Errorf("list images: %w", err) } defer rows.Close() var out []model.Image for rows.Next() { var img model.Image var isDefault int var createdAt string if err := rows.Scan(&img.ID, &img.Name, &img.Kind, &img.Version, &img.KernelPath, &img.InitrdPath, &isDefault, &createdAt); err != nil { return nil, fmt.Errorf("scan image: %w", err) } img.IsDefault = isDefault == 1 img.CreatedAt, _ = time.Parse(time.RFC3339, createdAt) out = append(out, img) } return out, rows.Err() } func (s *Images) GetDefault(ctx context.Context) (*model.Image, error) { row := s.DB.QueryRowContext(ctx, `SELECT id, name, kind, version, kernel_path, initrd_path, is_default, created_at FROM images WHERE is_default = 1 LIMIT 1`) var img model.Image var isDefault int var createdAt string if err := row.Scan(&img.ID, &img.Name, &img.Kind, &img.Version, &img.KernelPath, &img.InitrdPath, &isDefault, &createdAt); err != nil { if err == sql.ErrNoRows { return nil, ErrNotFound } return nil, fmt.Errorf("get default image: %w", err) } img.IsDefault = true img.CreatedAt, _ = time.Parse(time.RFC3339, createdAt) return &img, nil } func (s *Images) Get(ctx context.Context, id int64) (*model.Image, error) { row := s.DB.QueryRowContext(ctx, `SELECT id, name, kind, version, kernel_path, initrd_path, is_default, created_at FROM images WHERE id = ?`, id) var img model.Image var isDefault int var createdAt string if err := row.Scan(&img.ID, &img.Name, &img.Kind, &img.Version, &img.KernelPath, &img.InitrdPath, &isDefault, &createdAt); err != nil { if err == sql.ErrNoRows { return nil, ErrNotFound } return nil, fmt.Errorf("get image: %w", err) } img.IsDefault = isDefault == 1 img.CreatedAt, _ = time.Parse(time.RFC3339, createdAt) return &img, nil } func (s *Images) SetDefault(ctx context.Context, id int64) error { tx, err := s.DB.BeginTx(ctx, nil) if err != nil { return err } if _, err := tx.ExecContext(ctx, `UPDATE images SET is_default = 0`); err != nil { _ = tx.Rollback() return err } if _, err := tx.ExecContext(ctx, `UPDATE images SET is_default = 1 WHERE id = ?`, id); err != nil { _ = tx.Rollback() return err } return tx.Commit() } func boolToInt(b bool) int { if b { return 1 } return 0 }