MM-14246 - Plugin framework: support transactional semantics with KV Store (#10634)
* MM-14246 - Plugin framework: support transactional semantics with KV Store Rename old, new variable names Moving New function to the bottom * Made CompareAndUpdate sync, updated tests * Removed going through channel in CompareAndSetPluginKey * Inserting new key when oldValue is nil to KVCompareAndSet * Updated error text to include CompareAndSet
Этот коммит содержится в:
коммит произвёл
Christopher Speller
родитель
446c6d452e
Коммит
6f8577b4c1
@@ -71,6 +71,51 @@ func (ps SqlPluginStore) SaveOrUpdate(kv *model.PluginKeyValue) store.StoreChann
|
||||
})
|
||||
}
|
||||
|
||||
func (ps SqlPluginStore) CompareAndSet(kv *model.PluginKeyValue, oldValue []byte) (bool, *model.AppError) {
|
||||
if err := kv.IsValid(); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if oldValue == nil {
|
||||
// Insert if oldValue is nil
|
||||
if err := ps.GetMaster().Insert(kv); err != nil {
|
||||
// If the error is from unique constraints violation, it's the result of a
|
||||
// race condition, return false and no error. Otherwise we have a real error and
|
||||
// need to return it.
|
||||
if IsUniqueConstraintError(err, []string{"PRIMARY", "PluginId", "Key", "PKey"}) {
|
||||
return false, nil
|
||||
} else {
|
||||
return false, model.NewAppError("SqlPluginStore.CompareAndSet", "store.sql_plugin_store.save.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
} 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`,
|
||||
map[string]interface{}{
|
||||
"PluginId": kv.PluginId,
|
||||
"Key": kv.Key,
|
||||
"Old": oldValue,
|
||||
"New": kv.Value,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return false, model.NewAppError("SqlPluginStore.CompareAndSet", "store.sql_plugin_store.save.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
if rowsAffected, err := updateResult.RowsAffected(); err != nil {
|
||||
// Failed to update
|
||||
return false, model.NewAppError("SqlPluginStore.CompareAndSet", "store.sql_plugin_store.save.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
} else if rowsAffected == 0 {
|
||||
// No rows were affected by the update, where condition was not satisfied,
|
||||
// return false, but no error.
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (ps SqlPluginStore) Get(pluginId, key string) store.StoreChannel {
|
||||
return store.Do(func(result *store.StoreResult) {
|
||||
var kv *model.PluginKeyValue
|
||||
|
||||
Ссылка в новой задаче
Block a user