// save updates this Notebook in the datastore func (notebook *Notebook) save(c appengine.Context) error { if Debug { c.Debugf("updating notebook: %#v", *notebook) } _, err := cachestore.Put(c, notebook.Key(c), notebook) if err != nil { c.Errorf("updating notebook: %s", err) } return err }
// addNoteWithoutTags adds a Note to the datastore so that a unique Key is created for it. That Key is // then used for adding/updating Tags. func (notebook Notebook) addNoteWithoutTags(note *Note, c appengine.Context) (*datastore.Key, error) { note.Created = time.Now() note.LastModified = note.Created note.NotebookKeys = []*datastore.Key{notebook.Key(c)} key := notebook.newNoteKey(note, c) if Debug { c.Debugf("adding note (without tags): %#v", note) } key, err := cachestore.Put(c, key, note) if err != nil { c.Errorf("adding note (without tags): %s", err) return nil, err } note.ID = key.Encode() return key, nil }
// updateNote updates a Note in this Notebook, updating existing Tags to either start or stop pointing to it, // cleaning up Tags that no longer point to any Note, and adding any new Tags. func (notebook *Notebook) updateNote(note Note, c appengine.Context) (Note, error) { err := datastore.RunInTransaction(c, func(tc appengine.Context) error { // get old note var oldNote Note key := note.Key(tc) err := cachestore.Get(tc, key, &oldNote) if err != nil { tc.Errorf("getting old note: %s", err) return err } oldNote.ID = note.ID // add/update/delete tags err = notebook.updateTags(key, &oldNote, ¬e, tc) if err != nil { return err } // update note note.Created = oldNote.Created note.LastModified = time.Now() note.NotebookKeys = oldNote.NotebookKeys if Debug { tc.Debugf("updating note: %#v", note) } key, err = cachestore.Put(tc, key, ¬e) if err != nil { tc.Errorf("updating note: %s", err) return err } // update notebook return notebook.save(tc) }, &datastore.TransactionOptions{XG: true}) if err != nil { memcache.Flush(c) } return note, err }
// addNote adds a Note to this Notebook, updating existing Tags to point to it if they're mentioned // and adding any new Tags func (notebook *Notebook) addNote(note Note, c appengine.Context) (Note, error) { err := datastore.RunInTransaction(c, func(tc appengine.Context) error { // add note (without tags) TODO add existing tags key, err := notebook.addNoteWithoutTags(¬e, tc) if err != nil { return err } // add/update tags err = notebook.updateTags(key, new(Note), ¬e, tc) if err != nil { return err } // update note (with tags) TODO skip if no new tags if Debug { tc.Debugf("updating note (with tags): %#v", note) } key, err = cachestore.Put(tc, key, ¬e) if err != nil { tc.Errorf("updating note (with tags): %s", err) return err } // update notebook notebook.NoteKeys = append(notebook.NoteKeys, key) if len(note.TagKeys) > 0 { notebook.addTagKeys(note.TagKeys) } else { notebook.UntaggedNoteKeys = append(notebook.UntaggedNoteKeys, key) } return notebook.save(tc) }, &datastore.TransactionOptions{XG: true}) if err != nil { memcache.Flush(c) } return note, err }
// CurrentNotebook returns the current user's Notebook func CurrentNotebook(c appengine.Context) (*Notebook, error) { notebook := new(Notebook) u := user.Current(c) if u == nil { return notebook, errors.New("user is null") } notebook.ID = u.ID key := notebook.Key(c) err := cachestore.Get(c, key, notebook) if err != nil { if err != datastore.ErrNoSuchEntity { c.Warningf(err.Error()) } // create new user if Debug { c.Debugf("adding new notebook for: %s", u.Email) } notebook.Name = u.Email notebook.Order = NewOrder() key, err = cachestore.Put(c, key, notebook) } return notebook, err }