Allow for returning map[string]interface{} from patch.

pull/6/head
Wojciech Tyczynski 2016-12-30 11:19:22 +01:00
parent 8f99b74466
commit d08abdb187
6 changed files with 41 additions and 27 deletions

View File

@ -244,7 +244,7 @@ func (e *eventLogger) eventObserve(newEvent *v1.Event) (*v1.Event, []byte, error
newData, _ := json.Marshal(event)
oldData, _ := json.Marshal(eventCopy2)
patch, err = strategicpatch.CreateStrategicMergePatch(oldData, newData, event)
patch, err = strategicpatch.CreateTwoWayMergePatch(oldData, newData, event)
}
// record our new observation

View File

@ -111,10 +111,10 @@ func (nsu *nodeStatusUpdater) UpdateNodeStatuses() error {
}
patchBytes, err :=
strategicpatch.CreateStrategicMergePatch(oldData, newData, node)
strategicpatch.CreateTwoWayMergePatch(oldData, newData, node)
if err != nil {
return fmt.Errorf(
"failed to CreateStrategicMergePatch for node %q. %v",
"failed to CreateTwoWayMergePatch for node %q. %v",
nodeName,
err)
}

View File

@ -607,11 +607,11 @@ func patchResource(
if err != nil {
return nil, err
}
currentPatch, err := strategicpatch.CreateStrategicMergePatch(originalObjJS, currentObjectJS, versionedObj)
currentPatch, err := strategicpatch.CreateTwoWayMergePatch(originalObjJS, currentObjectJS, versionedObj)
if err != nil {
return nil, err
}
originalPatch, err := strategicpatch.CreateStrategicMergePatch(originalObjJS, originalPatchedObjJS, versionedObj)
originalPatch, err := strategicpatch.CreateTwoWayMergePatch(originalObjJS, originalPatchedObjJS, versionedObj)
if err != nil {
return nil, err
}
@ -1090,7 +1090,7 @@ func getPatchedJS(patchType types.PatchType, originalJS, patchJS []byte, obj run
case types.MergePatchType:
return jsonpatch.MergePatch(originalJS, patchJS)
case types.StrategicMergePatchType:
return strategicpatch.StrategicMergePatchData(originalJS, patchJS, obj)
return strategicpatch.StrategicMergePatch(originalJS, patchJS, obj)
default:
// only here as a safety net - go-restful filters content-type
return nil, fmt.Errorf("unknown Content-Type header for patch: %v", patchType)

View File

@ -215,7 +215,7 @@ func (tc *patchTestCase) Run(t *testing.T) {
continue
case types.StrategicMergePatchType:
patch, err = strategicpatch.CreateStrategicMergePatch(originalObjJS, changedJS, versionedObj)
patch, err = strategicpatch.CreateTwoWayMergePatch(originalObjJS, changedJS, versionedObj)
if err != nil {
t.Errorf("%s: unexpected error: %v", tc.name, err)
return

View File

@ -261,7 +261,7 @@ func getPatchedJSON(patchType types.PatchType, originalJS, patchJS []byte, obj r
return jsonpatch.MergePatch(originalJS, patchJS)
case types.StrategicMergePatchType:
return strategicpatch.StrategicMergePatchData(originalJS, patchJS, obj)
return strategicpatch.StrategicMergePatch(originalJS, patchJS, obj)
default:
// only here as a safety net - go-restful filters content-type

View File

@ -48,6 +48,13 @@ const (
deleteFromPrimitiveListDirectivePrefix = "$deleteFromPrimitiveList"
)
// JSONMap is a representations of JSON object encoded as map[string]interface{}
// where the children can be either map[string]interface{}, []interface{} or
// primitive type).
// Operating on JSONMap representation is much faster as it doesn't require any
// json marshaling and/or unmarshaling operations.
type JSONMap map[string]interface{}
// IsPreconditionFailed returns true if the provided error indicates
// a precondition failed.
func IsPreconditionFailed(err error) bool {
@ -136,11 +143,6 @@ func RequireMetadataKeyUnchanged(key string) PreconditionFunc {
}
}
// Deprecated: Use the synonym CreateTwoWayMergePatch, instead.
func CreateStrategicMergePatch(original, modified []byte, dataStruct interface{}) ([]byte, error) {
return CreateTwoWayMergePatch(original, modified, dataStruct)
}
// CreateTwoWayMergePatch creates a patch that can be passed to StrategicMergePatch from an original
// document and a modified document, which are passed to the method as json encoded content. It will
// return a patch that yields the modified document when applied to the original document, or an error
@ -160,12 +162,24 @@ func CreateTwoWayMergePatch(original, modified []byte, dataStruct interface{}, f
}
}
patchMap, err := CreateTwoWayMergeMapPatch(originalMap, modifiedMap, dataStruct, fns...)
if err != nil {
return nil, err
}
return json.Marshal(patchMap)
}
// CreateTwoWayMergeMapPatch creates a patch from an original and modified JSON objects,
// encoded JSONMap.
// The serialized version of the map can then be passed to StrategicMergeMapPatch.
func CreateTwoWayMergeMapPatch(original, modified JSONMap, dataStruct interface{}, fns ...PreconditionFunc) (JSONMap, error) {
t, err := getTagStructType(dataStruct)
if err != nil {
return nil, err
}
patchMap, err := diffMaps(originalMap, modifiedMap, t, false, false)
patchMap, err := diffMaps(original, modified, t, false, false)
if err != nil {
return nil, err
}
@ -177,7 +191,7 @@ func CreateTwoWayMergePatch(original, modified []byte, dataStruct interface{}, f
}
}
return json.Marshal(patchMap)
return patchMap, nil
}
// Returns a (recursive) strategic merge patch that yields modified when applied to original.
@ -494,12 +508,6 @@ loopB:
return patch, nil
}
// Deprecated: StrategicMergePatchData is deprecated. Use the synonym StrategicMergePatch,
// instead, which follows the naming convention of evanphx/json-patch.
func StrategicMergePatchData(original, patch []byte, dataStruct interface{}) ([]byte, error) {
return StrategicMergePatch(original, patch, dataStruct)
}
// StrategicMergePatch applies a strategic merge patch. The patch and the original document
// must be json encoded content. A patch can be created from an original and a modified document
// by calling CreateStrategicMergePatch.
@ -524,12 +532,7 @@ func StrategicMergePatch(original, patch []byte, dataStruct interface{}) ([]byte
return nil, errBadJSONDoc
}
t, err := getTagStructType(dataStruct)
if err != nil {
return nil, err
}
result, err := mergeMap(originalMap, patchMap, t, true)
result, err := StrategicMergeMapPatch(originalMap, patchMap, dataStruct)
if err != nil {
return nil, err
}
@ -537,6 +540,17 @@ func StrategicMergePatch(original, patch []byte, dataStruct interface{}) ([]byte
return json.Marshal(result)
}
// StrategicMergePatch applies a strategic merge patch. The original and patch documents
// must be JSONMap. A patch can be created from an original and modified document by
// calling CreateTwoWayMergeMapPatch.
func StrategicMergeMapPatch(original, patch JSONMap, dataStruct interface{}) (JSONMap, error) {
t, err := getTagStructType(dataStruct)
if err != nil {
return nil, err
}
return mergeMap(original, patch, t, true)
}
func getTagStructType(dataStruct interface{}) (reflect.Type, error) {
if dataStruct == nil {
return nil, fmt.Errorf(errBadArgTypeFmt, "struct", "nil")