diff --git a/cmd/main.go b/cmd/main.go index ea9288f..7c5971b 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -10,7 +10,7 @@ import ( "gitea.michaelthomson.dev/mthomson/habits/internal/middleware" "gitea.michaelthomson.dev/mthomson/habits/internal/migrate" todohandler "gitea.michaelthomson.dev/mthomson/habits/internal/todo/handler" - todorepository "gitea.michaelthomson.dev/mthomson/habits/internal/todo/repository/postgres" + todorepository "gitea.michaelthomson.dev/mthomson/habits/internal/todo/repository" todoservice "gitea.michaelthomson.dev/mthomson/habits/internal/todo/service" "github.com/jackc/pgx/v5/pgxpool" ) @@ -41,7 +41,7 @@ func main() { migrate.Migrate(logger, db) // create repos - todoRepository := todorepository.NewPostgresTodoRepository(logger, db) + todoRepository := todorepository.NewTodoRepository(logger, db) // create services todoService := todoservice.NewTodoService(logger, todoRepository) diff --git a/internal/todo/repository/postgres/postgres.go b/internal/todo/repository/postgres/postgres.go deleted file mode 100644 index bdf03cb..0000000 --- a/internal/todo/repository/postgres/postgres.go +++ /dev/null @@ -1,85 +0,0 @@ -package postgres - -import ( - "context" - "log/slog" - - "gitea.michaelthomson.dev/mthomson/habits/internal/todo/repository" - "github.com/jackc/pgx/v5" - "github.com/jackc/pgx/v5/pgxpool" -) - -type PostgresTodoRepository struct { - logger *slog.Logger - db *pgxpool.Pool -} - -func NewPostgresTodoRepository(logger *slog.Logger, db *pgxpool.Pool) *PostgresTodoRepository { - return &PostgresTodoRepository{ - logger: logger, - db: db, - } -} - -func (r *PostgresTodoRepository) GetById(ctx context.Context, id int64) (repository.TodoRow, error) { - todo := repository.TodoRow{} - - err := r.db.QueryRow(ctx, "SELECT * FROM todo WHERE id = $1;", id).Scan(&todo.Id, &todo.Name, &todo.Done) - - if err != nil { - if err == pgx.ErrNoRows { - return todo, repository.ErrNotFound - } - - r.logger.ErrorContext(ctx, err.Error()) - return todo, err - } - - return todo, nil -} - -func (r *PostgresTodoRepository) Create(ctx context.Context, todo repository.TodoRow) (repository.TodoRow, error) { - result := r.db.QueryRow(ctx, "INSERT INTO todo (name, done) VALUES ($1, $2) RETURNING id;", todo.Name, todo.Done) - err := result.Scan(&todo.Id) - - if err != nil { - r.logger.ErrorContext(ctx, err.Error()) - return repository.TodoRow{}, err - } - - return todo, nil -} - -func (r *PostgresTodoRepository) Update(ctx context.Context, todo repository.TodoRow) error { - result, err := r.db.Exec(ctx, "UPDATE todo SET name = $1, done = $2 WHERE id = $3;", todo.Name, todo.Done, todo.Id) - - if err != nil { - r.logger.ErrorContext(ctx, err.Error()) - return err - } - - rowsAffected := result.RowsAffected() - - if rowsAffected == 0 { - return repository.ErrNotFound - } - - return nil -} - -func (r *PostgresTodoRepository) Delete(ctx context.Context, id int64) error { - result, err := r.db.Exec(ctx, "DELETE FROM todo WHERE id = $1;", id) - - if err != nil { - r.logger.ErrorContext(ctx, err.Error()) - return err - } - - rowsAffected := result.RowsAffected() - - if rowsAffected == 0 { - return repository.ErrNotFound - } - - return nil -} diff --git a/internal/todo/repository/repository.go b/internal/todo/repository/repository.go index ff46533..39fe063 100644 --- a/internal/todo/repository/repository.go +++ b/internal/todo/repository/repository.go @@ -1,7 +1,12 @@ package repository import ( + "context" "errors" + "log/slog" + + "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgxpool" ) var ( @@ -21,3 +26,78 @@ func NewTodoRow(name string, done bool) TodoRow { func (t TodoRow) Equal(todo TodoRow) bool { return t.Id == todo.Id && t.Name == todo.Name && t.Done == todo.Done } + +type TodoRepository struct { + logger *slog.Logger + db *pgxpool.Pool +} + +func NewTodoRepository(logger *slog.Logger, db *pgxpool.Pool) *TodoRepository { + return &TodoRepository{ + logger: logger, + db: db, + } +} + +func (r *TodoRepository) GetById(ctx context.Context, id int64) (TodoRow, error) { + todo := TodoRow{} + + err := r.db.QueryRow(ctx, "SELECT * FROM todo WHERE id = $1;", id).Scan(&todo.Id, &todo.Name, &todo.Done) + + if err != nil { + if err == pgx.ErrNoRows { + return todo, ErrNotFound + } + + r.logger.ErrorContext(ctx, err.Error()) + return todo, err + } + + return todo, nil +} + +func (r *TodoRepository) Create(ctx context.Context, todo TodoRow) (TodoRow, error) { + result := r.db.QueryRow(ctx, "INSERT INTO todo (name, done) VALUES ($1, $2) RETURNING id;", todo.Name, todo.Done) + err := result.Scan(&todo.Id) + + if err != nil { + r.logger.ErrorContext(ctx, err.Error()) + return TodoRow{}, err + } + + return todo, nil +} + +func (r *TodoRepository) Update(ctx context.Context, todo TodoRow) error { + result, err := r.db.Exec(ctx, "UPDATE todo SET name = $1, done = $2 WHERE id = $3;", todo.Name, todo.Done, todo.Id) + + if err != nil { + r.logger.ErrorContext(ctx, err.Error()) + return err + } + + rowsAffected := result.RowsAffected() + + if rowsAffected == 0 { + return ErrNotFound + } + + return nil +} + +func (r *TodoRepository) Delete(ctx context.Context, id int64) error { + result, err := r.db.Exec(ctx, "DELETE FROM todo WHERE id = $1;", id) + + if err != nil { + r.logger.ErrorContext(ctx, err.Error()) + return err + } + + rowsAffected := result.RowsAffected() + + if rowsAffected == 0 { + return ErrNotFound + } + + return nil +} diff --git a/internal/todo/repository/postgres/postgres_test.go b/internal/todo/repository/repository_test.go similarity index 95% rename from internal/todo/repository/postgres/postgres_test.go rename to internal/todo/repository/repository_test.go index 7cb35c2..ca514a6 100644 --- a/internal/todo/repository/postgres/postgres_test.go +++ b/internal/todo/repository/repository_test.go @@ -1,4 +1,4 @@ -package postgres +package repository_test import ( "context" @@ -15,7 +15,7 @@ func TestCRUD(t *testing.T) { logger := slog.Default() tdb := test.NewTestDatabase(t) defer tdb.TearDown() - r := NewPostgresTodoRepository(logger, tdb.Db) + r := repository.NewTodoRepository(logger, tdb.Db) t.Run("creates new todo", func(t *testing.T) { want := repository.TodoRow{Id: 1, Name: "clean dishes", Done: false} diff --git a/internal/todo/service/service_test.go b/internal/todo/service/service_test.go index bf1c84c..5a274d2 100644 --- a/internal/todo/service/service_test.go +++ b/internal/todo/service/service_test.go @@ -7,9 +7,7 @@ import ( "gitea.michaelthomson.dev/mthomson/habits/internal/test" "gitea.michaelthomson.dev/mthomson/habits/internal/todo/repository" - "gitea.michaelthomson.dev/mthomson/habits/internal/todo/repository/postgres" "gitea.michaelthomson.dev/mthomson/habits/internal/todo/service" - _ "github.com/jackc/pgx/v5/stdlib" ) func TestCreateTodo(t *testing.T) { @@ -18,7 +16,7 @@ func TestCreateTodo(t *testing.T) { logger := slog.Default() tdb := test.NewTestDatabase(t) defer tdb.TearDown() - r := postgres.NewPostgresTodoRepository(logger, tdb.Db) + r := repository.NewTodoRepository(logger, tdb.Db) todoService := service.NewTodoService(logger, r) @@ -37,7 +35,7 @@ func TestGetTodo(t *testing.T) { logger := slog.Default() tdb := test.NewTestDatabase(t) defer tdb.TearDown() - r := postgres.NewPostgresTodoRepository(logger, tdb.Db) + r := repository.NewTodoRepository(logger, tdb.Db) row := repository.TodoRow{Id: 1, Name: "clean dishes", Done: false} _, err := r.Create(ctx, row) @@ -64,7 +62,7 @@ func TestDeleteTodo(t *testing.T) { logger := slog.Default() tdb := test.NewTestDatabase(t) defer tdb.TearDown() - r := postgres.NewPostgresTodoRepository(logger, tdb.Db) + r := repository.NewTodoRepository(logger, tdb.Db) row := repository.TodoRow{Id: 1, Name: "clean dishes", Done: false} _, err := r.Create(ctx, row) @@ -91,7 +89,7 @@ func TestUpdateTodo(t *testing.T) { logger := slog.Default() tdb := test.NewTestDatabase(t) defer tdb.TearDown() - r := postgres.NewPostgresTodoRepository(logger, tdb.Db) + r := repository.NewTodoRepository(logger, tdb.Db) row := repository.TodoRow{Id: 1, Name: "clean dishes", Done: false} _, err := r.Create(ctx, row)