// Subscribe adds a feed to the user's feed list if it is not already there. func subscribe(c appengine.Context, f FeedInfo) error { key := datastore.NewKey(c, feedKind, f.Url, 0, nil) return datastore.RunInTransaction(c, func(c appengine.Context) error { u, err := getUserInfo(c) if err != nil { return err } if len(u.Feeds) >= maxFeeds { return fmt.Errorf("Too many feeds, max is %d", maxFeeds) } for _, k := range u.Feeds { if key.Equal(k) { return nil } } if err := datastore.Get(c, key, &f); err != nil && err != datastore.ErrNoSuchEntity { return err } f.Refs++ if _, err := datastore.Put(c, key, &f); err != nil { return err } u.Feeds = append(u.Feeds, key) _, err = datastore.Put(c, userInfoKey(c), &u) return err }, &datastore.TransactionOptions{XG: true}) }
func addTagToFact(c appengine.Context, factKey *datastore.Key, tag string) { q := datastore.NewQuery("Tag").Filter("Name =", tag) cnt, _ := q.Count(c) var existingTag Tag var existingTagKey *datastore.Key if cnt > 0 { // retrieve for t := q.Run(c); ; { existingTagKey, _ = t.Next(&existingTag) break // only need one } } else { // create a new one var t = Tag{Name: tag} existingTagKey, _ = datastore.Put(c, datastore.NewIncompleteKey(c, "Tag", nil), &t) } qft := datastore.NewQuery("FactTag"). Filter("Fact = ", factKey). Filter("Tag = ", existingTagKey) cnt2, _ := qft.Count(c) if cnt2 == 0 { // create a new one var ft = FactTag{Fact: factKey, Tag: existingTagKey} _, _ = datastore.Put(c, datastore.NewIncompleteKey(c, "FactTag", nil), &ft) } }
func accept(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) id := r.FormValue("id") intID, err := strconv.ParseInt(id, 10, 64) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } pkg := &Package{} key := datastore.NewKey(c, "Package", "", intID, nil) err = datastore.Get(c, key, pkg) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } // check if the package is already present acceptQuery := datastore.NewQuery("Package"). Filter("Accepted =", true). Filter("Repo =", pkg.Repo) var packages []*Package keys, err := acceptQuery.GetAll(c, &packages) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } if len(packages) > 1 { // just print an error to let admin know c.Errorf("More tha one package for repo: %v", pkg.Repo) } if len(packages) > 0 { // update the package and delete oldKey := keys[0] oldPkg := packages[0] oldPkg.Name = pkg.Name oldPkg.Description = pkg.Description oldPkg.IsLibrary = pkg.IsLibrary oldPkg.Category = pkg.Category oldPkg.Updated = time.Now() if _, err = datastore.Put(c, oldKey, oldPkg); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } if err = datastore.Delete(c, key); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } } else { // accept the new package pkg.Accepted = true if _, err = datastore.Put(c, key, pkg); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } } memcache.Delete(c, pkg.Repo) memcache.Delete(c, CAT) memcache.Delete(c, ALL_QUERY) }
func addTestData(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) e := DiaryEntry{ Author: "Julian", Content: []byte(`Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.`), Date: (time.Now()).Add(time.Hour * 24), CreationTime: time.Now(), } _, _ = datastore.Put(c, datastore.NewIncompleteKey(c, "DiaryEntry", nil), &e) e = DiaryEntry{ Author: "Julian", Content: []byte("It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like)."), Date: time.Now(), CreationTime: time.Now(), } _, _ = datastore.Put(c, datastore.NewIncompleteKey(c, "DiaryEntry", nil), &e) w.Header().Set("Status", "302") w.Header().Set("Location", "/") }
func save(w http.ResponseWriter, r *http.Request) { if err := r.ParseForm(); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } c := appengine.NewContext(r) u := user.Current(c) tags := strings.Split(r.FormValue("tags"), ",") p := datatypes.Post{ Author: u.String(), Title: r.FormValue("title"), Text: r.FormValue("blogcontent"), GoDate: time.Now(), ID: -1, Tags: tags, } key, err := datastore.Put(c, datastore.NewIncompleteKey(c, "posts", nil), &p) if err != nil { log.Fatal(err) } for i := range tags { _, err := datastore.Put(c, datastore.NewIncompleteKey(c, tags[i], nil), &p) if err != nil { log.Fatal(err) } } time.Sleep(500 * time.Millisecond) http.Redirect(w, r, "/posts/"+strconv.FormatInt(key.IntID(), 10), http.StatusFound) }
func createNewGame(c appengine.Context, userId string, players []string) (Game, error) { g := Game{ UserId: userId, Started: time.Now(), Players: players, } err := datastore.RunInTransaction(c, func(c appengine.Context) error { key, err := datastore.Put(c, datastore.NewIncompleteKey(c, "game", nil), &g) if err != nil { return err } // For now just add all players into the queue. for _, p := range players { qp := QueuePlayer{ UserId: p, Timestamp: time.Now(), } _, err := datastore.Put(c, datastore.NewIncompleteKey(c, "queueplayer", key), &qp) if err != nil { return err } } g.Id = key.Encode() return nil }, nil) return g, err }
func (portal Portal) save(c appengine.Context, portalId string) (*datastore.Key, error) { key := datastore.NewKey(c, "Portal", portalId, 0, nil) //save portal keys keys := portal.Keys for i := range keys { keys[i].PortalId = portalId var agentId int64 if keys[i].AgentId != 0 { agentId = keys[i].AgentId } else if keys[i].Agent.Id != 0 { agentId = keys[i].Agent.Id } else { return nil, fmt.Errorf("laca") } keys[i].AgentId = agentId kkey := datastore.NewKey(c, "Key", portalId+strconv.FormatInt(agentId, 10), 0, nil) datastore.Put(c, kkey, &keys[i]) } for _, val := range portal.Labels { SaveLabel(c, val) } _, err := datastore.Put(c, key, &portal) err = IndexPortal(c, portal) return key, err }
func (handler *userHandler) Post(r *fhttp.JsonRequest) fhttp.Response { user := new(models.User) err := r.Extract(user) if err != nil { return fhttp.UserError("invalid json") } if user.Nickname == "" { return fhttp.UserError("nickname cannot be empty") } context := appengine.NewContext((*http.Request)(r)) userKey, err := datastore.Put(context, datastore.NewIncompleteKey(context, "User", nil), user) if err != nil { return fhttp.ServerError(err.String()) } auth := models.NewAuth(userKey) _, err = datastore.Put(context, datastore.NewIncompleteKey(context, "Auth", nil), auth) if err != nil { return fhttp.ServerError(err.String()) } return fhttp.JsonResponse{ &postResponse{ fmt.Sprintf("%x", auth.Public), }, } }
// Increment increments the named counter. func Increment(c appengine.Context, name string) error { // Get counter config. var cfg counterConfig ckey := datastore.NewKey(c, configKind, name, 0, nil) err := datastore.RunInTransaction(c, func(c appengine.Context) error { err := datastore.Get(c, ckey, &cfg) if err == datastore.ErrNoSuchEntity { cfg.Shards = defaultShards _, err = datastore.Put(c, ckey, &cfg) } return err }, nil) if err != nil { return err } err = datastore.RunInTransaction(c, func(c appengine.Context) error { shardName := fmt.Sprintf("%v%d", name, rand.Intn(cfg.Shards)) key := datastore.NewKey(c, shardKind, shardName, 0, nil) var s shard err := datastore.Get(c, key, &s) // A missing entity and a present entity will both work. if err != nil && err != datastore.ErrNoSuchEntity { return err } s.Count++ s.Name = name _, err = datastore.Put(c, key, &s) return err }, nil) if err != nil { return err } //memcache.Increment(c, memcacheKey(name), 1, 0) return nil }
func pushPos(w http.ResponseWriter, r *http.Request) { data := r.FormValue("data") //fmt.Fprintf(w, "%#v",data) ent := new(Position) json.Unmarshal([]byte(data), &ent) ent.Creation = time.Now() //fmt.Fprintf(w, "%#v",ent) c := appengine.NewContext(r) k := datastore.NewIncompleteKey(c, "Position", nil) ent.Creation = time.Now() key, err := datastore.Put(c, k, ent) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } ent.IdVal = key.IntID() datastore.Put(c, key, ent) result := getPosiciones(r, ent.Track) salida, _ := json.Marshal(result) fmt.Fprintf(w, "%s", salida) return }
/* This call deletes and creates unit-testing data. */ func (h *System) CreateTestData(r *http.Request, args *SystemArgs, reply *GeneralReply) error { c := appengine.NewContext(r) var err error // delete any previous testing data { var keys_to_delete []*datastore.Key REGION_UIDS_TO_DELETE := []string{"@test-san-francisco", "@test-los-angeles"} RESTAURANT_UIDS_TO_DELETE := []string{"@test-mcdonalds", "@test-In-N-Out", "@test-Wendys"} TAGS_UIDS_TO_DELETE := []string{"@test-american", "@test-french"} for _, uid := range REGION_UIDS_TO_DELETE { q := datastore.NewQuery("Tags").Filter("Uid =", uid).KeysOnly() keys_to_delete, err = q.GetAll(c, nil) checkErr(err, "DB error1") err = datastore.DeleteMulti(c, keys_to_delete) checkErr(err, "DB error2") } for _, uid := range RESTAURANT_UIDS_TO_DELETE { q := datastore.NewQuery("Region").Filter("Uid =", uid).KeysOnly() keys_to_delete, err = q.GetAll(c, nil) checkErr(err, "DB error3") err = datastore.DeleteMulti(c, keys_to_delete) checkErr(err, "DB error4") } for _, uid := range TAGS_UIDS_TO_DELETE { q := datastore.NewQuery("Restaurant").Filter("Uid =", uid).KeysOnly() _, err = q.GetAll(c, &keys_to_delete) checkErr(err, "DB error5") err = datastore.DeleteMulti(c, keys_to_delete) checkErr(err, "DB error6") } log.Printf("... cleanup done") } // re-create the data (unless this was a cleanup operation only) if !args.CleanupOnly { region1 := models.Region{Uid: "@test-san-francisco", Title: "TEST San Francisco"} _, err = datastore.Put(c, datastore.NewKey(c, "Region", region1.Uid, 0, nil), ®ion1) checkErr(err, "fail trying to insert") region2 := models.Region{Uid: "@test-los-angeles", Title: "TEST Los Angeles"} _, err = datastore.Put(c, datastore.NewKey(c, "Region", region2.Uid, 0, nil), ®ion2) checkErr(err, "fail trying to insert") restaurant1 := models.Restaurant{Uid: "@test-mcdonalds", Title: "TEST McDonalds", Tags: []string{"French Cuisine", "American"}, Regions: []string{region1.Uid}} _, err = datastore.Put(c, datastore.NewKey(c, "Restaurant", restaurant1.Uid, 0, nil), &restaurant1) checkErr(err, "fail trying to insert") restaurant2 := models.Restaurant{Uid: "@test-In-N-Out", Tags: []string{"American"}, Regions: []string{region1.Uid, region2.Uid}} _, err = datastore.Put(c, datastore.NewKey(c, "Restaurant", restaurant2.Uid, 0, nil), &restaurant2) checkErr(err, "fail trying to insert") restaurant3 := models.Restaurant{Uid: "@test-Wendys", Tags: []string{"American"}, Regions: []string{region2.Uid}} _, err = datastore.Put(c, datastore.NewKey(c, "Restaurant", restaurant3.Uid, 0, nil), &restaurant3) checkErr(err, "fail trying to insert") log.Printf("... creation done") } return nil }
// 勉強会の追加 func (group *Group) Add(c appengine.Context) os.Error { count := new(Counter) countKey := datastore.NewKey(c, "Counter", "mycounter", 0, nil) countErr := datastore.RunInTransaction(c, func(c appengine.Context) os.Error { err := datastore.Get(c, countKey, count) if err != nil && err != datastore.ErrNoSuchEntity { return err } count.GroupCount++ _, err = datastore.Put(c, countKey, count) return err }, nil) if countErr != nil { return countErr } group.Id = count.GroupCount group.CreateDate = datastore.SecondsToTime(time.Seconds()) key := datastore.NewKey(c, "Group", "", int64(group.Id), nil) _, err := datastore.Put(c, key, group) return err }
func NewUser(r *http.Request, id string, email string, name string, provider string) (*User, error) { c := appengine.NewContext(r) // create new user userId, _, _ := datastore.AllocateIDs(c, "User", nil, 1) key := datastore.NewKey(c, "User", "", userId, nil) user := User{userId, email, name, time.Now()} _, err := datastore.Put(c, key, &user) if err != nil { return nil, err } // create external authentication externalAuthId, _, _ := datastore.AllocateIDs(c, "ExternalAuth", nil, 1) key = datastore.NewKey(c, "ExternalAuth", "", externalAuthId, nil) externalAuth := ExternalAuth{externalAuthId, id, userId, provider} _, err = datastore.Put(c, key, &externalAuth) if err != nil { return nil, err } return &user, err }
func newGrid(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) title := r.FormValue("title") rows := strings.Split(r.FormValue("rows"), "\n") cols := strings.Split(r.FormValue("cols"), "\n") key := newKey() k := datastore.NewKey(c, "grid", key, 0, nil) g := new(Grid) g.Id = key g.Title = title _, err := datastore.Put(c, k, g) if err != nil { c.Errorf("error adding grid: %v", err) } for i, r := range rows { rkey := datastore.NewKey(c, "row", newKey(), 0, nil) row := new(Row) row.Grid = k row.Label = strings.TrimSpace(r) row.DisplayOrder = i _, err := datastore.Put(c, rkey, row) c.Errorf("added row %v", err) } for i, co := range cols { ckey := datastore.NewKey(c, "col", newKey(), 0, nil) col := new(Col) col.Grid = k col.Label = strings.TrimSpace(co) col.DisplayOrder = i _, err := datastore.Put(c, ckey, col) c.Errorf("added col %v", err) } http.Redirect(w, r, "/grid/"+key, http.StatusFound) }
func acceptSuggestion(w http.ResponseWriter, r *http.Request) { if csrf.ValidateToken(r, r.FormValue("CSRFToken")) { trimPath := strings.Trim(r.URL.Path, "/admin/post/suggestion/accept") postID, _ := strconv.Atoi(trimPath) postID64 := int64(postID) c := appengine.NewContext(r) keyS := datastore.NewKey(c, "PostSuggestion", "", postID64, nil) var suggestion PostSuggestion datastore.Get(c, keyS, &suggestion) var post Post keyP := datastore.NewIncompleteKey(c, "Post", nil) var counter Counter keyC := datastore.NewKey(c, "Counter", "", 1, nil) datastore.Get(c, keyC, &counter) counter.Count = counter.Count + 1 // Add Cache Counter mCount := new(bytes.Buffer) encCount := gob.NewEncoder(mCount) encCount.Encode(counter) cache.AddCache(r, "Counter", mCount.Bytes()) post.Content = suggestion.Content post.Sequence = counter.Count datastore.Put(c, keyP, &post) datastore.Put(c, keyC, &counter) datastore.Delete(c, keyS) http.Redirect(w, r, "/admin/post/suggestion", http.StatusFound) } }
// req: POST /items/ {"Title": "Buy bread"} // resp: 201 func NewItem(w http.ResponseWriter, r *http.Request) error { req := struct{ Title string }{} if err := json.NewDecoder(r.Body).Decode(&req); err != nil { return badRequest{err} } if req.Title == "" { return fmt.Errorf("Empty title!") } newItem := newDefaultItem() newItem.Title = req.Title c := appengine.NewContext(r) itemKey, e := datastore.Put(c, datastore.NewIncompleteKey(c, "Item", nil), newItem) if e != nil { return e } newItem.ID = itemKey.IntID() _, e = datastore.Put(c, itemKey, newItem) // log.Println("newItem.ID -> ", newItem.ID) if e != nil { return e } newUrl := r.URL.Path + strconv.FormatInt(newItem.ID, 10) w.Header().Set("Location", newUrl) w.WriteHeader(http.StatusCreated) return nil }
func (self *store) Enqueue(perma_blobref string, blobref string, dependencies []string) (err os.Error) { parent := datastore.NewKey("perma", perma_blobref, 0, nil) key := datastore.NewKey("pending", blobref, 0, parent) p := pendingStruct{int64(len(dependencies))} // Store it _, err = datastore.Put(self.c, key, &p) if err != nil { return } for _, dep := range dependencies { key := datastore.NewKey("missing", dep, 0, parent) var m missingStruct if err = datastore.Get(self.c, key, &m); err != nil { if err != datastore.ErrNoSuchEntity { return } } m.Pending = append(m.Pending, blobref) // Store it _, err = datastore.Put(self.c, key, &m) if err != nil { return err } } return nil }
// ユーザーを追加する func addUser(c appengine.Context, email, password string) error { hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) if err != nil { return err } user := User{ Email: email, PasswordHash: hash, } ik := datastore.NewIncompleteKey(c, UserEntity, nil) key, err := datastore.Put(c, ik, &user) if err != nil { return err } user.Id = key.IntID() // 生成されたIDを格納する _, err = datastore.Put(c, key, &user) // 再度格納 if err != nil { return err } return nil }
func subscribe(context appengine.Context, userdata *UserData, url string, isdefault bool) (err error) { query := datastore.NewQuery("Feed").Filter("URL=", url) iterator := query.Run(context) feedsubscribed := false var feed Feed var key *datastore.Key key, err = iterator.Next(&feed) if err == datastore.Done { feed.URL = url feed.Subscribers = []string{userdata.String} feed.Default = isdefault key, err = datastore.Put(context, datastore.NewIncompleteKey(context, "Feed", nil), &feed) refreshSubscriptionURLDelay.Call(context, feed.URL) feedsubscribed = true } if !ContainsString(userdata.Feeds, url) { userdata.Feeds = append(userdata.Feeds, url) if !feedsubscribed { feed.Subscribers = append(feed.Subscribers, userdata.String) _, err = datastore.Put(context, key, &feed) } } return }
func TestLoadBatchFromDatastore(t *testing.T) { gaeCtx, _ := aetest.NewContext(nil) defer gaeCtx.Close() Convey("Given I have a load batch from datastore transformer", t, func() { riversCtx := rivers.NewContext() loadBatchProcessor := appx.NewStep(riversCtx).LoadBatchFromDatastore(gaeCtx) Convey("And I have a few entities in datastore", func() { user1 := NewUser(User{ Name: "Borges", Email: "*****@*****.**", SSN: "123123123", }) user2 := NewUser(User{ Name: "Borges", Email: "*****@*****.**", SSN: "123123123", }) err := appx.NewKeyResolver(gaeCtx).Resolve(user1) So(err, ShouldBeNil) err = appx.NewKeyResolver(gaeCtx).Resolve(user2) So(err, ShouldBeNil) _, err = datastore.Put(gaeCtx, user1.Key(), user1) So(err, ShouldBeNil) _, err = datastore.Put(gaeCtx, user2.Key(), user2) So(err, ShouldBeNil) Convey("When I transform the incoming batch", func() { userFromDatastore1 := NewUser(User{Name: user1.Name}) userFromDatastore2 := NewUser(User{Name: user2.Name}) appx.NewKeyResolver(gaeCtx).Resolve(userFromDatastore1) appx.NewKeyResolver(gaeCtx).Resolve(userFromDatastore2) batch := &appx.DatastoreBatch{ Size: 2, Keys: []*datastore.Key{ userFromDatastore1.Key(), userFromDatastore2.Key(), }, Items: []appx.Entity{ userFromDatastore1, userFromDatastore2, }, } loadBatchProcessor(batch) Convey("And entities are loaded from datastore", func() { So(userFromDatastore1, ShouldResemble, user1) So(userFromDatastore2, ShouldResemble, user2) }) }) }) }) }
func upload(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) blobs, _, err := blobstore.ParseUpload(r) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } file := blobs["file"] if len(file) == 0 { c.Errorf("No file uploaded") http.Redirect(w, r, "/", http.StatusFound) return } reader := blobstore.NewReader(c, file[0].BlobKey) var pkg *Package switch file[0].ContentType { case "application/x-tar": pkg, err = parsePackageVarsFromTar(bufio.NewReader(reader)) if err == nil { pkg.Type = TAR } case "application/octet-stream": pkg, err = parsePackageVarsFromFile(bufio.NewReader(reader)) if err == nil { pkg.Type = SINGLE } default: http.Error(w, err.Error(), http.StatusBadRequest) } if err != nil { c.Errorf(fmt.Sprintf("Error reading from upload: %v", err)) http.Error(w, err.Error(), http.StatusInternalServerError) return } key := packageKey(c, pkg.Name) _, err = datastore.Put(c, key, pkg) if err != nil { c.Errorf(fmt.Sprintf("Failed to save package %v", pkg.Name)) http.Error(w, err.Error(), http.StatusInternalServerError) return } contents := Contents{ BlobKey: file[0].BlobKey, Version: pkg.LatestVersion, UploadTime: time.Now().UTC(), } _, err = datastore.Put(c, versionKey(c, pkg.LatestVersion, key), &contents) if err != nil { c.Errorf( fmt.Sprintf( "Failed to save contents for version %v, package %v", pkg.LatestVersion, pkg.Name)) http.Error(w, err.Error(), http.StatusInternalServerError) return } http.Redirect(w, r, "/upload_complete.html?package="+ url.QueryEscape(pkg.Name), http.StatusFound) }
func solve(w http.ResponseWriter, r *http.Request) { context := appengine.NewContext(r) j, err := getParamsJeu(r) if err != nil { w.WriteHeader(http.StatusBadRequest) context.Errorf("%s", err) return } if j.CheckJeu() == false { context.Errorf("Données du jeu invalide: Plaques: %d, Total: %d", j.Plaques, j.Total) w.WriteHeader(http.StatusBadRequest) return } //Generation de la Key k := genStringID(j) //Netoyage de pending err = datastore.RunInTransaction(context, func(c appengine.Context) error { var err error key := datastore.NewKey(c, PENDING, k, 0, nil) if err = datastore.Delete(c, key); err != nil { return err } //Ajout dans ongoing key = datastore.NewKey(c, ONGOING, k, 0, nil) if _, err = datastore.Put(c, key, &j); err != nil { return err } //Résolution du compte est bon var sol solution sol.Resultats = j.Resolv() sol.Jeu = j //Netoyage de ongoing key = datastore.NewKey(c, ONGOING, k, 0, nil) if err = datastore.Delete(c, key); err != nil { return err } //Ajout dans finised key = datastore.NewKey(c, FINISHED, k, 0, nil) if _, err = datastore.Put(c, key, &sol); err != nil { return err } return err }, &datastore.TransactionOptions{XG: true}) if err != nil { w.WriteHeader(http.StatusInternalServerError) context.Errorf("%s", err) return } return }
func SetProperty(c appengine.Context, ref ArticleRef, propertyName string, propertyValue bool) ([]string, error) { articleKey, err := ref.key(c) if err != nil { return nil, err } article := new(Article) if err := datastore.Get(c, articleKey, article); err != nil && !IsFieldMismatch(err) { return nil, err } if propertyValue != article.HasProperty(propertyName) { wasUnread := article.IsUnread() wasLiked := article.IsLiked() unreadDelta := 0 article.SetProperty(propertyName, propertyValue) // Update unread counts if necessary if wasUnread != article.IsUnread() { if wasUnread { unreadDelta = -1 } else { unreadDelta = 1 } } if _, err := datastore.Put(c, articleKey, article); err != nil { return nil, err } if wasLiked != article.IsLiked() { if wasLiked { article.updateLikeCount(c, -1) } else { article.updateLikeCount(c, 1) } } if unreadDelta != 0 { // Update unread counts - not critical subscriptionKey := articleKey.Parent() subscription := new(Subscription) if err := datastore.Get(c, subscriptionKey, subscription); err != nil { c.Warningf("Unread count update failed: subscription read error (%s)", err) } else if subscription.UnreadCount+unreadDelta >= 0 { subscription.UnreadCount += unreadDelta if _, err := datastore.Put(c, subscriptionKey, subscription); err != nil { c.Warningf("Unread count update failed: subscription write error (%s)", err) } } } } return article.Properties, nil }
func (b *Banner) Save(ctx appengine.Context) error { var err error k, err := datastore.Put(ctx, b.key(ctx), b) if k != nil { b.ID = k.IntID() datastore.Put(ctx, k, b) } return err }
// TODO(sadovsky): Differentiate between user error and app error. func doSignup(w http.ResponseWriter, r *http.Request, c *Context) (*User, error) { salt := GenerateSecureRandomString() newUser := &User{ Email: ParseEmail(r.FormValue("signup-email")), SaltB: salt, PassHashB: SaltAndHash(salt, r.FormValue("signup-password")), FullName: ParseFullName(r.FormValue("signup-name")), } if r.FormValue("signup-copy-email") == "on" { newUser.PayPalEmail = newUser.Email } else { newUser.PayPalEmail = ParseEmail(r.FormValue("signup-paypal-email")) } // TODO(sadovsky): Check that the PayPal account is valid and confirmed. // Check whether user already exists. If so, report error; if not, create new // account. var userId int64 err := datastore.RunInTransaction(c.Aec(), func(aec appengine.Context) error { userId = 0 // ensure transaction is idempotent userIdKey := ToUserIdKey(c.Aec(), newUser.Email) userIdStruct := &UserId{} err := datastore.Get(aec, userIdKey, userIdStruct) if err != nil && err != datastore.ErrNoSuchEntity { return err } if err == nil { // entity already exists return errors.New(fmt.Sprintf("User already exists: %q", newUser.Email)) } incompleteUserKey := datastore.NewIncompleteKey(c.Aec(), "User", nil) userKey, err := datastore.Put(c.Aec(), incompleteUserKey, newUser) CheckError(err) userId = userKey.IntID() userIdStruct = &UserId{ UserId: userId, } if _, err := datastore.Put(aec, userIdKey, userIdStruct); err != nil { return err } aec.Infof("Signed up user: %q", newUser.Email) return nil }, makeXG()) if err != nil { return nil, err } if err = MakeSession(userId, newUser.Email, newUser.FullName, w, c); err != nil { return nil, err } if err = doInitiateVerifyEmail(c); err != nil { return nil, err } return newUser, nil }
func (c *Content) Save(ctx appengine.Context) error { var err error k, err := datastore.Put(ctx, c.key(ctx), c) if k != nil { c.ID = k.IntID() datastore.Put(ctx, k, c) } return err }
func (a *AboutUs) Save(ctx appengine.Context) error { var err error k, err := datastore.Put(ctx, a.key(ctx), a) if k != nil { a.ID = k.IntID() datastore.Put(ctx, k, a) } return err }
// Increment increments the named counter. func Increment(c appengine.Context, valName string) error { // Get counter config. wNumShards := dsu.WrapInt{} dsu.McacheGet(c, mCKNumShards(valName), &wNumShards) if wNumShards.I < 1 { ckey := datastore.NewKey(c, dsKindNumShards, mCKNumShards(valName), 0, nil) errTx := datastore.RunInTransaction(c, func(c appengine.Context) error { err := datastore.Get(c, ckey, &wNumShards) if err == datastore.ErrNoSuchEntity { wNumShards.I = defaultNumShards _, err = datastore.Put(c, ckey, &wNumShards) } return err }, nil) if errTx != nil { return errTx } dsu.McacheSet(c, mCKNumShards(valName), dsu.WrapInt{wNumShards.I}) } // pick random counter and increment it errTx := datastore.RunInTransaction(c, func(c appengine.Context) error { shardId := rand.Intn(wNumShards.I) dsKey := datastore.NewKey(c, dsKindShard, dSKSingleShard(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) c.Infof("ds put %v %v", dsKey, sd) return err }, nil) if errTx != nil { return errTx } memcache.Increment(c, mCKValue(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 }
// Persist persists the long URL by creating necessary objects. func Persist(originalURL string, c appengine.Context) (id int64, err error) { bytes := []byte(originalURL) hash := fmt.Sprintf("%x|%x|%x", sha512.Sum512(bytes), sha1.Sum(bytes), md5.Sum(bytes)) hashKey := datastore.NewKey(c, "ShortUrlHash", hash, 0, nil) shortURLKey := datastore.NewIncompleteKey(c, "ShortUrl", nil) err = datastore.RunInTransaction(c, func(c appengine.Context) error { var existingHash Hash err1 := datastore.Get(c, hashKey, &existingHash) if err1 != datastore.ErrNoSuchEntity { c.Infof("ShortUrl Hash already exists") return ErrURLAlreadyExist } _, err1 = datastore.Put(c, hashKey, &Hash{ Timestamp: time.Now().Unix(), }) if err1 != nil { c.Errorf("Failed to persist ShortUrlHash for url '%s' with error: %s", originalURL, err.Error()) return err1 } shortURLKey, err1 = datastore.Put(c, shortURLKey, &ShortURL{ Hash: hash, OriginalURL: originalURL, }) if err != nil { c.Errorf("Failed to persist ShortUrl for url '%s' with error: %s", originalURL, err.Error()) } return err1 }, &datastore.TransactionOptions{ XG: true, }) if err == nil { id = shortURLKey.IntID() } else if err == ErrURLAlreadyExist { c.Infof("Trying to load existing ShortUrl for URL: '%s'", originalURL) q := datastore.NewQuery("ShortUrl").Filter("Hash = ", hash).KeysOnly() keys, err1 := q.GetAll(c, nil) if err1 != nil { c.Errorf("Failed to load ShortUrl for URL '%s'. Error: %s", originalURL, err1) err = err1 } if len(keys) > 0 { id = keys[0].IntID() err = nil } else { err = ErrHashCannotBeFound } } return }
func (e *Equipment) Save(ctx appengine.Context) error { var err error k, err := datastore.Put(ctx, e.key(ctx), e) if k != nil { e.ID = k.IntID() datastore.Put(ctx, k, e) } return err }