2024-06-24 23:34:10 +00:00
|
|
|
package storage
|
|
|
|
|
|
|
|
import (
|
2024-06-26 01:45:04 +00:00
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
|
2024-06-24 23:34:10 +00:00
|
|
|
"git.obamna.ru/erius/ozon-task/graph/model"
|
|
|
|
)
|
|
|
|
|
|
|
|
type InMemory struct {
|
|
|
|
postId uint
|
|
|
|
commentId uint
|
|
|
|
posts []*model.Post
|
|
|
|
comments []*model.Comment
|
|
|
|
}
|
|
|
|
|
|
|
|
func InitInMemory() *InMemory {
|
|
|
|
return &InMemory{
|
|
|
|
postId: 0,
|
|
|
|
commentId: 0,
|
|
|
|
posts: make([]*model.Post, 0),
|
|
|
|
comments: make([]*model.Comment, 0),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *InMemory) AddPost(input *model.PostInput) (*model.AddResult, error) {
|
|
|
|
post := model.PostFromInput(input)
|
2024-06-26 01:45:04 +00:00
|
|
|
s.insertPost(post)
|
2024-06-24 23:34:10 +00:00
|
|
|
return &model.AddResult{ItemID: &post.ID}, nil
|
|
|
|
}
|
|
|
|
|
2024-06-26 01:45:04 +00:00
|
|
|
func (s *InMemory) AddReplyToComment(input *model.CommentInput) (*model.AddResult, error) {
|
|
|
|
if !s.commentExists(*input.ParentCommentID) {
|
|
|
|
return nil, &IDNotFoundError{objName: "comment", id: *input.ParentCommentID}
|
|
|
|
}
|
|
|
|
comment, parent := model.CommentFromInput(input), s.comments[*input.ParentCommentID]
|
|
|
|
s.insertComment(comment)
|
|
|
|
parent.Replies = append(parent.Replies, comment)
|
|
|
|
return &model.AddResult{ItemID: &comment.ID}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *InMemory) AddCommentToPost(input *model.CommentInput) (*model.AddResult, error) {
|
|
|
|
if !s.postExists(*input.ParentPostID) {
|
|
|
|
return nil, &IDNotFoundError{objName: "post", id: *input.ParentPostID}
|
|
|
|
}
|
|
|
|
parent := s.posts[*input.ParentPostID]
|
|
|
|
if !parent.AllowComments {
|
|
|
|
return nil, fmt.Errorf("author disabled comments for this post")
|
|
|
|
}
|
2024-06-24 23:34:10 +00:00
|
|
|
comment := model.CommentFromInput(input)
|
2024-06-27 01:28:18 +00:00
|
|
|
comment.RootComment = true
|
2024-06-26 01:45:04 +00:00
|
|
|
s.insertComment(comment)
|
|
|
|
parent.Comments = append(parent.Comments, comment)
|
|
|
|
return &model.AddResult{ItemID: &comment.ID}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *InMemory) GetPost(id uint, ctx context.Context) (*model.Post, error) {
|
|
|
|
if !s.postExists(id) {
|
|
|
|
return nil, &IDNotFoundError{objName: "post", id: id}
|
|
|
|
}
|
|
|
|
return s.posts[id], nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *InMemory) GetComment(id uint, ctx context.Context) (*model.Comment, error) {
|
|
|
|
if !s.commentExists(id) {
|
|
|
|
return nil, &IDNotFoundError{objName: "comment", id: id}
|
|
|
|
}
|
|
|
|
return s.comments[id], nil
|
|
|
|
}
|
|
|
|
|
2024-06-27 01:28:18 +00:00
|
|
|
func (s *InMemory) GetPosts(first uint, cursor *uint, ctx context.Context) (*model.PostsConnection, error) {
|
|
|
|
start := uint(0)
|
|
|
|
if cursor != nil {
|
|
|
|
start = *cursor + 1
|
2024-06-26 01:45:04 +00:00
|
|
|
}
|
2024-06-27 01:28:18 +00:00
|
|
|
if !s.postExists(start) {
|
|
|
|
return &model.EmptyPostsConnections, nil
|
|
|
|
}
|
|
|
|
nextPage, until := true, start+first
|
2024-06-26 01:45:04 +00:00
|
|
|
if !s.postExists(until) {
|
|
|
|
nextPage = false
|
|
|
|
until = uint(len(s.posts))
|
|
|
|
}
|
|
|
|
info, edges := &model.PageInfo{
|
2024-06-27 01:28:18 +00:00
|
|
|
StartCursor: start,
|
2024-06-26 01:45:04 +00:00
|
|
|
EndCursor: until - 1,
|
|
|
|
HasNextPage: nextPage,
|
2024-06-27 01:28:18 +00:00
|
|
|
}, make([]*model.PostsEdge, until-start)
|
|
|
|
for i, p := range s.posts[start:until] {
|
2024-06-26 01:45:04 +00:00
|
|
|
edges[i] = &model.PostsEdge{
|
|
|
|
Cursor: p.ID,
|
|
|
|
Node: p,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return &model.PostsConnection{
|
|
|
|
Edges: edges,
|
|
|
|
PageInfo: info,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2024-06-27 01:28:18 +00:00
|
|
|
func (s *InMemory) GetComments(post *model.Post, first uint, cursor *uint, ctx context.Context) (*model.CommentsConnection, error) {
|
|
|
|
return getCommentsFrom(post.Comments, first, cursor), nil
|
2024-06-26 01:45:04 +00:00
|
|
|
}
|
|
|
|
|
2024-06-27 01:28:18 +00:00
|
|
|
func (s *InMemory) GetReplies(comment *model.Comment, first uint, cursor *uint, ctx context.Context) (*model.CommentsConnection, error) {
|
|
|
|
return getCommentsFrom(comment.Replies, first, cursor), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func getCommentsFrom(source []*model.Comment, first uint, cursor *uint) *model.CommentsConnection {
|
|
|
|
start := uint(0)
|
|
|
|
if cursor != nil {
|
|
|
|
start = *cursor + 1
|
|
|
|
}
|
|
|
|
if start >= uint(len(source)) {
|
|
|
|
return &model.EmptyCommentsConnection
|
2024-06-26 01:45:04 +00:00
|
|
|
}
|
2024-06-27 01:28:18 +00:00
|
|
|
nextPage, until := true, start+first
|
|
|
|
if until >= uint(len(source)) {
|
2024-06-26 01:45:04 +00:00
|
|
|
nextPage = false
|
2024-06-27 01:28:18 +00:00
|
|
|
until = uint(len(source))
|
2024-06-26 01:45:04 +00:00
|
|
|
}
|
|
|
|
info, edges := &model.PageInfo{
|
2024-06-27 01:28:18 +00:00
|
|
|
StartCursor: start,
|
2024-06-26 01:45:04 +00:00
|
|
|
EndCursor: until - 1,
|
|
|
|
HasNextPage: nextPage,
|
2024-06-27 01:28:18 +00:00
|
|
|
}, make([]*model.CommentsEdge, until-start)
|
|
|
|
for i, c := range source[start:until] {
|
2024-06-26 01:45:04 +00:00
|
|
|
edges[i] = &model.CommentsEdge{
|
|
|
|
Cursor: c.ID,
|
|
|
|
Node: c,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return &model.CommentsConnection{
|
|
|
|
Edges: edges,
|
|
|
|
PageInfo: info,
|
2024-06-27 01:28:18 +00:00
|
|
|
}
|
2024-06-26 01:45:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (s *InMemory) postExists(id uint) bool {
|
|
|
|
return id < uint(len(s.posts))
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *InMemory) commentExists(id uint) bool {
|
|
|
|
return id < uint(len(s.comments))
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *InMemory) insertComment(comment *model.Comment) {
|
2024-06-24 23:34:10 +00:00
|
|
|
comment.ID = s.commentId
|
|
|
|
s.comments = append(s.comments, comment)
|
|
|
|
s.commentId++
|
|
|
|
}
|
|
|
|
|
2024-06-26 01:45:04 +00:00
|
|
|
func (s *InMemory) insertPost(post *model.Post) {
|
|
|
|
post.ID = s.postId
|
|
|
|
s.posts = append(s.posts, post)
|
|
|
|
s.postId++
|
2024-06-24 23:34:10 +00:00
|
|
|
}
|