func serveDocumentsUpdate(res http.ResponseWriter, req *http.Request, params httprouter.Params) { serveAPI(res, req, func() interface{} { ctx := appengine.NewContext(req) session, _ := sessionStore.Get(req, "session") email, ok := session.Values["email"].(string) if !ok { return HTTPError{403, "access denied"} } var document Document err := json.NewDecoder(req.Body).Decode(&document) if err != nil { return err } document.ID = params.ByName("id") userKey := datastore.NewKey(ctx, "User", email, 0, nil) docKey := datastore.NewKey(ctx, "Document", params.ByName("id"), 0, userKey) var originalDocument Document err = datastore.Get(ctx, docKey, &originalDocument) if err != nil { return err } _, err = datastore.Put(ctx, docKey, &document) if err != nil { return err } return document }) }
func serveDocumentsDelete(res http.ResponseWriter, req *http.Request, params httprouter.Params) { serveAPI(res, req, func() interface{} { ctx := appengine.NewContext(req) session, _ := sessionStore.Get(req, "session") email, ok := session.Values["email"].(string) if !ok { return HTTPError{403, "access denied"} } id := params.ByName("id") userKey := datastore.NewKey(ctx, "User", email, 0, nil) docKey := datastore.NewKey(ctx, "Document", id, 0, userKey) var document Document err := datastore.Get(ctx, docKey, &document) if err != nil { return err } err = datastore.Delete(ctx, docKey) if err != nil { return err } return true }) }
func TestProcess(t *testing.T) { ctx, done, _ := aetest.NewContext() defer done() smallTest := strings.NewReader(`{ "User/jsmith": { "Name": "John Smith", "LotteryNumbers": [1,2,3,4,5], "CreatedAt": { "Type": "time", "Value": "1993-05-01T12:31:00.000Z" } }, "User/jdoe": { "Name": "Jane Doe", "LotteryNumbers": [2,4,6,8,10], "CreatedAt": { "Type": "time", "Value": "1992-01-30T08:01:00.000Z" } } }`) if err := Process(ctx, smallTest); err != nil { t.Errorf("Unexpected error %s", err) } key1 := datastore.NewKey(ctx, "User", "jdoe", 0, nil) key2 := datastore.NewKey(ctx, "User", "jsmith", 0, nil) value1 := fakeUser{} value2 := fakeUser{} if err := nds.Get(ctx, key1, &value1); err != nil { t.Errorf("Unexpected error %s retrieving value1", err) } else if err := nds.Get(ctx, key2, &value2); err != nil { t.Errorf("Unexpected error %s retrieving value2", err) } value1.CreatedAt = value1.CreatedAt.UTC() value2.CreatedAt = value2.CreatedAt.UTC() if !reflect.DeepEqual(value1, fakeUser{ Name: "Jane Doe", LotteryNumbers: []int64{2, 4, 6, 8, 10}, CreatedAt: time.Date(1992, 1, 30, 8, 1, 0, 0, time.UTC), }) { t.Errorf("Unexpected value in value1: %+v", value1) } if !reflect.DeepEqual(value2, fakeUser{ Name: "John Smith", LotteryNumbers: []int64{1, 2, 3, 4, 5}, CreatedAt: time.Date(1993, 5, 1, 12, 31, 0, 0, time.UTC), }) { t.Errorf("Unexpected value in value2: %+v", value1) } }
func serveDocumentsCreate(res http.ResponseWriter, req *http.Request, params httprouter.Params) { serveAPI(res, req, func() interface{} { ctx := appengine.NewContext(req) session, _ := sessionStore.Get(req, "session") email, ok := session.Values["email"].(string) if !ok { return HTTPError{403, "access denied"} } var document Document err := json.NewDecoder(req.Body).Decode(&document) if err != nil { return err } if document.ID != "" { return fmt.Errorf("invalid document: id must not be set") } document.ID = uuid.NewV1().String() userKey := datastore.NewKey(ctx, "User", email, 0, nil) docKey := datastore.NewKey(ctx, "Document", document.ID, 0, userKey) docKey, err = datastore.Put(ctx, docKey, &document) if err != nil { return err } return document }) }
func (s *SpaceService) ByID(ctx context.Context, id string) (*Space, error) { rootKey := datastore.NewKey(ctx, "Root", "root", 0, nil) k := datastore.NewKey(ctx, "Space", id, 0, rootKey) csp, ok := CacheFromContext(ctx).Get(k).(*Space) if ok { return csp, nil } span := trace.FromContext(ctx).NewChild("trythings.space.ByID") defer span.Finish() var sp Space err := datastore.Get(ctx, k, &sp) if err != nil { return nil, err } ok, err = s.IsVisible(ctx, &sp) if err != nil { return nil, err } if !ok { return nil, errors.New("cannot access space") } CacheFromContext(ctx).Set(k, &sp) return &sp, nil }
func (s *UserService) Create(ctx context.Context, u *User) error { span := trace.FromContext(ctx).NewChild("trythings.user.Create") defer span.Finish() // TODO Make sure u.GoogleID == user.Current(ctx).ID if u.ID != "" { return fmt.Errorf("u already has id %q", u.ID) } if u.CreatedAt.IsZero() { u.CreatedAt = time.Now() } id, _, err := datastore.AllocateIDs(ctx, "User", nil, 1) if err != nil { return err } u.ID = fmt.Sprintf("%x", id) rootKey := datastore.NewKey(ctx, "Root", "root", 0, nil) k := datastore.NewKey(ctx, "User", u.ID, 0, rootKey) k, err = datastore.Put(ctx, k, u) if err != nil { return err } return nil }
func decodeKey(c context.Context, v interface{}) (*datastore.Key, error) { var result, ancestor *datastore.Key p, ok := v.([]interface{}) if !ok { return nil, ErrInvalidKeyElement } for i := 0; i < len(p); i += 2 { kind := p[i].(string) id := p[i+1] switch id.(type) { case string: result = datastore.NewKey(c, kind, id.(string), 0, ancestor) case json.Number: n, err := id.(json.Number).Int64() if err != nil { return nil, invalidIDError(id) } result = datastore.NewKey(c, kind, "", n, ancestor) default: return nil, invalidIDError(id) } ancestor = result } return result, nil }
func newSceneProcess(res http.ResponseWriter, req *http.Request, _ httprouter.Params) { ctx := appengine.NewContext(req) sd := sessionInfo(req) t := time.Now() time := t.Local() s := fmt.Sprintf("%v", time) scene := Scene{ Author: sd.Username, Name: req.FormValue("name"), Content: req.FormValue("scene"), CreatedDate: s, } storykey := datastore.NewKey(ctx, "Stories", req.FormValue("story"), 0, nil) key := datastore.NewKey(ctx, "Scenes", req.FormValue("name"), 0, storykey) //owner is ancestor - eliminates need for owner-story table key, err := datastore.Put(ctx, key, &scene) if err != nil { log.Errorf(ctx, "error adding todo: %v", err) http.Error(res, err.Error(), 500) return } // redirect link := strings.Replace(req.FormValue("story"), " ", "-", -1) http.Redirect(res, req, "/view/"+link+"/"+sd.Username, 302) }
func (s *SearchService) Update(ctx context.Context, se *Search) error { span := trace.FromContext(ctx).NewChild("trythings.search.Update") defer span.Finish() if se.ID == "" { return errors.New("cannot update search with no ID") } // Make sure we have access to the search before it was modified. _, err := s.ByID(ctx, se.ID) if err != nil { return err } // Make sure we continue to have access to the task after our update. ok, err := s.IsVisible(ctx, se) if err != nil { return err } if !ok { return errors.New("cannot update search to lose access") } rootKey := datastore.NewKey(ctx, "Root", "root", 0, nil) k := datastore.NewKey(ctx, "Search", se.ID, 0, rootKey) _, err = datastore.Put(ctx, k, se) if err != nil { return err } CacheFromContext(ctx).Set(k, se) return nil }
func example6() { type Photo struct { URL string } var ctx context.Context // [START ancestor_query_example] // Create two Photo entities in the datastore with a Person as their ancestor. tomKey := datastore.NewKey(ctx, "Person", "Tom", 0, nil) wPhoto := Photo{URL: "http://example.com/some/path/to/wedding_photo.jpg"} wKey := datastore.NewKey(ctx, "Photo", "", 0, tomKey) _, err := datastore.Put(ctx, wKey, wPhoto) // check err bPhoto := Photo{URL: "http://example.com/some/path/to/baby_photo.jpg"} bKey := datastore.NewKey(ctx, "Photo", "", 0, tomKey) _, err = datastore.Put(ctx, bKey, bPhoto) // check err // Now fetch all Photos that have tomKey as an ancestor. // This will populate the photos slice with wPhoto and bPhoto. q := datastore.NewQuery("Photo").Ancestor(tomKey) var photos []Photo _, err = q.GetAll(ctx, &photos) // check err // do something with photos // [END ancestor_query_example] _ = err _ = photos }
func viewStory(res http.ResponseWriter, req *http.Request, ps httprouter.Params) { ctx := appengine.NewContext(req) sd := sessionInfo(req) link := ps.ByName("story") title := strings.Replace(link, "-", " ", -1) //translate link to title owner := ps.ByName("owner") userkey := datastore.NewKey(ctx, "Users", owner, 0, nil) key := datastore.NewKey(ctx, "Stories", title, 0, userkey) //owner is ancestor - eliminates need for owner-story table var story Story err := datastore.Get(ctx, key, &story) if err != nil { panic(err) } var user User user.Username = owner err = datastore.Get(ctx, userkey, &user) if err != nil { panic(err) } sd.ViewingStory = story sd.ViewingUser = user tpl.ExecuteTemplate(res, "view.html", &sd) }
func (s *ViewService) ByID(ctx context.Context, id string) (*View, error) { rootKey := datastore.NewKey(ctx, "Root", "root", 0, nil) k := datastore.NewKey(ctx, "View", id, 0, rootKey) cv, ok := CacheFromContext(ctx).Get(k).(*View) if ok { return cv, nil } span := trace.FromContext(ctx).NewChild("trythings.view.ByID") defer span.Finish() var v View err := datastore.Get(ctx, k, &v) if err != nil { return nil, err } ok, err = s.IsVisible(ctx, &v) if err != nil { return nil, err } if !ok { return nil, errors.New("cannot access view") } CacheFromContext(ctx).Set(k, &v) return &v, nil }
func index(res http.ResponseWriter, req *http.Request) { if req.Method == "POST" { name := req.FormValue("name") descrip := req.FormValue("descrip") ctx := appengine.NewContext(req) parentKey := datastore.NewKey(ctx, "House", "Garage", 0, nil) key := datastore.NewKey(ctx, "Tools", name, 0, parentKey) // 1 write / second // We will eventually use memcache to buffer our writes entity := &Tool{ Name: name, Description: descrip, } _, err := datastore.Put(ctx, key, entity) if err != nil { http.Error(res, err.Error(), 500) return } } res.Header().Set("Content-Type", "text/html") fmt.Fprintln(res, ` <form method="POST"> <h1>Tool</h1> <input type="text" name="name"><br> <h1>Descrip</h1> <textarea name="descrip"></textarea> <input type="submit"> </form>`) }
func newStoryProcess(res http.ResponseWriter, req *http.Request, _ httprouter.Params) { ctx := appengine.NewContext(req) sd := sessionInfo(req) t := time.Now() // y, m, d := t.Date() time := t.UTC() s := fmt.Sprintf("%v", time) story := Story{ Owner: sd.Username, Title: req.FormValue("story"), Description: req.FormValue("description"), Link: strings.Replace(req.FormValue("story"), " ", "-", -1), CreatedDate: s, } userkey := datastore.NewKey(ctx, "Users", sd.Username, 0, nil) key := datastore.NewKey(ctx, "Stories", story.Title, 0, userkey) //owner is ancestor - eliminates need for owner-story table key, err := datastore.Put(ctx, key, &story) if err != nil { log.Errorf(ctx, "error adding todo: %v", err) http.Error(res, err.Error(), 500) return } // redirect http.Redirect(res, req, "/browse", 302) }
func (s *TaskService) ByID(ctx context.Context, id string) (*Task, error) { rootKey := datastore.NewKey(ctx, "Root", "root", 0, nil) k := datastore.NewKey(ctx, "Task", id, 0, rootKey) ct, ok := CacheFromContext(ctx).Get(k).(*Task) if ok { return ct, nil } span := trace.FromContext(ctx).NewChild("trythings.task.ByID") defer span.Finish() var t Task err := datastore.Get(ctx, k, &t) if err != nil { return nil, err } ok, err = s.IsVisible(ctx, &t) if err != nil { return nil, err } if !ok { return nil, errors.New("cannot access task") } CacheFromContext(ctx).Set(k, &t) return &t, nil }
// ByIDs filters out Tasks that are not visible to the current User. func (s *TaskService) ByIDs(ctx context.Context, ids []string) ([]*Task, error) { span := trace.FromContext(ctx).NewChild("trythings.task.ByIDs") defer span.Finish() rootKey := datastore.NewKey(ctx, "Root", "root", 0, nil) ks := []*datastore.Key{} for _, id := range ids { ks = append(ks, datastore.NewKey(ctx, "Task", id, 0, rootKey)) } var allTasks = make([]*Task, len(ks)) err := datastore.GetMulti(ctx, ks, allTasks) if err != nil { return nil, err } ts := []*Task{} for _, t := range allTasks { // TODO#Perf: Batch the isVisible check. ok, err := s.IsVisible(ctx, t) if err != nil { return nil, err } if !ok { continue } ts = append(ts, t) } return ts, nil }
func editPassword(res http.ResponseWriter, req *http.Request, _ httprouter.Params) { ctx := appengine.NewContext(req) sd := sessionInfo(req) key := datastore.NewKey(ctx, "Users", sd.Username, 0, nil) var user User err := datastore.Get(ctx, key, &user) if err != nil || bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(req.FormValue("password"))) != nil { // wrong current password http.Redirect(res, req, "/user/"+sd.Username, 302) return } else { // correct current password hashedPass, err := bcrypt.GenerateFromPassword([]byte(req.FormValue("password1")), bcrypt.DefaultCost) if err != nil { log.Errorf(ctx, "error creating password: %v", err) http.Error(res, err.Error(), 500) return } user.Password = string(hashedPass) key = datastore.NewKey(ctx, "Users", sd.Username, 0, nil) key, err = datastore.Put(ctx, key, &user) if err != nil { http.Error(res, err.Error(), 500) return } createSession(res, req, user) } // redirect to profile page http.Redirect(res, req, "/user/"+sd.Username, 302) }
func follow(res http.ResponseWriter, req *http.Request, ps httprouter.Params) { ctx := appengine.NewContext(req) // get session memItem, err := getSession(req) if err != nil { log.Infof(ctx, "Attempt to follow from logged out user") http.Error(res, "You must be logged in", http.StatusForbidden) return } // declare a variable of type user // initialize user with values from memcache item var user User json.Unmarshal(memItem.Value, &user) // get the datastore key for the follower followerKey := datastore.NewKey(ctx, "Users", user.UserName, 0, nil) // get a datastore key for the followee followeeKey := datastore.NewKey(ctx, "Follows", ps.ByName("user"), 0, followerKey) // the follower is following the followee // put this into the datastore type F struct { Following string } // _, err = datastore.Put(ctx, followeeKey, &F{ps.ByName("user")}) if err != nil { log.Errorf(ctx, "error adding followee: %v", err) http.Error(res, err.Error(), 500) return } http.Redirect(res, req, "/user/"+ps.ByName("user"), 302) }
func (s *UserService) ByID(ctx context.Context, id string) (*User, error) { rootKey := datastore.NewKey(ctx, "Root", "root", 0, nil) k := datastore.NewKey(ctx, "User", id, 0, rootKey) cu, ok := CacheFromContext(ctx).Get(k).(*User) if ok { return cu, nil } var u User err := datastore.Get(ctx, k, &u) if err != nil { return nil, err } ok, err = s.IsVisible(ctx, &u) if err != nil { return nil, err } if !ok { return nil, errors.New("cannot access user") } CacheFromContext(ctx).Set(k, &u) return &u, nil }
func ParseKeyFromID(ctx context.Context, id string, m DataModel) *datastore.Key { ty := getType(m) parentKey := datastore.NewKey(ctx, "Model", "Model", 0, nil) i, _ := strconv.Atoi(id) key := datastore.NewKey(ctx, ty, "", int64(i), parentKey) return key }
// Increment increments the named counter. func Increment(ctx context.Context, name string) error { // Get counter config. var cfg counterConfig ckey := datastore.NewKey(ctx, configKind, name, 0, nil) err := datastore.RunInTransaction(ctx, func(ctx context.Context) error { err := datastore.Get(ctx, ckey, &cfg) if err == datastore.ErrNoSuchEntity { cfg.Shards = defaultShards _, err = datastore.Put(ctx, ckey, &cfg) } return err }, nil) if err != nil { return err } var s shard err = datastore.RunInTransaction(ctx, func(ctx context.Context) error { shardName := fmt.Sprintf("%s-shard%d", name, rand.Intn(cfg.Shards)) key := datastore.NewKey(ctx, shardKind, shardName, 0, nil) err := datastore.Get(ctx, key, &s) // A missing entity and a present entity will both work. if err != nil && err != datastore.ErrNoSuchEntity { return err } s.Name = name s.Count++ _, err = datastore.Put(ctx, key, &s) return err }, nil) if err != nil { return err } memcache.IncrementExisting(ctx, memcacheKey(name), 1) return nil }
func showWord(res http.ResponseWriter, req *http.Request) { ctx := appengine.NewContext(req) var key *datastore.Key x := strings.Split(req.URL.Path, "/")[1] y, err := strconv.Atoi(x) if err != nil { key = datastore.NewKey(ctx, "Word", x, 0, nil) } else { key = datastore.NewKey(ctx, "Word", "", int64(y), nil) } var entity Word err = datastore.Get(ctx, key, &entity) if err == datastore.ErrNoSuchEntity { http.NotFound(res, req) return } else if err != nil { http.Error(res, err.Error(), 500) return } fmt.Fprintln(res, ` <dl> <dt>`+entity.Term+`</dt> <dd>`+entity.Definition+`</dd> </dl> `) }
func TestEncodeEntities(t *testing.T) { c, clean, err := aetest.NewContext() if err != nil { t.Fatal(err) } defer clean() parent := datastore.NewKey(c, "Parent", "parent-1", 0, nil) entities := make([]Entity, 0, 10) for i := 0; i < 10; i++ { id := i + 1 k := datastore.NewKey(c, "Test", "", int64(id), nil) if i%2 == 0 { k = datastore.NewKey(c, "Test", "", int64(id), parent) } e := Entity{Key: k} e.Add(datastore.Property{ Name: "name", Value: fmt.Sprintf("Test Entity #%d", id), }) for j := 0; j < 3; j++ { e.Add(datastore.Property{ Name: "tags", Value: fmt.Sprintf("tag%d", j), Multiple: true, }) } e.Add(datastore.Property{ Name: "active", Value: i%2 == 0, }) e.Add(datastore.Property{ Name: "height", Value: i * 10, }) entities = append(entities, e) } p := encodeKey(entities[0].Key) t.Logf("encodeKey: from %s to %#v", entities[0].Key, p) w := new(bytes.Buffer) err = EncodeEntities(entities, w) if err != nil { t.Fatal(err) } json := w.String() t.Logf("JSON encoded entities: %s", json) attrs := []string{"name", "tags", "active", "height"} for _, a := range attrs { if !strings.Contains(json, a) { t.Errorf("Invalid JSON string: missing attribute %s.", a) } } }
func example3() { // [START get_key] employeeKey := datastore.NewKey(ctx, "Employee", "asalieri", 0, nil) addressKey := datastore.NewKey(ctx, "Address", "", 1, employeeKey) var addr Address err = datastore.Get(ctx, addressKey, &addr) // [END get_key] }
// TestGetNamespacedKey ensures issue https://goo.gl/rXU8nK is fixed so that // memcache uses the namespace from the key instead of the context. func TestGetNamespacedKey(t *testing.T) { c, closeFunc := NewContext(t) defer closeFunc() const intVal = int64(12) type testEntity struct { IntVal int64 } namespacedCtx, err := appengine.Namespace(c, "keyNamespace") if err != nil { t.Fatal(err) } key := datastore.NewKey(c, "Entity", "", 1, nil) namespacedKey := datastore.NewKey(namespacedCtx, "Entity", "", key.IntID(), nil) entity := &testEntity{intVal} if namespacedKey, err = nds.Put(c, namespacedKey, entity); err != nil { t.Fatal(err) } // Prime cache. if err := nds.Get(namespacedCtx, namespacedKey, &testEntity{}); err != nil { t.Fatal(err) } // Ensure that we get a value back from the cache by checking if the // datastore is called at all. entityFromCache := true nds.SetDatastoreGetMulti(func(c context.Context, keys []*datastore.Key, vals interface{}) error { if len(keys) != 0 { entityFromCache = false } return nil }) if err := nds.Get(c, namespacedKey, &testEntity{}); err != nil { t.Fatal(err) } nds.SetDatastoreGetMulti(datastore.GetMulti) if !entityFromCache { t.Fatal("entity not obtained from cache") } if err := nds.Delete(namespacedCtx, namespacedKey); err != nil { t.Fatal(err) } entity = &testEntity{} if err := nds.Get(c, namespacedKey, entity); err == nil { t.Fatalf("expected no such entity error but got %+v", entity) } else if err != datastore.ErrNoSuchEntity { t.Fatal(err) } }
// Increment increments the named counter. func Increment(c context.Context, valName string) error { // Get counter config. shardsTotal := dsu.WrapInt{} dsu.McacheGet(c, mcKeyShardsTotal(valName), &shardsTotal) if shardsTotal.I < 1 { ckey := datastore.NewKey(c, dsKindNumShards, mcKeyShardsTotal(valName), 0, nil) errTx := datastore.RunInTransaction(c, func(c context.Context) error { err := datastore.Get(c, ckey, &shardsTotal) if err == datastore.ErrNoSuchEntity { shardsTotal.I = defaultNumShards _, err = datastore.Put(c, ckey, &shardsTotal) } return err }, nil) if errTx != nil { return errTx } dsu.McacheSet(c, mcKeyShardsTotal(valName), dsu.WrapInt{shardsTotal.I}) } // pick random counter and increment it errTx := datastore.RunInTransaction(c, func(c context.Context) error { shardId := rand.Intn(shardsTotal.I) dsKey := datastore.NewKey(c, dsKindShard, keySingleShard(valName, shardId), 0, nil) var sd WrapShardData err := datastore.Get(c, dsKey, &sd) // A missing entity and a present entity will both work. if err != nil && err != datastore.ErrNoSuchEntity { return err } sd.Name = valName sd.ShardId = shardId sd.I++ _, err = datastore.Put(c, dsKey, &sd) if ll > 2 { aelog.Infof(c, "ds put %v %v", dsKey, sd) } return err }, nil) if errTx != nil { return errTx } memcache.Increment(c, mcKey(valName), 1, 0) // collect number of updates // per valName per instance in memory // for every interval of 10 minutes // // a batch job checks if the number of shards should be increased or decreased // and truncates this map updateSamplingFrequency[valName+util.TimeMarker()[:len("2006-01-02 15:0")]] += 1 return nil }
func loadJsonToDatastore(ctx context.Context, pkey *datastore.Key, data map[string]interface{}, logger wcg.Logger) error { var kind string var ns string var keyval interface{} var key *datastore.Key var ok bool var err error if _, ok = data["_kind"]; !ok { return fmt.Errorf("Missing key `_kind`") } kind = data["_kind"].(string) if keyval, ok = data["_key"]; !ok { return fmt.Errorf("Missing key `_key`") } if _, ok = data["_ns"]; ok { ns = data["_ns"].(string) ctx, err = appengine.Namespace(ctx, ns) if err != nil { return fmt.Errorf("Could not change the namespace of %q, check _ns value: ", ns, err) } } switch keyval.(type) { case int64: key = datastore.NewKey(ctx, kind, "", keyval.(int64), pkey) case string: key = datastore.NewKey(ctx, kind, keyval.(string), 0, pkey) default: return fmt.Errorf("Invalid `_key` type.") } if _, err := datastore.Put(ctx, key, jsonSaver(data)); err != nil { return err } // Check the data is actually stored. if err := wcg.RetryUntil(func() error { var v jsonSaver if err := datastore.Get(ctx, key, &v); err != nil { return fmt.Errorf( "fixture is not synched on '%s:[%s]': internal error?(%v) on ", kind, keyval, err, ) } return nil }, 5*time.Second, 500*time.Millisecond); err != nil { return err } logger.Debugf("[Fixture] %s%s -- %v", ns, key, data) if children, ok := data["_children"]; ok { for _, v := range children.([]interface{}) { if err := loadJsonToDatastore(ctx, key, v.(map[string]interface{}), logger); err != nil { return err } } } return nil }
func (s *SpotGet) key(ctx context.Context) *datastore.Key { if s.SpotCode == 0 { low, _, err := datastore.AllocateIDs(ctx, "Spot", nil, 1) if err != nil { return nil } return datastore.NewKey(ctx, "Spot", "", low, nil) } return datastore.NewKey(ctx, "Spot", "", s.SpotCode, nil) }
func GetUserData(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) if userId := GetUserId(r); userId != "" { var userData UserData datastore.Get(c, datastore.NewKey(c, "UserData", userId, 0, datastore.NewKey(c, "User", userId, 0, nil)), &userData) b, _ := json.Marshal(userData) w.Header().Set("content-type", "application/json") fmt.Fprintf(w, string(b)) return } http.Error(w, "no user id present", http.StatusForbidden) }
func TestDatastoreFixture(t *testing.T) { filepath := mkTempfile(`[{ "_kind": "FixtureKind", "_key": "key1", "IntValue": 10, "FloatValue": 2.4, "BoolValue": true, "StringValue": "foobar", "BytesValue": "[]bytesfoobar", "DateTimeValue": "2014-01-02T14:02:50Z", "DateValue": "2014-01-02", "Slice": ["a", "b", "c"], "Struct": { "Foo": "bar" } },{ "_kind": "FixtureKind", "_key": "key1", "_ns": "ns1", "StringValue": "withns1" } ]`) assert := wcg.NewAssert(t) var fk FixtureKind assert.Nil(DatastoreFixture(ts.Context, filepath, nil), "DatastoreFixture") key := datastore.NewKey(ts.Context, "FixtureKind", "key1", 0, nil) wcg.NewLogger(nil).Infof("GET: %s", key) assert.Nil(datastore.Get(ts.Context, key, &fk), "datastore.Get('key1') ") assert.EqInt(10, fk.IntValue, "IntValue should be 10") assert.EqFloat32(2.4, fk.FloatValue, "FloatValue should be 2.4") assert.EqStr("foobar", fk.StringValue, "StringValue should be 'foobar'") assert.EqStr("bytesfoobar", string(fk.BytesValue), "BytesValue should be 'foobar'") assert.EqInt(3, len(fk.Slice), "len(Slice) should be 3") assert.EqStr("a", string(fk.Slice[0]), "Slice[0] should be 'a'") assert.EqStr("b", string(fk.Slice[1]), "Slice[0] should be 'a'") assert.EqStr("c", string(fk.Slice[2]), "Slice[0] should be 'a'") assert.EqTime(time.Date(2014, 01, 02, 14, 02, 50, 0, time.UTC), fk.DateTimeValue, "DateTimeValue should be 2014-01-02T14:02:50Z") assert.EqTime(time.Date(2014, 01, 02, 0, 0, 0, 0, time.UTC), fk.DateValue, "DateTimeValue should be 2014-01-02T00:00:00Z") assert.EqStr("bar", string(fk.Struct.Foo), "Struct.Foo should be 'bar'") // namespace ns1, _ := appengine.Namespace(ts.Context, "ns1") key = datastore.NewKey(ns1, "FixtureKind", "key1", 0, nil) assert.Nil(datastore.Get(ns1, key, &fk), "datastore.Get('key1') /w ns1") assert.EqStr("withns1", fk.StringValue, "StringValue should be 'withns1'") }