func FromGAEWithoutValidate(k *datastore.Key) (result key.Key) { if k == nil { return key.Key("") } result = key.NewWithoutValidate(k.Kind(), k.StringID(), k.IntID(), FromGAEWithoutValidate(k.Parent())) return }
// Get given a *datastore.Key returns a single entity from the store func Get(c appengine.Context, key *datastore.Key, dst interface{}) (err error) { sc := getConfig(key.Kind()) needMemory := true needMemcache := true if sc.Memory { err = memory.Get(c, key, dst) if err == nil { needMemory = false goto Complete } } if sc.Memcache { err = memcache.Get(c, key, dst) if err == nil { needMemcache = false goto Complete } } if sc.Datastore { err = dsds.Get(c, key, dst) if err == nil { goto Complete } } return Complete: // Save the entity to any caches that it should be saved to. if sc.Memcache && needMemcache { _, _ = memcache.Put(c, key, dst) } if sc.Memory && needMemory { _, _ = memory.Put(c, key, dst) } return }
// Valid only if k has no descendents of its own kind. func exists(c appengine.Context, k *datastore.Key) (bool, error) { count, err := datastore.NewQuery(k.Kind()).KeysOnly().Ancestor(k).Count(c) if err != nil { return false, err } return (count != 0), err }
func FromGAE(k *datastore.Key) (result key.Key, err error) { if k == nil { return key.Key(""), nil } parent, err := FromGAE(k.Parent()) if err != nil { return } return key.New(k.Kind(), k.StringID(), k.IntID(), parent) }
func TestDatastoreKeyForUnpersistedRecord(t *testing.T) { people := CreateTestModel() person := people.New() var key *datastore.Key = person.DatastoreKey() assertEqual(t, int64(0), key.IntID()) assertEqual(t, people.RecordType(), key.Kind()) }
func TestDatastoreKeyForPersistedRecord(t *testing.T) { people := CreateTestModelWithPropertyType("modeltwo") person := people.New().setID(123) var key *datastore.Key = person.DatastoreKey() assertEqual(t, int64(123), key.IntID()) assertEqual(t, people.RecordType(), key.Kind()) }
func recursiveJson(key *datastore.Key) Response { var parentJson Response if key.Parent() != nil { parentJson = recursiveJson(key.Parent()) } return Response{ "stringID": key.StringID(), "intID": key.IntID(), "kind": key.Kind(), "appID": key.AppID(), "namespace": key.Namespace(), "parent": parentJson, } }
// Can check if the user has permission to perform the action. func (u *User) Can(c appengine.Context, perm string, key *datastore.Key) bool { // Users can do anything to their own user object. if key.Kind() == "User" && u.Key.StringID() == key.StringID() { return true } // Admins can do anything. if u.HasRole("admin") { return true } // Other permissions must be set. if ok, _ := acl.Can(c, u.Key.String(), perm, key); ok { return true } return false }
// Put given a *datastore.Key and a struct pointer adds a single entity // to the store. func Put(c appengine.Context, key *datastore.Key, src interface{}) (*datastore.Key, error) { sc := getConfig(key.Kind()) key, err := dsds.Put(c, key, src) if err != nil { return key, err } if sc.Memcache { key, err = memcache.Put(c, key, src) } if sc.Memory { key, err = memory.Put(c, key, src) } return key, err }
func translate(sourceKey *datastore.Key, translateAppId bool, targetAppId string, translateNamespace bool, targetNamespace string) (*datastore.Key, error) { if !translateAppId { targetAppId = sourceKey.AppID() } if !translateNamespace { targetNamespace = sourceKey.Namespace() } var translatedParent *datastore.Key = nil if sourceKey.Parent() != nil { var err error translatedParent, err = translate(sourceKey.Parent(), translateAppId, targetAppId, translateNamespace, targetNamespace) if err != nil { return nil, err } } return datastorekey.CreateKey(nil, targetAppId, targetNamespace, sourceKey.Kind(), sourceKey.StringID(), sourceKey.IntID(), translatedParent) }
func fillFields(key *datastore.Key, data map[string]interface{}) { data["kind"] = key.Kind() data["stringid"] = key.StringID() data["intid"] = key.IntID() data["appid"] = key.AppID() data["namespace"] = key.Namespace() if key.Parent() != nil { data["kind2"] = key.Parent().Kind() data["stringid2"] = key.Parent().StringID() data["intid2"] = key.Parent().IntID() if key.Parent().Parent() != nil { data["kind3"] = key.Parent().Parent().Kind() data["stringid3"] = key.Parent().Parent().StringID() data["intid3"] = key.Parent().Parent().IntID() } } }
func extract(key *datastore.Key, field string) (string, error) { switch strings.ToLower(field) { case "kind": return key.Kind(), nil case "appid": return key.AppID(), nil case "namespace": return key.Namespace(), nil case "name": return key.StringID(), nil case "id": return fmt.Sprintf("%v", key.IntID()), nil case "parent": if key.Parent() == nil { return "", nil } else { return key.Parent().Encode(), nil } default: return "", fmt.Errorf("Unsupported field [%v]. Supported fields are kind, appID, namespace, name, id, parentkey.", field) } }
func (g *Goon) setStructKey(src interface{}, key *datastore.Key) 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]) && g.KindNameResolver(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") } dskeyType := reflect.TypeOf(&datastore.Key{}) vfType := vf.Type() if vfType.ConvertibleTo(dskeyType) { vf.Set(reflect.ValueOf(key.Parent()).Convert(vfType)) parentSet = true } } } } if !idSet { return fmt.Errorf("goon: Could not set id field") } return nil }
// cacheKey generates a memcache key for this non-nil *datastore.Key. func cacheKey(key *datastore.Key) string { return fmt.Sprintf("%v/%v/sb=>%v", key.Encode(), key.Kind(), key.StringID()) }
func rebuildKey(c appengine.Context, key *datastore.Key) *datastore.Key { if key == nil { return nil } return datastore.NewKey(c, key.Kind(), key.StringID(), key.IntID(), rebuildKey(c, key.Parent())) }