erius
e0aa12b126
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
166 lines
4.3 KiB
Go
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++
|
|
}
|