erius
8fce488888
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
63 lines
1.9 KiB
Go
63 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)
|
|
}
|
|
}
|