MM-16821 - Add a KVCompareAndDelete to the plugin API (#11804)
* Implement KVCompareAndDelete and KVCompareAndDeleteJSON * Add tests for KVCompareAndDelete * Update minimum server version * Handle nil value on CompareAndSet so that it deletes it * Fix comments * Tweaks from PR comments * Go back to deleted, err
Этот коммит содержится в:
коммит произвёл
Jesse Hallam
родитель
f8ad9f3b8f
Коммит
11b0a20d7d
@@ -71,6 +71,11 @@ func (ps SqlPluginStore) CompareAndSet(kv *model.PluginKeyValue, oldValue []byte
|
||||
return false, err
|
||||
}
|
||||
|
||||
if kv.Value == nil {
|
||||
// Setting a key to nil is the same as removing it
|
||||
return ps.CompareAndDelete(kv, oldValue)
|
||||
}
|
||||
|
||||
if oldValue == nil {
|
||||
// Insert if oldValue is nil
|
||||
if err := ps.GetMaster().Insert(kv); err != nil {
|
||||
@@ -111,6 +116,37 @@ func (ps SqlPluginStore) CompareAndSet(kv *model.PluginKeyValue, oldValue []byte
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (ps SqlPluginStore) CompareAndDelete(kv *model.PluginKeyValue, oldValue []byte) (bool, *model.AppError) {
|
||||
if err := kv.IsValid(); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if oldValue == nil {
|
||||
// nil can't be stored. Return showing that we didn't do anything
|
||||
return false, nil
|
||||
}
|
||||
|
||||
deleteResult, err := ps.GetMaster().Exec(
|
||||
`DELETE FROM PluginKeyValueStore WHERE PluginId = :PluginId AND PKey = :Key AND PValue = :Old`,
|
||||
map[string]interface{}{
|
||||
"PluginId": kv.PluginId,
|
||||
"Key": kv.Key,
|
||||
"Old": oldValue,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return false, model.NewAppError("SqlPluginStore.CompareAndDelete", "store.sql_plugin_store.save.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
if rowsAffected, err := deleteResult.RowsAffected(); err != nil {
|
||||
return false, model.NewAppError("SqlPluginStore.CompareAndDelete", "store.sql_plugin_store.save.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
} else if rowsAffected == 0 {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (ps SqlPluginStore) Get(pluginId, key string) (*model.PluginKeyValue, *model.AppError) {
|
||||
var kv *model.PluginKeyValue
|
||||
currentTime := model.GetMillis()
|
||||
|
||||
@@ -520,6 +520,7 @@ type UserAccessTokenStore interface {
|
||||
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)
|
||||
Get(pluginId, key string) (*model.PluginKeyValue, *model.AppError)
|
||||
Delete(pluginId, key string) *model.AppError
|
||||
DeleteAllForPlugin(PluginId string) *model.AppError
|
||||
|
||||
@@ -12,6 +12,29 @@ type PluginStore struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// CompareAndDelete provides a mock function with given fields: keyVal, oldValue
|
||||
func (_m *PluginStore) CompareAndDelete(keyVal *model.PluginKeyValue, oldValue []byte) (bool, *model.AppError) {
|
||||
ret := _m.Called(keyVal, oldValue)
|
||||
|
||||
var r0 bool
|
||||
if rf, ok := ret.Get(0).(func(*model.PluginKeyValue, []byte) bool); ok {
|
||||
r0 = rf(keyVal, oldValue)
|
||||
} else {
|
||||
r0 = ret.Get(0).(bool)
|
||||
}
|
||||
|
||||
var r1 *model.AppError
|
||||
if rf, ok := ret.Get(1).(func(*model.PluginKeyValue, []byte) *model.AppError); ok {
|
||||
r1 = rf(keyVal, oldValue)
|
||||
} else {
|
||||
if ret.Get(1) != nil {
|
||||
r1 = ret.Get(1).(*model.AppError)
|
||||
}
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// CompareAndSet provides a mock function with given fields: keyVal, oldValue
|
||||
func (_m *PluginStore) CompareAndSet(keyVal *model.PluginKeyValue, oldValue []byte) (bool, *model.AppError) {
|
||||
ret := _m.Called(keyVal, oldValue)
|
||||
|
||||
Ссылка в новой задаче
Block a user