ozon-task/internal/storage/memory.go

167 lines
4.3 KiB
Go
Raw Normal View History

2024-06-24 23:34:10 +00:00
package storage
import (
"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)
s.insertPost(post)
2024-06-24 23:34:10 +00:00
return &model.AddResult{ItemID: &post.ID}, nil
}
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)
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
}
func (s *InMemory) GetPosts(first uint, after uint, ctx context.Context) (*model.PostsConnection, error) {
if !s.postExists(after) {
return nil, &IDNotFoundError{objName: "post", id: after}
}
nextPage, until := true, after+first
if !s.postExists(until) {
nextPage = false
until = uint(len(s.posts))
}
info, edges := &model.PageInfo{
StartCursor: after,
EndCursor: until - 1,
HasNextPage: nextPage,
}, make([]*model.PostsEdge, until-after)
for i, p := range s.posts[after:until] {
edges[i] = &model.PostsEdge{
Cursor: p.ID,
Node: p,
}
}
return &model.PostsConnection{
Edges: edges,
PageInfo: info,
}, nil
}
func (s *InMemory) GetComments(post *model.Post, first uint, after uint, ctx context.Context) (*model.CommentsConnection, error) {
if !s.commentExists(after) {
return nil, &IDNotFoundError{objName: "comment", id: after}
}
nextPage, until := true, after+first
if !s.commentExists(until) {
nextPage = false
until = uint(len(s.comments))
}
info, edges := &model.PageInfo{
StartCursor: after,
EndCursor: until - 1,
HasNextPage: nextPage,
}, make([]*model.CommentsEdge, until-after)
for i, c := range post.Comments[after:until] {
edges[i] = &model.CommentsEdge{
Cursor: c.ID,
Node: c,
}
}
return &model.CommentsConnection{
Edges: edges,
PageInfo: info,
}, nil
}
func (s *InMemory) GetReplies(comment *model.Comment, first uint, after uint, ctx context.Context) (*model.CommentsConnection, error) {
if !s.commentExists(after) {
return nil, &IDNotFoundError{objName: "comment", id: after}
}
nextPage, until := true, after+first
if !s.commentExists(until) {
nextPage = false
until = uint(len(s.comments))
}
info, edges := &model.PageInfo{
StartCursor: after,
EndCursor: until - 1,
HasNextPage: nextPage,
}, make([]*model.CommentsEdge, until-after)
for i, c := range comment.Replies[after:until] {
edges[i] = &model.CommentsEdge{
Cursor: c.ID,
Node: c,
}
}
return &model.CommentsConnection{
Edges: edges,
PageInfo: info,
}, nil
}
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++
}
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
}