Index: go/src/infra/gae/libs/gae/prod/raw_datastore_type_converter.go |
diff --git a/go/src/infra/gae/libs/gae/prod/raw_datastore_type_converter.go b/go/src/infra/gae/libs/gae/prod/raw_datastore_type_converter.go |
new file mode 100644 |
index 0000000000000000000000000000000000000000..87fdce1400d00c1ff89281bc37ba9ca59c47f192 |
--- /dev/null |
+++ b/go/src/infra/gae/libs/gae/prod/raw_datastore_type_converter.go |
@@ -0,0 +1,85 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+package prod |
+ |
+import ( |
+ "errors" |
+ |
+ "infra/gae/libs/gae" |
+ |
+ "google.golang.org/appengine" |
+ "google.golang.org/appengine/datastore" |
+) |
+ |
+type typeFilter struct { |
+ dps gae.DSPropertyLoadSaver |
+} |
+ |
+var _ datastore.PropertyLoadSaver = &typeFilter{} |
+ |
+func (tf *typeFilter) Load(props []datastore.Property) (err error) { |
+ newProps := map[string][]gae.DSProperty{} |
+ for _, p := range props { |
+ val := p.Value |
+ switch x := val.(type) { |
+ case datastore.ByteString: |
+ val = gae.DSByteString(x) |
+ case *datastore.Key: |
+ val = dsR2F(x) |
+ case appengine.BlobKey: |
+ val = gae.BSKey(x) |
+ case appengine.GeoPoint: |
+ val = gae.DSGeoPoint(x) |
+ } |
+ prop := gae.DSProperty{} |
+ if err = prop.SetValue(val, p.NoIndex); err != nil { |
+ return err |
+ } |
+ newProps[p.Name] = append(newProps[p.Name], prop) |
+ } |
+ convFailures, err := tf.dps.Load(newProps) |
+ if err == nil && len(convFailures) > 0 { |
+ me := make(gae.MultiError, len(convFailures)) |
+ for i, f := range convFailures { |
+ me[i] = errors.New(f) |
+ } |
+ err = me |
+ } |
+ return |
+} |
+ |
+func (tf *typeFilter) Save() ([]datastore.Property, error) { |
+ newProps, err := tf.dps.Save() |
+ if err != nil { |
+ return nil, err |
+ } |
+ |
+ props := []datastore.Property{} |
+ for name, propList := range newProps { |
+ multiple := len(propList) > 1 |
+ for _, prop := range propList { |
+ toAdd := datastore.Property{ |
+ Name: name, |
+ Multiple: multiple, |
+ NoIndex: prop.NoIndex(), |
+ } |
+ switch x := prop.Value().(type) { |
+ case gae.DSByteString: |
+ toAdd.Value = datastore.ByteString(x) |
+ case gae.DSKey: |
+ toAdd.Value = dsF2R(x) |
+ case gae.BSKey: |
+ toAdd.Value = appengine.BlobKey(x) |
+ case gae.DSGeoPoint: |
+ toAdd.Value = appengine.GeoPoint(x) |
+ default: |
+ toAdd.Value = x |
+ } |
+ props = append(props, toAdd) |
+ } |
+ } |
+ |
+ return props, nil |
+} |