blob: 5f30a7602d9b643b6e09a85578288ea4f18eb3ed [file]
package sqlautobisectionstore
import (
"context"
"fmt"
"go.opencensus.io/trace"
"go.skia.org/infra/go/skerr"
"go.skia.org/infra/go/sql/pool"
"go.skia.org/infra/perf/go/autobisection"
v1 "go.skia.org/infra/perf/go/autobisection/proto/v1"
"go.skia.org/infra/perf/go/autobisection/sqlautobisectionstore/schema"
)
// statement is an SQL statement identifier.
type statement int
const (
insertAutobisection statement = iota
)
var statements = map[statement]string{
insertAutobisection: `
INSERT INTO
Autobisections (job_id, workflow_id, anomaly_group_id, anomaly_id, regression_status)
VALUES
($1, $2, $3, $4, $5)
`,
}
// AutobisectionStore implements the autobisection.Store interface using a SQL database.
type AutobisectionStore struct {
db pool.Pool
}
// New returns a new AutobisectionStore.
func New(db pool.Pool) (*AutobisectionStore, error) {
return &AutobisectionStore{
db: db,
}, nil
}
// Save implements the autobisection.Store interface.
func (s *AutobisectionStore) Save(ctx context.Context, b *schema.AutobisectionSchema) error {
ctx, span := trace.StartSpan(ctx, "sqlautobisectionstore.Save")
defer span.End()
if err := validateAutobisection(b); err != nil {
return skerr.Wrap(err)
}
statement := statements[insertAutobisection]
if _, err := s.db.Exec(ctx, statement,
b.JobID,
b.WorkflowID,
b.AnomalyGroupID,
b.AnomalyId,
b.RegressionStatus,
); err != nil {
return fmt.Errorf("error inserting autobisection result into Autobisections table: %w", err)
}
return nil
}
func validateAutobisection(b *schema.AutobisectionSchema) error {
if b.JobID == "" {
return skerr.Fmt("job_id cannot be empty")
}
if b.AnomalyGroupID == "" {
return skerr.Fmt("anomaly group id cannot be empty")
}
if b.AnomalyId == "" {
return skerr.Fmt("anomaly id cannot be empty")
}
if b.WorkflowID == "" {
return skerr.Fmt("workflow id cannot be empty")
}
if !validateRegressionStatus(b.RegressionStatus) {
return skerr.Fmt("regression status is invalid: %s", b.RegressionStatus)
}
return nil
}
func validateRegressionStatus(regressionStatus string) bool {
v, ok := v1.RegressionStatus_value[regressionStatus]
// value 0 is "unspecified", but we always provide the status.
return ok && v > 0
}
// Ensure AutobisectionStore implements autobisection.Store
var _ autobisection.Store = (*AutobisectionStore)(nil)