package store import ( "database/sql" "errors" "fmt" "github.com/google/uuid" ) // CreateStaticSiteSecret inserts a new secret for a static site. func (s *Store) CreateStaticSiteSecret(secret StaticSiteSecret) (StaticSiteSecret, error) { secret.ID = uuid.New().String() secret.CreatedAt = Now() secret.UpdatedAt = secret.CreatedAt _, err := s.db.Exec( `INSERT INTO static_site_secrets (id, site_id, key, value, encrypted, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?)`, secret.ID, secret.SiteID, secret.Key, secret.Value, BoolToInt(secret.Encrypted), secret.CreatedAt, secret.UpdatedAt, ) if err != nil { return StaticSiteSecret{}, fmt.Errorf("insert static site secret: %w", err) } return secret, nil } // GetStaticSiteSecretsBySiteID returns all secrets for a static site. func (s *Store) GetStaticSiteSecretsBySiteID(siteID string) ([]StaticSiteSecret, error) { rows, err := s.db.Query( `SELECT id, site_id, key, value, encrypted, created_at, updated_at FROM static_site_secrets WHERE site_id = ? ORDER BY key`, siteID, ) if err != nil { return nil, fmt.Errorf("query static site secrets: %w", err) } defer rows.Close() secrets := []StaticSiteSecret{} for rows.Next() { secret, err := scanStaticSiteSecret(rows) if err != nil { return nil, err } secrets = append(secrets, secret) } return secrets, rows.Err() } // GetStaticSiteSecretByID returns a single secret by ID. func (s *Store) GetStaticSiteSecretByID(id string) (StaticSiteSecret, error) { var secret StaticSiteSecret var encrypted int err := s.db.QueryRow( `SELECT id, site_id, key, value, encrypted, created_at, updated_at FROM static_site_secrets WHERE id = ?`, id, ).Scan(&secret.ID, &secret.SiteID, &secret.Key, &secret.Value, &encrypted, &secret.CreatedAt, &secret.UpdatedAt) if errors.Is(err, sql.ErrNoRows) { return StaticSiteSecret{}, fmt.Errorf("static site secret %s: %w", id, ErrNotFound) } if err != nil { return StaticSiteSecret{}, fmt.Errorf("query static site secret: %w", err) } secret.Encrypted = encrypted != 0 return secret, nil } // UpdateStaticSiteSecret updates an existing secret. func (s *Store) UpdateStaticSiteSecret(secret StaticSiteSecret) error { secret.UpdatedAt = Now() result, err := s.db.Exec( `UPDATE static_site_secrets SET key=?, value=?, encrypted=?, updated_at=? WHERE id=?`, secret.Key, secret.Value, BoolToInt(secret.Encrypted), secret.UpdatedAt, secret.ID, ) if err != nil { return fmt.Errorf("update static site secret: %w", err) } n, _ := result.RowsAffected() if n == 0 { return fmt.Errorf("static site secret %s: %w", secret.ID, ErrNotFound) } return nil } // DeleteStaticSiteSecret removes a secret by ID. func (s *Store) DeleteStaticSiteSecret(id string) error { result, err := s.db.Exec(`DELETE FROM static_site_secrets WHERE id = ?`, id) if err != nil { return fmt.Errorf("delete static site secret: %w", err) } n, _ := result.RowsAffected() if n == 0 { return fmt.Errorf("static site secret %s: %w", id, ErrNotFound) } return nil } // scanStaticSiteSecret scans a secret row from a *sql.Rows cursor. func scanStaticSiteSecret(rows *sql.Rows) (StaticSiteSecret, error) { var secret StaticSiteSecret var encrypted int err := rows.Scan(&secret.ID, &secret.SiteID, &secret.Key, &secret.Value, &encrypted, &secret.CreatedAt, &secret.UpdatedAt) if err != nil { return StaticSiteSecret{}, fmt.Errorf("scan static site secret: %w", err) } secret.Encrypted = encrypted != 0 return secret, nil }