func DeleteComment(rdb *Store, profile *pb.Profile, entry *pb.Entry, commentId string) (*pb.Entry, error) { var err error index := -1 for i, cmt := range entry.Comments { if commentId == cmt.Id { index = i break } } if index >= 0 { entry.Comments = append(entry.Comments[:index], entry.Comments[index+1:]...) _, err = PutEntry(rdb, entry, true) } return entry, err }
func DeleteLike(rdb *Store, profile *pb.Profile, entry *pb.Entry) (*pb.Entry, error) { var err error index := -1 for i, like := range entry.Likes { if like.From.Id == profile.Id { index = i break } } if index >= 0 { entry.Likes = append(entry.Likes[:index], entry.Likes[index+1:]...) _, err = PutEntry(rdb, entry, true) } return entry, err }
func Comment(rdb *Store, profile *pb.Profile, entry *pb.Entry, comment *pb.Comment) (*UUIDKey, *pb.Entry, error) { var err error // is update? idx := -1 for i, cmt := range entry.Comments { if cmt.Id == comment.Id { // recheck perm if cmt.From.Id != comment.From.Id { return nil, nil, fmt.Errorf("403: perm error") } idx = i break } } if idx >= 0 { entry.Comments[idx] = comment } else { entry.Comments = append(entry.Comments, comment) } key, err := PutEntry(rdb, entry, true) return key, entry, err }
func Like(rdb *Store, profile *pb.Profile, entry *pb.Entry) (*UUIDKey, *pb.Entry, error) { var err error var key *UUIDKey index := -1 for i, like := range entry.Likes { if like.From.Id == profile.Id { index = i break } } if index == -1 { like := &pb.Like{ Date: time.Now().Format(time.RFC3339), From: &pb.Feed{ Id: profile.Id, Name: profile.Name, Type: profile.Type, }, } entry.Likes = append(entry.Likes, like) key, err = PutEntry(rdb, entry, true) } return key, entry, err }
func fmtLikes(req *pb.FeedRequest, entry *pb.Entry) { entry.FormatLikes(req.MaxLikes) }
func fmtComments(req *pb.FeedRequest, entry *pb.Entry) { entry.FormatComments(req.MaxComments) }
func PutEntry(rdb *Store, entry *pb.Entry, update bool) (*UUIDKey, error) { uuid1, err := uuid.FromString(entry.ProfileUuid) if err != nil { return nil, err } if strings.HasPrefix(entry.Id, "e/") { entry.Id = strings.TrimPrefix(entry.Id, "e/") } // marshal should after uuid trimmed bytes, err := proto.Marshal(entry) if err != nil { return nil, err } uuid2, err := uuid.FromString(entry.Id) if err != nil { return nil, err } // static unique key: // | table | entry uuid | key := NewUUIDKey(TableEntry, uuid2) kb1 := key.Bytes() // is entry exists? value, err := rdb.Get(kb1) if err == nil && value != nil { // already exists // TODO: it is not safe to update(comments/likes) // split comments/likes from entry if update { if err := rdb.Put(kb1, bytes); err != nil { return nil, err } return key, nil } return key, &Error{"ok", ExistItem} } // not exists if err := rdb.Put(kb1, bytes); err != nil { return nil, err } // Entry index list: // K-> | table | user uuid | snowflake | // V-> | +++++ entry key ++++++ | oldtime, err := time.Parse(time.RFC3339, entry.Date) if err != nil { return nil, err } // flakeid := rdb.TimeTravelId(oldtime) // key2 := NewUUIDFlakeKey(TableEntryIndex, uuid1, flakeid) // err = rdb.Put(key2.Bytes(), kb1) // if err != nil { // return nil, err // } // Reverse Entry index: // K-> | table | user uuid | max-minus-ts-flake | // V-> | +++++ entry key ++++++ | flakeid := rdb.TimeTravelReverseId(oldtime) key3 := NewUUIDFlakeKey(TableReverseEntryIndex, uuid1, flakeid) err = rdb.Put(key3.Bytes(), kb1) if err != nil { return nil, err } return key, nil }