mirror of
https://github.com/spf13/viper
synced 2025-05-11 22:57:21 +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
|
aliases map[string]string
|
||||||
typeByDefValue bool
|
typeByDefValue bool
|
||||||
|
|
||||||
|
previousValues map[string]interface{}
|
||||||
|
|
||||||
// Store read properties on the object so that we can write back in order with comments.
|
// 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.
|
// This will only be used if the configuration read is a properties file.
|
||||||
properties *properties.Properties
|
properties *properties.Properties
|
||||||
|
@ -220,6 +222,7 @@ func New() *Viper {
|
||||||
v.override = make(map[string]interface{})
|
v.override = make(map[string]interface{})
|
||||||
v.defaults = make(map[string]interface{})
|
v.defaults = make(map[string]interface{})
|
||||||
v.kvstore = make(map[string]interface{})
|
v.kvstore = make(map[string]interface{})
|
||||||
|
v.previousValues = make(map[string]interface{})
|
||||||
v.pflags = make(map[string]FlagValue)
|
v.pflags = make(map[string]FlagValue)
|
||||||
v.env = make(map[string]string)
|
v.env = make(map[string]string)
|
||||||
v.aliases = make(map[string]string)
|
v.aliases = make(map[string]string)
|
||||||
|
@ -685,6 +688,45 @@ func GetViper() *Viper {
|
||||||
return v
|
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 can retrieve any value given the key to use.
|
||||||
// Get is case-insensitive for a key.
|
// Get is case-insensitive for a key.
|
||||||
// Get has the behavior of returning the value associated with the first
|
// 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{} {
|
func (v *Viper) Get(key string) interface{} {
|
||||||
lcaseKey := strings.ToLower(key)
|
lcaseKey := strings.ToLower(key)
|
||||||
val := v.find(lcaseKey)
|
val := v.find(lcaseKey)
|
||||||
|
|
||||||
|
v.lock.Lock()
|
||||||
|
v.previousValues[lcaseKey] = val
|
||||||
|
v.lock.Unlock()
|
||||||
|
|
||||||
if val == nil {
|
if val == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1761,6 +1761,25 @@ func TestArrayOfObjects(t *testing.T) {
|
||||||
require.NoError(t, WriteConfig())
|
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) {
|
func BenchmarkGetBool(b *testing.B) {
|
||||||
key := "BenchmarkGetBool"
|
key := "BenchmarkGetBool"
|
||||||
v = New()
|
v = New()
|
||||||
|
|
Loading…
Add table
Reference in a new issue