mirror of
https://github.com/grafana/grafana.git
synced 2024-11-25 18:30:41 -06:00
05709ce411
* chore: add alias for InitTestDB and Session Adds an alias for the sqlstore InitTestDB and Session, and updates tests using these to reduce dependencies on the sqlstore.Store. * next pass of removing sqlstore imports * last little bit * remove mockstore where possible
106 lines
3.6 KiB
Go
106 lines
3.6 KiB
Go
package store
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/grafana/grafana/pkg/infra/db"
|
|
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
|
)
|
|
|
|
type provenanceRecord struct {
|
|
Id int `xorm:"pk autoincr 'id'"`
|
|
OrgID int64 `xorm:"'org_id'"`
|
|
RecordKey string
|
|
RecordType string
|
|
Provenance models.Provenance
|
|
}
|
|
|
|
func (pr provenanceRecord) TableName() string {
|
|
return "provenance_type"
|
|
}
|
|
|
|
// GetProvenance gets the provenance status for a provisionable object.
|
|
func (st DBstore) GetProvenance(ctx context.Context, o models.Provisionable, org int64) (models.Provenance, error) {
|
|
recordType := o.ResourceType()
|
|
recordKey := o.ResourceID()
|
|
|
|
provenance := models.ProvenanceNone
|
|
err := st.SQLStore.WithDbSession(ctx, func(sess *db.Session) error {
|
|
filter := "record_key = ? AND record_type = ? AND org_id = ?"
|
|
var result models.Provenance
|
|
has, err := sess.Table(provenanceRecord{}).Where(filter, recordKey, recordType, org).Desc("id").Cols("provenance").Get(&result)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to query for existing provenance status: %w", err)
|
|
}
|
|
if has {
|
|
provenance = result
|
|
}
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
return models.ProvenanceNone, err
|
|
}
|
|
return provenance, nil
|
|
}
|
|
|
|
// GetProvenance gets the provenance status for a provisionable object.
|
|
func (st DBstore) GetProvenances(ctx context.Context, org int64, resourceType string) (map[string]models.Provenance, error) {
|
|
resultMap := make(map[string]models.Provenance)
|
|
err := st.SQLStore.WithDbSession(ctx, func(sess *db.Session) error {
|
|
filter := "record_type = ? AND org_id = ?"
|
|
rawData, err := sess.Table(provenanceRecord{}).Where(filter, resourceType, org).Desc("id").Cols("record_key", "provenance").QueryString()
|
|
if err != nil {
|
|
return fmt.Errorf("failed to query for existing provenance status: %w", err)
|
|
}
|
|
for _, data := range rawData {
|
|
resultMap[data["record_key"]] = models.Provenance(data["provenance"])
|
|
}
|
|
return nil
|
|
})
|
|
return resultMap, err
|
|
}
|
|
|
|
// SetProvenance changes the provenance status for a provisionable object.
|
|
func (st DBstore) SetProvenance(ctx context.Context, o models.Provisionable, org int64, p models.Provenance) error {
|
|
recordType := o.ResourceType()
|
|
recordKey := o.ResourceID()
|
|
|
|
return st.SQLStore.WithTransactionalDbSession(ctx, func(sess *db.Session) error {
|
|
// TODO: Add a unit-of-work pattern, so updating objects + provenance will happen consistently with rollbacks across stores.
|
|
// TODO: Need to make sure that writing a record where our concurrency key fails will also fail the whole transaction. That way, this gets rolled back too. can't just check that 0 updates happened inmemory. Check with jp. If not possible, we need our own concurrency key.
|
|
// TODO: Clean up stale provenance records periodically.
|
|
filter := "record_key = ? AND record_type = ? AND org_id = ?"
|
|
_, err := sess.Table(provenanceRecord{}).Where(filter, recordKey, recordType, org).Delete(provenanceRecord{})
|
|
|
|
if err != nil {
|
|
return fmt.Errorf("failed to delete pre-existing provisioning status: %w", err)
|
|
}
|
|
|
|
record := provenanceRecord{
|
|
RecordKey: recordKey,
|
|
RecordType: recordType,
|
|
Provenance: p,
|
|
OrgID: org,
|
|
}
|
|
|
|
if _, err := sess.Insert(record); err != nil {
|
|
return fmt.Errorf("failed to store provisioning status: %w", err)
|
|
}
|
|
|
|
return nil
|
|
})
|
|
}
|
|
|
|
// DeleteProvenance deletes the provenance record from the table
|
|
func (st DBstore) DeleteProvenance(ctx context.Context, o models.Provisionable, org int64) error {
|
|
return st.SQLStore.WithTransactionalDbSession(ctx, func(sess *db.Session) error {
|
|
_, err := sess.Delete(provenanceRecord{
|
|
RecordKey: o.ResourceID(),
|
|
RecordType: o.ResourceType(),
|
|
OrgID: org,
|
|
})
|
|
return err
|
|
})
|
|
}
|