Пример #1
0
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
	})
}
Пример #2
0
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
	})
}
Пример #3
0
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)
	}

}
Пример #4
0
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
	})
}
Пример #5
0
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
}
Пример #6
0
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
}
Пример #7
0
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
}
Пример #8
0
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)
}
Пример #9
0
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
}
Пример #10
0
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
}
Пример #11
0
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)
}
Пример #12
0
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
}
Пример #13
0
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>`)
}
Пример #14
0
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)
}
Пример #15
0
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
}
Пример #16
0
// 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
}
Пример #17
0
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)
}
Пример #18
0
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)
}
Пример #19
0
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
}
Пример #20
0
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
}
Пример #21
0
// 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
}
Пример #22
0
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>
	`)
}
Пример #23
0
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)
		}
	}
}
Пример #24
0
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]
}
Пример #25
0
// 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)
	}
}
Пример #26
0
// 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
}
Пример #27
0
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
}
Пример #28
0
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)
}
Пример #29
0
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)
}
Пример #30
0
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'")
}