MM-16822 - Implement KVSetWithOptions (#11818)

* Add SetWithOptions

* Avoid passing two structs to the functions

* Rename ExpiryInSeconds -> ExpireInSeconds

* Use t.Run for the tests

* Fix build

* Address feedback

* Update log message

* Update docs and use KVSetWithOptions in KVCompareAndSetJSON

* Improve code style

* Use struct instead of pointer to struct

* Fix minimum server versions

* Update documentation

* Address feedback

* Revert new implemention of kv helpers

* Adress feedback
Этот коммит содержится в:
Gervasio Marchand
2019-11-04 09:49:54 -03:00
коммит произвёл Ben Schumacher
родитель 812c40a307
Коммит 1db045bce3
13 изменённых файлов: 420 добавлений и 77 удалений

Просмотреть файл

@@ -91,12 +91,13 @@ func (ps SqlPluginStore) CompareAndSet(kv *model.PluginKeyValue, oldValue []byte
} else {
// Update if oldValue is not nil
updateResult, err := ps.GetMaster().Exec(
`UPDATE PluginKeyValueStore SET PValue = :New WHERE PluginId = :PluginId AND PKey = :Key AND PValue = :Old`,
`UPDATE PluginKeyValueStore SET PValue = :New, ExpireAt = :ExpireAt WHERE PluginId = :PluginId AND PKey = :Key AND PValue = :Old`,
map[string]interface{}{
"PluginId": kv.PluginId,
"Key": kv.Key,
"Old": oldValue,
"New": kv.Value,
"ExpireAt": kv.ExpireAt,
},
)
if err != nil {
@@ -147,6 +148,34 @@ func (ps SqlPluginStore) CompareAndDelete(kv *model.PluginKeyValue, oldValue []b
return true, nil
}
func (ps SqlPluginStore) SetWithOptions(pluginId string, key string, value interface{}, opt model.PluginKVSetOptions) (bool, *model.AppError) {
if err := opt.IsValid(); err != nil {
return false, err
}
kv, err := model.NewPluginKeyValueFromOptions(pluginId, key, value, opt)
if err != nil {
return false, err
}
if opt.Atomic {
var serializedOldValue []byte
serializedOldValue, err = opt.GetOldValueSerialized()
if err != nil {
return false, err
}
return ps.CompareAndSet(kv, serializedOldValue)
}
savedKv, err := ps.SaveOrUpdate(kv)
if err != nil {
return false, err
}
return savedKv != nil, nil
}
func (ps SqlPluginStore) Get(pluginId, key string) (*model.PluginKeyValue, *model.AppError) {
var kv *model.PluginKeyValue
currentTime := model.GetMillis()

Просмотреть файл

@@ -528,6 +528,7 @@ type PluginStore interface {
SaveOrUpdate(keyVal *model.PluginKeyValue) (*model.PluginKeyValue, *model.AppError)
CompareAndSet(keyVal *model.PluginKeyValue, oldValue []byte) (bool, *model.AppError)
CompareAndDelete(keyVal *model.PluginKeyValue, oldValue []byte) (bool, *model.AppError)
SetWithOptions(pluginId string, key string, value interface{}, options model.PluginKVSetOptions) (bool, *model.AppError)
Get(pluginId, key string) (*model.PluginKeyValue, *model.AppError)
Delete(pluginId, key string) *model.AppError
DeleteAllForPlugin(PluginId string) *model.AppError

Просмотреть файл

@@ -182,3 +182,26 @@ func (_m *PluginStore) SaveOrUpdate(keyVal *model.PluginKeyValue) (*model.Plugin
return r0, r1
}
// SetWithOptions provides a mock function with given fields: pluginId, key, value, options
func (_m *PluginStore) SetWithOptions(pluginId string, key string, value interface{}, options model.PluginKVSetOptions) (bool, *model.AppError) {
ret := _m.Called(pluginId, key, value, options)
var r0 bool
if rf, ok := ret.Get(0).(func(string, string, interface{}, model.PluginKVSetOptions) bool); ok {
r0 = rf(pluginId, key, value, options)
} else {
r0 = ret.Get(0).(bool)
}
var r1 *model.AppError
if rf, ok := ret.Get(1).(func(string, string, interface{}, model.PluginKVSetOptions) *model.AppError); ok {
r1 = rf(pluginId, key, value, options)
} else {
if ret.Get(1) != nil {
r1 = ret.Get(1).(*model.AppError)
}
}
return r0, r1
}