mirror of
https://github.com/spf13/viper
synced 2025-05-07 20:57:18 +00:00
Adds HasChanged and HasChangedSinceInit
These two methods return true if a value has changed.
This commit is contained in:
parent
5bace2abf4
commit
3c36e1d361
2 changed files with 66 additions and 0 deletions
47
viper.go
47
viper.go
|
@ -200,6 +200,8 @@ type Viper struct {
|
|||
aliases map[string]string
|
||||
typeByDefValue bool
|
||||
|
||||
previousValues map[string]interface{}
|
||||
|
||||
// Store read properties on the object so that we can write back in order with comments.
|
||||
// This will only be used if the configuration read is a properties file.
|
||||
properties *properties.Properties
|
||||
|
@ -220,6 +222,7 @@ func New() *Viper {
|
|||
v.override = make(map[string]interface{})
|
||||
v.defaults = make(map[string]interface{})
|
||||
v.kvstore = make(map[string]interface{})
|
||||
v.previousValues = make(map[string]interface{})
|
||||
v.pflags = make(map[string]FlagValue)
|
||||
v.env = make(map[string]string)
|
||||
v.aliases = make(map[string]string)
|
||||
|
@ -685,6 +688,45 @@ func GetViper() *Viper {
|
|||
return v
|
||||
}
|
||||
|
||||
// HasChanged returns true if a key has changed and the change has not been retrieved yet using `Get()` and all
|
||||
// casters `GetString()`, `GetDuration()`, ...
|
||||
//
|
||||
// If the value has not been retrieved at all this will also return true.
|
||||
func HasChanged(key string) bool { return v.HasChanged(key) }
|
||||
func (v *Viper) HasChanged(key string) bool {
|
||||
lcaseKey := strings.ToLower(key)
|
||||
v.lock.RLock()
|
||||
defer v.lock.RUnlock()
|
||||
|
||||
value, ok := v.previousValues[lcaseKey]
|
||||
if !ok {
|
||||
return IsSet(lcaseKey)
|
||||
}
|
||||
|
||||
// Avoid writing the change
|
||||
return value != v.find(lcaseKey)
|
||||
}
|
||||
|
||||
// HasChangedSinceInit returns true if a key has changed and the change has not been retrieved yet using `Get()` and all
|
||||
// casters `GetString()`, `GetDuration()`, ...
|
||||
//
|
||||
// If the value has not been retrieved before at all this will return false.
|
||||
func HasChangedSinceInit(key string) bool { return v.HasChangedSinceInit(key) }
|
||||
func (v *Viper) HasChangedSinceInit(key string) bool {
|
||||
lcaseKey := strings.ToLower(key)
|
||||
v.lock.RLock()
|
||||
defer v.lock.RUnlock()
|
||||
|
||||
value, ok := v.previousValues[lcaseKey]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
// Avoid writing the change
|
||||
return value != v.find(lcaseKey)
|
||||
|
||||
}
|
||||
|
||||
// Get can retrieve any value given the key to use.
|
||||
// Get is case-insensitive for a key.
|
||||
// Get has the behavior of returning the value associated with the first
|
||||
|
@ -696,6 +738,11 @@ func Get(key string) interface{} { return v.Get(key) }
|
|||
func (v *Viper) Get(key string) interface{} {
|
||||
lcaseKey := strings.ToLower(key)
|
||||
val := v.find(lcaseKey)
|
||||
|
||||
v.lock.Lock()
|
||||
v.previousValues[lcaseKey] = val
|
||||
v.lock.Unlock()
|
||||
|
||||
if val == nil {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1761,6 +1761,25 @@ func TestArrayOfObjects(t *testing.T) {
|
|||
require.NoError(t, WriteConfig())
|
||||
}
|
||||
|
||||
func TestHasChanged(t *testing.T) {
|
||||
Reset()
|
||||
require.False(t, HasChanged("foo"))
|
||||
require.False(t, HasChangedSinceInit("foo"))
|
||||
|
||||
Set("foo", "bar")
|
||||
require.False(t, HasChangedSinceInit("foo"))
|
||||
require.True(t, HasChanged("foo"))
|
||||
require.Equal(t, "bar", Get("foo"))
|
||||
require.False(t, HasChanged("foo"))
|
||||
|
||||
Set("foo", "baz")
|
||||
require.True(t, HasChangedSinceInit("foo"))
|
||||
require.True(t, HasChanged("foo"))
|
||||
require.Equal(t, "baz", Get("foo"))
|
||||
require.False(t, HasChanged("foo"))
|
||||
require.False(t, HasChangedSinceInit("foo"))
|
||||
}
|
||||
|
||||
func BenchmarkGetBool(b *testing.B) {
|
||||
key := "BenchmarkGetBool"
|
||||
v = New()
|
||||
|
|
Loading…
Add table
Reference in a new issue