Enforce single default source on update

This ensures that there will only be on default source upon setting a
new default by unsetting the default flag on all other sources. This
only happens when the source to be updated has Default set to true to
avoid a performance hit when updating other attributes.
pull/10616/head
Tim Raymond 2016-11-04 16:52:15 -04:00
parent b4b9752601
commit 4a02ad7525
2 changed files with 40 additions and 5 deletions

View File

@ -103,6 +103,25 @@ func (s *SourcesStore) Update(ctx context.Context, src chronograf.Source) error
return chronograf.ErrSourceNotFound
}
//Unset any existing defaults if this is a new default
if src.Default {
srcs, err := s.All(ctx)
if err != nil {
return err
}
for _, other := range srcs {
if other.Default {
other.Default = false
if v, err := internal.MarshalSource(other); err != nil {
return err
} else if err := b.Put(itob(other.ID), v); err != nil {
return err
}
}
}
}
if v, err := internal.MarshalSource(src); err != nil {
return err
} else if err := b.Put(itob(src.ID), v); err != nil {

View File

@ -5,6 +5,7 @@ import (
"testing"
"github.com/influxdata/chronograf"
"github.com/influxdata/chronograf/bolt"
)
// Ensure an SourceStore can store, retrieve, update, and delete sources.
@ -54,11 +55,8 @@ func TestSourceStore(t *testing.T) {
// Update source.
srcs[0].Username = "calvinklein"
srcs[1].Name = "Enchantment Under the Sea Dance"
if err := s.Update(nil, srcs[0]); err != nil {
t.Fatal(err)
} else if err := s.Update(nil, srcs[1]); err != nil {
t.Fatal(err)
}
mustUpdateSource(t, s, srcs[0])
mustUpdateSource(t, s, srcs[1])
// Confirm sources have updated.
if src, err := s.Get(nil, srcs[0].ID); err != nil {
@ -72,6 +70,18 @@ func TestSourceStore(t *testing.T) {
t.Fatalf("source 1 update error: got %v, expected %v", src.Name, "Enchantment Under the Sea Dance")
}
// Attempt to make two default sources
srcs[0].Default = true
srcs[1].Default = true
mustUpdateSource(t, s, srcs[0])
mustUpdateSource(t, s, srcs[1])
if actual, err := s.Get(nil, srcs[0].ID); err != nil {
t.Fatal(err)
} else if actual.Default == true {
t.Fatal("Able to set two default sources when only one should be permitted")
}
// Delete an source.
if err := s.Delete(nil, srcs[0]); err != nil {
t.Fatal(err)
@ -90,3 +100,9 @@ func TestSourceStore(t *testing.T) {
t.Fatalf("After delete All returned incorrect source; got %v, expected %v", bsrcs[0], srcs[1])
}
}
func mustUpdateSource(t *testing.T, s *bolt.SourcesStore, src chronograf.Source) {
if err := s.Update(nil, src); err != nil {
t.Fatal(err)
}
}