| Index: go/src/infra/gae/libs/wrapper/memory/internal/goon/goon.go
|
| diff --git a/go/src/infra/gae/libs/wrapper/memory/internal/goon/goon.go b/go/src/infra/gae/libs/wrapper/memory/internal/goon/goon.go
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..406d14ee4eb2f9631e8b3e6b9ffa12beab8f18e4
|
| --- /dev/null
|
| +++ b/go/src/infra/gae/libs/wrapper/memory/internal/goon/goon.go
|
| @@ -0,0 +1,103 @@
|
| +/*
|
| + * Copyright (c) 2012 Matt Jibson <matt.jibson@gmail.com>
|
| + *
|
| + * Permission to use, copy, modify, and distribute this software for any
|
| + * purpose with or without fee is hereby granted, provided that the above
|
| + * copyright notice and this permission notice appear in all copies.
|
| + *
|
| + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
| + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
| + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
| + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
| + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
| + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
| + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
| + */
|
| +
|
| +package goon
|
| +
|
| +import (
|
| + "fmt"
|
| + "reflect"
|
| + "strings"
|
| +
|
| + "appengine/datastore"
|
| +
|
| + "github.com/mjibson/goon"
|
| +)
|
| +
|
| +// copied from goon since it's internal and we need it for Put() :/
|
| +
|
| +func SetStructKey(src interface{}, key *datastore.Key, knr goon.KindNameResolver) error {
|
| + v := reflect.ValueOf(src)
|
| + t := v.Type()
|
| + k := t.Kind()
|
| +
|
| + if k != reflect.Ptr {
|
| + return fmt.Errorf("goon: Expected pointer to struct, got instead: %v", k)
|
| + }
|
| +
|
| + v = reflect.Indirect(v)
|
| + t = v.Type()
|
| + k = t.Kind()
|
| +
|
| + if k != reflect.Struct {
|
| + return fmt.Errorf(fmt.Sprintf("goon: Expected struct, got instead: %v", k))
|
| + }
|
| +
|
| + idSet := false
|
| + kindSet := false
|
| + parentSet := false
|
| + for i := 0; i < v.NumField(); i++ {
|
| + tf := t.Field(i)
|
| + vf := v.Field(i)
|
| +
|
| + if !vf.CanSet() {
|
| + continue
|
| + }
|
| +
|
| + tag := tf.Tag.Get("goon")
|
| + tagValues := strings.Split(tag, ",")
|
| + if len(tagValues) > 0 {
|
| + tagValue := tagValues[0]
|
| + if tagValue == "id" {
|
| + if idSet {
|
| + return fmt.Errorf("goon: Only one field may be marked id")
|
| + }
|
| +
|
| + switch vf.Kind() {
|
| + case reflect.Int64:
|
| + vf.SetInt(key.IntID())
|
| + idSet = true
|
| + case reflect.String:
|
| + vf.SetString(key.StringID())
|
| + idSet = true
|
| + }
|
| + } else if tagValue == "kind" {
|
| + if kindSet {
|
| + return fmt.Errorf("goon: Only one field may be marked kind")
|
| + }
|
| + if vf.Kind() == reflect.String {
|
| + if (len(tagValues) <= 1 || key.Kind() != tagValues[1]) && knr(src) != key.Kind() {
|
| + vf.Set(reflect.ValueOf(key.Kind()))
|
| + }
|
| + kindSet = true
|
| + }
|
| + } else if tagValue == "parent" {
|
| + if parentSet {
|
| + return fmt.Errorf("goon: Only one field may be marked parent")
|
| + }
|
| + if vf.Type() == reflect.TypeOf(&datastore.Key{}) {
|
| + vf.Set(reflect.ValueOf(key.Parent()))
|
| + parentSet = true
|
| + }
|
| + }
|
| + }
|
| + }
|
| +
|
| + if !idSet {
|
| + return fmt.Errorf("goon: Could not set id field")
|
| + }
|
| +
|
| + return nil
|
| +}
|
|
|