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) } }