// Valid determines if a key is valid, according to a couple rules: // - k is not nil // - every token of k: // - (if !allowSpecial) token's kind doesn't start with '__' // - token's kind and appid are non-blank // - token is not incomplete // - all tokens have the same namespace and appid func Valid(k ds.Key, allowSpecial bool, aid, ns string) bool { if k == nil { return false } if aid != k.AppID() || ns != k.Namespace() { return false } for ; k != nil; k = k.Parent() { if !allowSpecial && len(k.Kind()) >= 2 && k.Kind()[:2] == "__" { return false } if k.Kind() == "" || k.AppID() == "" { return false } if k.StringID() != "" && k.IntID() != 0 { return false } if k.Parent() != nil { if k.Parent().Incomplete() { return false } if k.Parent().AppID() != k.AppID() || k.Parent().Namespace() != k.Namespace() { return false } } } return true }
func (d rdsImpl) AllocateIDs(incomplete *ds.Key, n int) (start int64, err error) { par, err := dsF2R(d.aeCtx, incomplete.Parent()) if err != nil { return } start, _, err = datastore.AllocateIDs(d.aeCtx, incomplete.Kind(), par, n) return }
func (d *dataStoreData) fixKeyLocked(ents *memCollection, key *ds.Key) (*ds.Key, error) { if key.Incomplete() { id, err := d.allocateIDsLocked(ents, key, 1) if err != nil { return key, err } key = ds.NewKey(key.AppID(), key.Namespace(), key.Kind(), "", id, key.Parent()) } return key, nil }
// Equal returns true iff the two keys represent identical key values. func Equal(a, b ds.Key) (ret bool) { ret = (a.Kind() == b.Kind() && a.StringID() == b.StringID() && a.IntID() == b.IntID() && a.AppID() == b.AppID() && a.Namespace() == b.Namespace()) if !ret { return } ap, bp := a.Parent(), b.Parent() return (ap == nil && bp == nil) || Equal(ap, bp) }
func (d *dataStoreData) allocateIDsLocked(ents *memCollection, incomplete *ds.Key, n int) (int64, error) { if d.disableSpecialEntities { return 0, errors.New("disableSpecialEntities is true so allocateIDs is disabled") } idKey := []byte(nil) if incomplete.Parent() == nil { idKey = rootIDsKey(incomplete.Kind()) } else { idKey = groupIDsKey(incomplete) } return incrementLocked(ents, idKey, n), nil }
func marshalDSKey(b *bytes.Buffer, k ds.Key) { if k.Parent() != nil { marshalDSKey(b, k.Parent()) } b.WriteByte('/') b.WriteString(k.Kind()) b.WriteByte(',') if k.StringID() != "" { b.WriteString(k.StringID()) } else { b.WriteString(strconv.FormatInt(k.IntID(), 10)) } }
// PropertyMapPartially turns a regular PropertyMap into a SerializedPmap. // Essentially all the []Property's become SerializedPslice, using cmpbin and // datastore/serialize's encodings. func PropertyMapPartially(k *ds.Key, pm ds.PropertyMap) (ret SerializedPmap) { ret = make(SerializedPmap, len(pm)+2) if k != nil { ret["__key__"] = [][]byte{ToBytes(ds.MkProperty(k))} for k != nil { ret["__ancestor__"] = append(ret["__ancestor__"], ToBytes(ds.MkProperty(k))) k = k.Parent() } } for k, vals := range pm { newVals := PropertySlice(vals) if len(newVals) > 0 { ret[k] = newVals } } return }
func partiallySerialize(k ds.Key, pm ds.PropertyMap) (ret serializedIndexablePmap) { ret = make(serializedIndexablePmap, len(pm)+2) if k == nil { impossible(fmt.Errorf("key to partiallySerialize is nil")) } ret["__key__"] = [][]byte{serialize.ToBytes(ds.MkProperty(k))} for k != nil { ret["__ancestor__"] = append(ret["__ancestor__"], serialize.ToBytes(ds.MkProperty(k))) k = k.Parent() } for k, vals := range pm { newVals := serializeRow(vals) if len(newVals) > 0 { ret[k] = newVals } } return }
func (d *dataStoreData) entsKeyLocked(key ds.Key) (*memCollection, ds.Key) { coll := "ents:" + key.Namespace() ents := d.head.GetCollection(coll) if ents == nil { ents = d.head.SetCollection(coll, nil) } if dskey.Incomplete(key) { idKey := []byte(nil) if key.Parent() == nil { idKey = rootIDsKey(key.Kind()) } else { idKey = groupIDsKey(key) } id := incrementLocked(ents, idKey) key = dskey.New(key.AppID(), key.Namespace(), key.Kind(), "", id, key.Parent()) } return ents, key }
// Root returns the entity root for the given key. func Root(k ds.Key) ds.Key { for k != nil && k.Parent() != nil { k = k.Parent() } return k }
// PartialValid returns true iff this key is suitable for use in a Put // operation. This is the same as Valid(k, false, ...), but also allowing k to // be Incomplete(). func PartialValid(k ds.Key, aid, ns string) bool { if k.Incomplete() { k = New(k.AppID(), k.Namespace(), k.Kind(), "", 1, k.Parent()) } return Valid(k, false, aid, ns) }