diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..aa47027 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,10 @@ +version: '3.1' + +services: + db: + image: postgres:14.3-alpine + ports: + - "5432:5432" + environment: + POSTGRES_PASSWORD: deckr + POSTGRES_USER: deckr \ No newline at end of file diff --git a/grpc/deck_service.go b/grpc/deck_service.go index df00118..4bfa473 100644 --- a/grpc/deck_service.go +++ b/grpc/deck_service.go @@ -9,7 +9,7 @@ import ( "github.com/mgjules/deckr/deck" "github.com/mgjules/deckr/logger" "github.com/mgjules/deckr/repo" - "github.com/mgjules/deckr/repo/inmemory" + "github.com/mgjules/deckr/repo/errs" "github.com/satori/uuid" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" @@ -74,8 +74,8 @@ func (s *DeckService) OpenDeck(ctx context.Context, req *OpenDeckRequest) (*Open if err != nil { s.log.Errorf("open deck: %v", err) - if errors.Is(err, inmemory.ErrDeckNotFound) { - return nil, status.Errorf(codes.NotFound, inmemory.ErrDeckNotFound.Error()) + if errors.Is(err, errs.ErrDeckNotFound) { + return nil, status.Errorf(codes.NotFound, errs.ErrDeckNotFound.Error()) } return nil, status.Errorf(codes.Internal, err.Error()) @@ -109,8 +109,8 @@ func (s *DeckService) DrawCards(ctx context.Context, req *DrawCardsRequest) (*Dr if err != nil { s.log.Errorf("get deck: %v", err) - if errors.Is(err, inmemory.ErrDeckNotFound) { - return nil, status.Errorf(codes.NotFound, inmemory.ErrDeckNotFound.Error()) + if errors.Is(err, errs.ErrDeckNotFound) { + return nil, status.Errorf(codes.NotFound, errs.ErrDeckNotFound.Error()) } return nil, status.Errorf(codes.Internal, err.Error()) @@ -153,8 +153,8 @@ func (s *DeckService) ShuffleDeck(ctx context.Context, req *ShuffleDeckRequest) if err != nil { s.log.Errorf("get deck: %v", err) - if errors.Is(err, inmemory.ErrDeckNotFound) { - return nil, status.Errorf(codes.NotFound, inmemory.ErrDeckNotFound.Error()) + if errors.Is(err, errs.ErrDeckNotFound) { + return nil, status.Errorf(codes.NotFound, errs.ErrDeckNotFound.Error()) } return nil, status.Errorf(codes.Internal, err.Error()) diff --git a/http/handler.go b/http/handler.go index dc7e8e5..ece72d3 100644 --- a/http/handler.go +++ b/http/handler.go @@ -10,7 +10,7 @@ import ( "github.com/mgjules/deckr/composition" "github.com/mgjules/deckr/deck" "github.com/mgjules/deckr/docs" - "github.com/mgjules/deckr/repo/inmemory" + "github.com/mgjules/deckr/repo/errs" "github.com/satori/uuid" ginSwagger "github.com/swaggo/gin-swagger" "github.com/swaggo/gin-swagger/swaggerFiles" @@ -122,8 +122,8 @@ func (s *Server) handleOpenDeck() gin.HandlerFunc { if err != nil { s.log.Errorf("open deck: %v", err) - if errors.Is(err, inmemory.ErrDeckNotFound) { - c.AbortWithStatusJSON(http.StatusNotFound, Error{inmemory.ErrDeckNotFound.Error()}) + if errors.Is(err, errs.ErrDeckNotFound) { + c.AbortWithStatusJSON(http.StatusNotFound, Error{errs.ErrDeckNotFound.Error()}) return } @@ -173,8 +173,8 @@ func (s *Server) handleDrawCards() gin.HandlerFunc { if err != nil { s.log.Errorf("get deck: %v", err) - if errors.Is(err, inmemory.ErrDeckNotFound) { - c.AbortWithStatusJSON(http.StatusNotFound, Error{inmemory.ErrDeckNotFound.Error()}) + if errors.Is(err, errs.ErrDeckNotFound) { + c.AbortWithStatusJSON(http.StatusNotFound, Error{errs.ErrDeckNotFound.Error()}) return } @@ -237,8 +237,8 @@ func (s *Server) handleShuffleDeck() gin.HandlerFunc { if err != nil { s.log.Errorf("get deck: %v", err) - if errors.Is(err, inmemory.ErrDeckNotFound) { - c.AbortWithStatusJSON(http.StatusNotFound, Error{inmemory.ErrDeckNotFound.Error()}) + if errors.Is(err, errs.ErrDeckNotFound) { + c.AbortWithStatusJSON(http.StatusNotFound, Error{errs.ErrDeckNotFound.Error()}) return } diff --git a/http/server.go b/http/server.go index 857c536..1756eb9 100644 --- a/http/server.go +++ b/http/server.go @@ -32,14 +32,14 @@ type Server struct { // NewServer creates a new Server. func NewServer( - prod bool, + debug bool, host string, port int, logger *logger.Logger, build *build.Info, repo repo.Repository, ) *Server { - if prod { + if !debug { gin.SetMode(gin.ReleaseMode) } diff --git a/repo/errs/errs.go b/repo/errs/errs.go new file mode 100644 index 0000000..16b6ea3 --- /dev/null +++ b/repo/errs/errs.go @@ -0,0 +1,6 @@ +package errs + +import "errors" + +// ErrDeckNotFound is the error returned when a deck is not found. +var ErrDeckNotFound = errors.New("deck not found") diff --git a/repo/inmemory/inmemory.go b/repo/inmemory/inmemory.go index a734ce2..f27a14f 100644 --- a/repo/inmemory/inmemory.go +++ b/repo/inmemory/inmemory.go @@ -2,17 +2,14 @@ package inmemory import ( "context" - "errors" "fmt" "sync" "github.com/mgjules/deckr/deck" "github.com/mgjules/deckr/logger" + "github.com/mgjules/deckr/repo/errs" ) -// ErrDeckNotFound is the error returned when a deck is not found. -var ErrDeckNotFound = errors.New("deck not found") - // Repository is an in-memory implementation of the deckr.Repository interface. type Repository struct { log *logger.Logger @@ -36,7 +33,7 @@ func (r *Repository) Get(_ context.Context, id string) (*deck.Deck, error) { saved, ok := r.items[id] if !ok { - return nil, fmt.Errorf("deck '%s': %w", id, ErrDeckNotFound) + return nil, fmt.Errorf("deck '%s': %w", id, errs.ErrDeckNotFound) } d, err := DeckToDomainDeck(saved) diff --git a/repo/postgres/postgres.go b/repo/postgres/postgres.go index e4eef8c..358a85c 100644 --- a/repo/postgres/postgres.go +++ b/repo/postgres/postgres.go @@ -7,13 +7,11 @@ import ( "github.com/mgjules/deckr/deck" "github.com/mgjules/deckr/logger" + "github.com/mgjules/deckr/repo/errs" "gorm.io/driver/postgres" "gorm.io/gorm" ) -// ErrDeckNotFound is the error returned when a deck is not found. -var ErrDeckNotFound = errors.New("deck not found") - // Repository is a PostgreSQL implementation of the deckr.Repository interface. type Repository struct { log *logger.Logger @@ -37,10 +35,16 @@ func NewRepository(uri string, log *logger.Logger) (*Repository, error) { // Get returns the deck with the given id. func (r *Repository) Get(_ context.Context, id string) (*deck.Deck, error) { - var saved Deck + saved := Deck{ + ID: id, + } + + if err := r.db.First(&saved).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, fmt.Errorf("deck '%s': %w", id, errs.ErrDeckNotFound) + } - if err := r.db.First(&saved, id); err != nil { - return nil, fmt.Errorf("deck '%s': %w", id, ErrDeckNotFound) + return nil, fmt.Errorf("deck '%s': %w", id, err) } d, err := DeckToDomainDeck(&saved) @@ -57,7 +61,9 @@ func (r *Repository) Get(_ context.Context, id string) (*deck.Deck, error) { func (r *Repository) Save(_ context.Context, d *deck.Deck) error { save := DomainDeckToDeck(d) - r.db.Save(save) + if err := r.db.Save(save).Error; err != nil { + return fmt.Errorf("save deck '%s': %w", save.ID, err) + } r.log.Debugf("saved deck '%s'", save.ID) diff --git a/repo/repo.go b/repo/repo.go index f827747..2e822d5 100644 --- a/repo/repo.go +++ b/repo/repo.go @@ -28,7 +28,7 @@ func NewRepository(uri string, log *logger.Logger) (Repository, error) { switch u.Scheme { case "inmemory": return inmemory.NewRepository(log), nil - case "postgres": + case "postgresql": repo, err := postgres.NewRepository(uri, log) if err != nil { return nil, fmt.Errorf("new postgres repository: %w", err)