ozon-task/internal/storage/storage.go
erius 8fce488888 Implemented pagination for posts, comments and replies
TODO: use dataloaders to reduce amount of sql queries (figure out how to batch query nested paginated data) and add some basic unit or integrated testing
2024-06-27 04:28:18 +03:00

64 lines
1.9 KiB
Go

package storage
import (
"context"
"fmt"
"log"
"os"
"git.obamna.ru/erius/ozon-task/graph/model"
"git.obamna.ru/erius/ozon-task/internal/storage/db"
)
type IDNotFoundError struct {
objName string
id uint
}
func (e *IDNotFoundError) Error() string {
return fmt.Sprintf("%s with id %d doesn't exist", e.objName, e.id)
}
// storage types enum
const (
inMemory = "inmemory"
postgres = "postgres"
)
var storage, storageSpecified = os.LookupEnv("APP_STORAGE")
type Storage interface {
AddPost(input *model.PostInput) (*model.AddResult, error)
// assumes that input.ParentCommentID is not nil
AddReplyToComment(input *model.CommentInput) (*model.AddResult, error)
// assumes that input.ParentPostID is not nil
AddCommentToPost(input *model.CommentInput) (*model.AddResult, error)
// passing query context to analyze requested fields and prevent overfetching
GetPost(id uint, ctx context.Context) (*model.Post, error)
GetComment(id uint, ctx context.Context) (*model.Comment, error)
// returns paginated data in the form of model.*Connection (passing context to prevent overfetching)
GetPosts(first uint, cursor *uint, ctx context.Context) (*model.PostsConnection, error)
GetComments(post *model.Post, first uint, cursor *uint, ctx context.Context) (*model.CommentsConnection, error)
GetReplies(comment *model.Comment, first uint, cursor *uint, ctx context.Context) (*model.CommentsConnection, error)
}
func InitStorage() (Storage, error) {
if !storageSpecified {
log.Println("APP_STORAGE isn't specified, falling back to default in-memory storage", storage)
return InitInMemory(), nil
}
log.Printf("initializing storage of type %s...", storage)
switch storage {
case inMemory:
return InitInMemory(), nil
case postgres:
return db.InitPostgres()
default:
return nil, fmt.Errorf("storage of type %s doesn't exists, change the value of APP_STORAGE env variable", storage)
}
}