Skip to content

Commit

Permalink
[1126] section 80
Browse files Browse the repository at this point in the history
  • Loading branch information
myeunee committed Nov 26, 2024
1 parent 4f3148b commit fba79e5
Show file tree
Hide file tree
Showing 14 changed files with 321 additions and 7 deletions.
1 change: 1 addition & 0 deletions chapter19/section75/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,6 @@ dry-migrate: ## Try migration
migrate: ## Execute migration
mysqldef -u todo -p todo -h 127.0.0.1 -P 33306 todo < ./_tools/mysql/schema.sql

SHELL := /bin/bash
generate:
go generate ./...
14 changes: 14 additions & 0 deletions chapter19/section75/entity/user.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package entity

import "time"

type UserID int64

type User struct {
ID UserID `json:"id" db:"id"`
Name string `json:"name" db:"name"`
Password string `json:"password" db:"password"`
Role string `json:"role" db:"role"`
Created time.Time `json:"created" db:"created"`
Modified time.Time `json:"modified" db:"modified"`
}
2 changes: 1 addition & 1 deletion chapter19/section75/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ require (
github.com/go-chi/chi/v5 v5.1.0
github.com/go-playground/validator/v10 v10.22.1
github.com/google/go-cmp v0.6.0
github.com/matryer/moq v0.5.0
github.com/matryer/moq v0.5.1
golang.org/x/sync v0.9.0
)

Expand Down
2 changes: 2 additions & 0 deletions chapter19/section75/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/matryer/moq v0.5.0 h1:h2PJUYjZSiyEahzVogDRmrgL9Bsx9xYAl8l+LPfmwL8=
github.com/matryer/moq v0.5.0/go.mod h1:39GTnrD0mVWHPvWdYj5ki/lxfhLQEtHcLh+tWoYF/iE=
github.com/matryer/moq v0.5.1 h1:oX5LkVcQsvf4ltDE71Cj0ScGfgsoxzTNTW6jt2WV744=
github.com/matryer/moq v0.5.1/go.mod h1:39GTnrD0mVWHPvWdYj5ki/lxfhLQEtHcLh+tWoYF/iE=
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
Expand Down
6 changes: 3 additions & 3 deletions chapter19/section75/handler/moq_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

46 changes: 46 additions & 0 deletions chapter19/section75/handler/register_user.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package handler

import (
"encoding/json"
"net/http"

"github.com/go-playground/validator/v10"
"github.com/myeunee/GolangStudy/chapter19/section75/entity"
)

type RegisterUser struct {
Service RegisterUserService
Validator *validator.Validate
}

func (ru *RegisterUser) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
var b struct {
Name string `json:"name" validate:"required"`
Password string `json:"password" validate:"required"`
Role string `json:"role" validate:"required"`
}
if err := json.NewDecoder(r.Body).Decode(&b); err != nil {
RespondJSON(ctx, w, &ErrResponse{
Message: err.Error(),
}, http.StatusInternalServerError)
return
}
if err := ru.Validator.Struct(b); err != nil {
RespondJSON(ctx, w, &ErrResponse{
Message: err.Error(),
}, http.StatusBadRequest)
return
}
u, err := ru.Service.RegisterUser(ctx, b.Name, b.Password, b.Role)
if err != nil {
RespondJSON(ctx, w, &ErrResponse{
Message: err.Error(),
}, http.StatusInternalServerError)
return
}
rsp := struct {
ID entity.UserID `json:"id"`
}{ID: u.ID}
RespondJSON(ctx, w, rsp, http.StatusOK)
}
8 changes: 6 additions & 2 deletions chapter19/section75/handler/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@ import (
"github.com/myeunee/GolangStudy/chapter19/section75/entity"
)

//go:generate go run github.com/matryer/moq -out moq_test.go . ListTasksService AddTaskService
//go:generate go run github.com/matryer/moq -out moq_test.go . ListTasksService AddTaskService RegisterUserService
type ListTasksService interface {
ListTasks(ctx context.Context) (entity.Task, error)
ListTasks(ctx context.Context) (entity.Tasks, error)
}

type AddTaskService interface {
AddTask(ctx context.Context, title string) (*entity.Task, error)
}

type RegisterUserService interface {
RegisterUser(ctx context.Context, name, password, role string) (*entity.User, error)
}
5 changes: 5 additions & 0 deletions chapter19/section75/mux.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,10 @@ func NewMux(ctx context.Context, cfg *config.Config) (http.Handler, func(), erro
Service: &service.ListTask{DB: db, Repo: &r},
}
mux.Get("/tasks", lt.ServeHTTP)
ru := &handler.RegisterUser{
Service: &service.RegisterUser{DB: db, Repo: &r},
Validator: v,
}
mux.Post("/register", ru.ServeHTTP)
return mux, cleanup, nil
}
6 changes: 5 additions & 1 deletion chapter19/section75/service/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@ import (
"github.com/myeunee/GolangStudy/chapter19/section75/store"
)

//go:generate go run github.com/matryer/moq -out moq_test.go . TaskAdder TaskLister
//go:generate go run github.com/matryer/moq -out moq_test.go . TaskAdder TaskLister UserRegister
type TaskAdder interface {
AddTask(ctx context.Context, db store.Execer, t *entity.Task) error
}
type TaskLister interface {
ListTasks(ctx context.Context, db store.Queryer) (entity.Tasks, error)
}

type UserRegister interface {
RegisterUser(ctx context.Context, db store.Execer, user *entity.User) error
}
161 changes: 161 additions & 0 deletions chapter19/section75/service/moq_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 33 additions & 0 deletions chapter19/section75/service/register_user.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package service

import (
"context"
"fmt"

"github.com/myeunee/GolangStudy/chapter19/section75/entity"
"github.com/myeunee/GolangStudy/chapter19/section75/store"
"golang.org/x/crypto/bcrypt"
)

type RegisterUser struct {
DB store.Execer
Repo UserRegister
}

func (r *RegisterUser) RegisterUser(
ctx context.Context, name, password, role string,
) (*entity.User, error) {
pw, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
if err != nil {
return nil, fmt.Errorf("cannot hash password: %w", err)
}
u := &entity.User{
Name: name,
Password: string(pw),
Role: role,
}
if err := r.Repo.RegisterUser(ctx, r.DB, u); err != nil {
return nil, fmt.Errorf("failed to register: %w", err)
}
return u, nil
}
12 changes: 12 additions & 0 deletions chapter19/section75/store/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package store
import (
"context"
"database/sql"
"errors"
"fmt"
"time"

Expand All @@ -12,6 +13,17 @@ import (
"github.com/myeunee/GolangStudy/chapter19/section75/config"
)

const (
// ErrCodeMySQLDuplicateEntry はMySQL系のDUPLICATEエラーコード
// https://dev.mysql.com/doc/mysql-errors/8.0/en/server-error-reference.html
// Error number: 1062; Symbol: ER_DUP_ENTRY; SQLSTATE: 23000
ErrCodeMySQLDuplicateEntry = 1062
)

var (
ErrAlreadyEntry = errors.New("duplicate entry")
)

func New(ctx context.Context, cfg *config.Config) (*sqlx.DB, func(), error) {
// sqlx.Connect를 사용하면 내부에서 ping함
db, err := sql.Open("mysql",
Expand Down
Loading

0 comments on commit fba79e5

Please sign in to comment.