Most of the other private CRUD methods have a consistent argument order
of a context, a source, then a transaction. setRandomDefault had two of
these args transposed, so this swaps them to be consistent with the rest
of the methods.
Previously, the logic to enforce on default source relied on the
public-facing CRUD methods already provided by SourcesStore. This was
prone to deadlocks due to the possibility of acquiring a transaction
within a transaction. This extracts the logic that was performed within
the transactions of each CRUD action and makes the private methods that
receive a *bolt.Tx. This allows the convenience methods that enforce
default source to use this private API and provide the transaction from
its caller. This ensures that there is only ever one transaction
acquired by each expored
CRUD method.
Whenver sources are present, there should be exactly one default source.
Prior to this commit, it was possible to add the first source as a
non-default source and circumvent this invariant. This unfortunately
requires a bit of special-casing logic in s.Add and requires a query to
fetch the number of sources currently persisted.
Tests have been added to cover this as well as deleting the final
source, to ensure that there aren't any odd indexing panics that might
result from trying to find another candidate default source when
deleting.
Enforcing the constraint that there be exactly one default source
whenever there are sources present isn't really a concern of the
traditional CRUD methods that are provided by SourcesStore. This makes
this separation a little more explicit and provides a place to glue some
documentation onto what would otherwise be a confusing bit of business
logic in the write path of SourcesStore.
Previously, when adding a new default source, it was possible to create
more than one default source, since the previous default would not be unset.
Implementing this revealed another issue where deleting the default
source would leave no default set. If the default source is deleted now,
another source is chosen to be the new default.
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.
I and Name were added to support react-grid-layout. They were added to
the chronograf types, but not to the protobuf definitions, so the only
layouts that could make use of them were the canned variety. This allows
layouts' I and Name to be persisted as well.