Beispiel #1
0
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
}
Beispiel #2
0
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
}
Beispiel #3
0
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
}
Beispiel #4
0
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
}
Beispiel #5
0
func fmtLikes(req *pb.FeedRequest, entry *pb.Entry) {
	entry.FormatLikes(req.MaxLikes)
}
Beispiel #6
0
func fmtComments(req *pb.FeedRequest, entry *pb.Entry) {
	entry.FormatComments(req.MaxComments)
}
Beispiel #7
0
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
}