ozon-task/internal/storage/memory.go
erius e0aa12b126 Separated graphql schema into multiple files and moved them to graph/schema dir, update the gqlgen.yml accordingly
Removed unnecesary bindings for ID and Int in gqlgen.yml
Minor changes to Makefile docker-clean target
Reduced docker-compose postgres healthcheck interval for faster local db connections
Added pagination to graphql schema, the paginated queries are WIP
Removed unneeded fields from the model structs
Added allowComment check when adding comments
Switched gorm logger to Info mode
App now panics if the specified APP_STORAGE in env doesn't exist
Reworked database methods, still barely working and are WIP
2024-06-26 04:45:04 +03:00

166 lines
4.3 KiB
Go

package storage
import (
"context"
"fmt"
"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)
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")
}
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) {
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++
}