From 1bbf94ba03d32d3bc7a2662c31d447b30bcd2313 Mon Sep 17 00:00:00 2001 From: ybkuroki <45133652+ybkuroki@users.noreply.github.com> Date: Sat, 26 Dec 2020 17:34:11 +0900 Subject: [PATCH] Create context --- config/config.go | 25 ++------ controller/account.go | 10 +-- controller/account_test.go | 6 +- controller/book.go | 21 ++++--- controller/book_test.go | 44 ++++++------- controller/error.go | 5 +- controller/health_test.go | 2 +- controller/master.go | 9 +-- controller/mater_test.go | 8 +-- logger/gormlogger.go | 2 +- logger/logger.go | 39 ++++-------- main.go | 23 +++---- middleware/middleware.go | 87 ++++++++++++++------------ migration/db_generator.go | 9 ++- migration/master_generator.go | 9 ++- model/account.go | 4 +- model/authority.go | 2 +- model/book.go | 16 ++--- model/category.go | 6 +- model/format.go | 6 +- mycontext/context.go | 37 +++++++++++ repository/repository.go | 112 +++++++++++++++++++++------------- router/router.go | 23 +++---- service/account.go | 8 +-- service/book.go | 44 ++++++------- service/master.go | 15 +++-- test/unittest_util.go | 28 +++++---- 27 files changed, 318 insertions(+), 282 deletions(-) create mode 100644 mycontext/context.go diff --git a/config/config.go b/config/config.go index 871f8bc9..eeb52a52 100644 --- a/config/config.go +++ b/config/config.go @@ -49,31 +49,14 @@ const ( DOC = "docker" ) -var config *Config -var env *string - // Load reads the settings written to the yml file -func Load() { - env = flag.String("env", "develop", "To switch configurations.") +func Load() (*Config, string) { + env := flag.String("env", "develop", "To switch configurations.") flag.Parse() - config = &Config{} + config := &Config{} if err := configor.Load(config, "application."+*env+".yml"); err != nil { fmt.Printf("Failed to read application.%s.yml: %s", *env, err) os.Exit(2) } -} - -// GetConfig returns the configuration data. -func GetConfig() *Config { - return config -} - -// SetConfig sets configuration data. -func SetConfig(conf *Config) { - config = conf -} - -// GetEnv returns the environment variable. -func GetEnv() *string { - return env + return config, *env } diff --git a/controller/account.go b/controller/account.go index a9c478d1..55656bc0 100644 --- a/controller/account.go +++ b/controller/account.go @@ -4,8 +4,8 @@ import ( "net/http" "github.com/labstack/echo/v4" - "github.com/ybkuroki/go-webapp-sample/config" "github.com/ybkuroki/go-webapp-sample/model" + "github.com/ybkuroki/go-webapp-sample/mycontext" "github.com/ybkuroki/go-webapp-sample/service" "github.com/ybkuroki/go-webapp-sample/session" ) @@ -20,9 +20,9 @@ func GetLoginStatus() echo.HandlerFunc { } // GetLoginAccount returns the account data of logged in user. -func GetLoginAccount() echo.HandlerFunc { +func GetLoginAccount(context mycontext.Context) echo.HandlerFunc { return func(c echo.Context) error { - if !config.GetConfig().Extension.SecurityEnabled { + if !context.GetConfig().Extension.SecurityEnabled { return c.JSON(http.StatusOK, dummyAccount) } return c.JSON(http.StatusOK, session.GetAccount(c)) @@ -30,14 +30,14 @@ func GetLoginAccount() echo.HandlerFunc { } // PostLogin is the method to login using username and password by http post. -func PostLogin() echo.HandlerFunc { +func PostLogin(context mycontext.Context) echo.HandlerFunc { return func(c echo.Context) error { username := c.FormValue("username") password := c.FormValue("password") account := session.GetAccount(c) if account == nil { - authenticate, a := service.AuthenticateByUsernameAndPassword(username, password) + authenticate, a := service.AuthenticateByUsernameAndPassword(context, username, password) if authenticate { _ = session.SetAccount(c, a) _ = session.Save(c) diff --git a/controller/account_test.go b/controller/account_test.go index 46e1d914..68fe9b73 100644 --- a/controller/account_test.go +++ b/controller/account_test.go @@ -11,7 +11,7 @@ import ( ) func TestGetLoginStatus(t *testing.T) { - router := test.Prepare() + router, _ := test.Prepare() router.GET(APIAccountLoginStatus, GetLoginStatus()) req := httptest.NewRequest("GET", APIAccountLoginStatus, nil) @@ -24,8 +24,8 @@ func TestGetLoginStatus(t *testing.T) { } func TestGetLoginAccount(t *testing.T) { - router := test.Prepare() - router.GET(APIAccountLoginAccount, GetLoginAccount()) + router, context := test.Prepare() + router.GET(APIAccountLoginAccount, GetLoginAccount(context)) req := httptest.NewRequest("GET", APIAccountLoginAccount, nil) rec := httptest.NewRecorder() diff --git a/controller/book.go b/controller/book.go index eda0e445..35eba92f 100644 --- a/controller/book.go +++ b/controller/book.go @@ -6,38 +6,39 @@ import ( "github.com/labstack/echo/v4" "github.com/ybkuroki/go-webapp-sample/model/dto" + "github.com/ybkuroki/go-webapp-sample/mycontext" "github.com/ybkuroki/go-webapp-sample/service" ) // GetBookList returns the list of all books. -func GetBookList() echo.HandlerFunc { +func GetBookList(context mycontext.Context) echo.HandlerFunc { return func(c echo.Context) error { page, _ := strconv.Atoi(c.QueryParam("page")) size, _ := strconv.Atoi(c.QueryParam("size")) - return c.JSON(http.StatusOK, service.FindAllBooksByPage(page, size)) + return c.JSON(http.StatusOK, service.FindAllBooksByPage(context, page, size)) } } // GetBookSearch returns the list of matched books by searching. -func GetBookSearch() echo.HandlerFunc { +func GetBookSearch(context mycontext.Context) echo.HandlerFunc { return func(c echo.Context) error { title := c.QueryParam("query") page, _ := strconv.Atoi(c.QueryParam("page")) size, _ := strconv.Atoi(c.QueryParam("size")) - return c.JSON(http.StatusOK, service.FindBooksByTitle(title, page, size)) + return c.JSON(http.StatusOK, service.FindBooksByTitle(context, title, page, size)) } } // PostBookRegist register a new book by http post. -func PostBookRegist() echo.HandlerFunc { +func PostBookRegist(context mycontext.Context) echo.HandlerFunc { return func(c echo.Context) error { dto := dto.NewRegBookDto() if err := c.Bind(dto); err != nil { return c.JSON(http.StatusBadRequest, dto) } - book, result := service.RegisterBook(dto) + book, result := service.RegisterBook(context, dto) if result != nil { return c.JSON(http.StatusBadRequest, result) } @@ -46,13 +47,13 @@ func PostBookRegist() echo.HandlerFunc { } // PostBookEdit edit the existing book by http post. -func PostBookEdit() echo.HandlerFunc { +func PostBookEdit(context mycontext.Context) echo.HandlerFunc { return func(c echo.Context) error { dto := dto.NewChgBookDto() if err := c.Bind(dto); err != nil { return c.JSON(http.StatusBadRequest, dto) } - book, result := service.EditBook(dto) + book, result := service.EditBook(context, dto) if result != nil { return c.JSON(http.StatusBadRequest, result) } @@ -61,13 +62,13 @@ func PostBookEdit() echo.HandlerFunc { } // PostBookDelete deletes the existing book by http post. -func PostBookDelete() echo.HandlerFunc { +func PostBookDelete(context mycontext.Context) echo.HandlerFunc { return func(c echo.Context) error { dto := dto.NewChgBookDto() if err := c.Bind(dto); err != nil { return c.JSON(http.StatusBadRequest, dto) } - book, result := service.DeleteBook(dto) + book, result := service.DeleteBook(context, dto) if result != nil { return c.JSON(http.StatusBadRequest, result) } diff --git a/controller/book_test.go b/controller/book_test.go index 64ce6683..fb0be3bc 100644 --- a/controller/book_test.go +++ b/controller/book_test.go @@ -9,15 +9,15 @@ import ( "github.com/stretchr/testify/assert" "github.com/ybkuroki/go-webapp-sample/model" "github.com/ybkuroki/go-webapp-sample/model/dto" - "github.com/ybkuroki/go-webapp-sample/repository" + "github.com/ybkuroki/go-webapp-sample/mycontext" "github.com/ybkuroki/go-webapp-sample/test" ) func TestGetBookList(t *testing.T) { - router := test.Prepare() - router.GET(APIBookList, GetBookList()) + router, context := test.Prepare() + router.GET(APIBookList, GetBookList(context)) - setUpTestData() + setUpTestData(context) uri := test.NewRequestBuilder().URL(APIBookList).Params("page", "0").Params("size", "5").Build().GetRequestURL() req := httptest.NewRequest("GET", uri, nil) @@ -26,17 +26,17 @@ func TestGetBookList(t *testing.T) { router.ServeHTTP(rec, req) book := &model.Book{} - data, _ := book.FindAllByPage(repository.GetRepository(), 0, 5) + data, _ := book.FindAllByPage(context.GetRepository(), 0, 5) assert.Equal(t, http.StatusOK, rec.Code) assert.JSONEq(t, test.ConvertToString(data), rec.Body.String()) } func TestGetBookSearch(t *testing.T) { - router := test.Prepare() - router.GET(APIBookSearch, GetBookSearch()) + router, context := test.Prepare() + router.GET(APIBookSearch, GetBookSearch(context)) - setUpTestData() + setUpTestData(context) uri := test.NewRequestBuilder().URL(APIBookSearch).Params("query", "Test").Params("page", "0").Params("size", "5").Build().GetRequestURL() req := httptest.NewRequest("GET", uri, nil) @@ -45,15 +45,15 @@ func TestGetBookSearch(t *testing.T) { router.ServeHTTP(rec, req) book := &model.Book{} - data, _ := book.FindByTitle(repository.GetRepository(), "Test", 0, 5) + data, _ := book.FindByTitle(context.GetRepository(), "Test", 0, 5) assert.Equal(t, http.StatusOK, rec.Code) assert.JSONEq(t, test.ConvertToString(data), rec.Body.String()) } func TestPostBookRegist(t *testing.T) { - router := test.Prepare() - router.POST(APIBookRegist, PostBookRegist()) + router, context := test.Prepare() + router.POST(APIBookRegist, PostBookRegist(context)) param := createRegDto() req := httptest.NewRequest("POST", APIBookRegist, strings.NewReader(test.ConvertToString(param))) @@ -64,17 +64,17 @@ func TestPostBookRegist(t *testing.T) { router.ServeHTTP(rec, req) book := &model.Book{} - data, _ := book.FindByID(repository.GetRepository(), 1) + data, _ := book.FindByID(context.GetRepository(), 1) assert.Equal(t, http.StatusOK, rec.Code) assert.JSONEq(t, test.ConvertToString(data), rec.Body.String()) } func TestPostBookEdit(t *testing.T) { - router := test.Prepare() - router.POST(APIBookEdit, PostBookEdit()) + router, context := test.Prepare() + router.POST(APIBookEdit, PostBookEdit(context)) - setUpTestData() + setUpTestData(context) param := createChgDto() req := httptest.NewRequest("POST", APIBookEdit, strings.NewReader(test.ConvertToString(param))) @@ -85,20 +85,20 @@ func TestPostBookEdit(t *testing.T) { router.ServeHTTP(rec, req) book := &model.Book{} - data, _ := book.FindByID(repository.GetRepository(), 1) + data, _ := book.FindByID(context.GetRepository(), 1) assert.Equal(t, http.StatusOK, rec.Code) assert.JSONEq(t, test.ConvertToString(data), rec.Body.String()) } func TestPostBookDelete(t *testing.T) { - router := test.Prepare() - router.POST(APIBookDelete, PostBookDelete()) + router, context := test.Prepare() + router.POST(APIBookDelete, PostBookDelete(context)) - setUpTestData() + setUpTestData(context) book := &model.Book{} - data, _ := book.FindByID(repository.GetRepository(), 1) + data, _ := book.FindByID(context.GetRepository(), 1) param := createChgDto() req := httptest.NewRequest("POST", APIBookDelete, strings.NewReader(test.ConvertToString(param))) @@ -112,9 +112,9 @@ func TestPostBookDelete(t *testing.T) { assert.JSONEq(t, test.ConvertToString(data), rec.Body.String()) } -func setUpTestData() { +func setUpTestData(context mycontext.Context) { model := model.NewBook("Test1", "123-123-123-1", 1, 1) - repo := repository.GetRepository() + repo := context.GetRepository() _, _ = model.Create(repo) } diff --git a/controller/error.go b/controller/error.go index d0ff2f76..b959e5ba 100644 --- a/controller/error.go +++ b/controller/error.go @@ -4,7 +4,6 @@ import ( "net/http" "github.com/labstack/echo/v4" - "github.com/ybkuroki/go-webapp-sample/logger" ) // APIError represents @@ -32,8 +31,8 @@ func JSONErrorHandler(err error, c echo.Context) { if !c.Response().Committed { if reserr := c.JSON(code, apierr); reserr != nil { - logger.GetZapLogger().Errorf(reserr.Error()) + //logger.GetZapLogger().Errorf(reserr.Error()) } } - logger.GetZapLogger().Debugf(err.Error()) + //logger.GetZapLogger().Debugf(err.Error()) } diff --git a/controller/health_test.go b/controller/health_test.go index a21a35e8..14b3748b 100644 --- a/controller/health_test.go +++ b/controller/health_test.go @@ -10,7 +10,7 @@ import ( ) func TestGetHealthCheck(t *testing.T) { - router := test.Prepare() + router, _ := test.Prepare() router.GET(APIHealth, GetHealthCheck()) req := httptest.NewRequest("GET", APIHealth, nil) diff --git a/controller/master.go b/controller/master.go index 4f6f7cb5..a00b2339 100644 --- a/controller/master.go +++ b/controller/master.go @@ -4,19 +4,20 @@ import ( "net/http" "github.com/labstack/echo/v4" + "github.com/ybkuroki/go-webapp-sample/mycontext" "github.com/ybkuroki/go-webapp-sample/service" ) // GetCategoryList returns the list of all categories. -func GetCategoryList() echo.HandlerFunc { +func GetCategoryList(context mycontext.Context) echo.HandlerFunc { return func(c echo.Context) error { - return c.JSON(http.StatusOK, service.FindAllCategories()) + return c.JSON(http.StatusOK, service.FindAllCategories(context)) } } // GetFormatList returns the list of all formats. -func GetFormatList() echo.HandlerFunc { +func GetFormatList(context mycontext.Context) echo.HandlerFunc { return func(c echo.Context) error { - return c.JSON(http.StatusOK, service.FindAllFormats()) + return c.JSON(http.StatusOK, service.FindAllFormats(context)) } } diff --git a/controller/mater_test.go b/controller/mater_test.go index 9757b7f0..23c0a07b 100644 --- a/controller/mater_test.go +++ b/controller/mater_test.go @@ -11,8 +11,8 @@ import ( ) func TestGetCategoryList(t *testing.T) { - router := test.Prepare() - router.GET(APIMasterCategory, GetCategoryList()) + router, context := test.Prepare() + router.GET(APIMasterCategory, GetCategoryList(context)) req := httptest.NewRequest("GET", APIMasterCategory, nil) rec := httptest.NewRecorder() @@ -30,8 +30,8 @@ func TestGetCategoryList(t *testing.T) { } func TestGetFormatList(t *testing.T) { - router := test.Prepare() - router.GET(APIMasterFormat, GetFormatList()) + router, context := test.Prepare() + router.GET(APIMasterFormat, GetFormatList(context)) req := httptest.NewRequest("GET", APIMasterFormat, nil) rec := httptest.NewRecorder() diff --git a/logger/gormlogger.go b/logger/gormlogger.go index 494a5044..1fd548b8 100644 --- a/logger/gormlogger.go +++ b/logger/gormlogger.go @@ -24,7 +24,7 @@ func (l *Logger) Print(values ...interface{}) { func (l *Logger) Println(values []interface{}) { sql := createLog(values) if sql != "" { - l.zap.Debugf(sql) + l.Zap.Debugf(sql) } } diff --git a/logger/logger.go b/logger/logger.go index 7d61bcac..d024ecc3 100644 --- a/logger/logger.go +++ b/logger/logger.go @@ -5,14 +5,11 @@ import ( "io/ioutil" "os" - "github.com/ybkuroki/go-webapp-sample/config" "go.uber.org/zap" "gopkg.in/natefinch/lumberjack.v2" "gopkg.in/yaml.v2" ) -var logger *Logger - // Config is type Config struct { ZapConfig zap.Config `json:"zap_config" yaml:"zap_config"` @@ -21,32 +18,12 @@ type Config struct { // Logger is an alternative implementation of *gorm.Logger type Logger struct { - zap *zap.SugaredLogger -} - -// GetLogger is return Logger -func GetLogger() *Logger { - return logger -} - -// SetLogger sets logger -func SetLogger(log *Logger) { - logger = log -} - -// GetZapLogger returns zapSugaredLogger -func GetZapLogger() *zap.SugaredLogger { - return logger.zap + Zap *zap.SugaredLogger } // NewLogger create logger object for *gorm.DB from *echo.Logger -func NewLogger(zap *zap.SugaredLogger) *Logger { - return &Logger{zap: zap} -} - -// InitLogger initialize logger. -func InitLogger() { - configYaml, err := ioutil.ReadFile("./zaplogger." + *config.GetEnv() + ".yml") +func NewLogger(env string) *Logger { + configYaml, err := ioutil.ReadFile("./zaplogger." + env + ".yml") if err != nil { fmt.Printf("Failed to read logger configuration: %s", err) os.Exit(2) @@ -64,7 +41,13 @@ func InitLogger() { } sugar := zap.Sugar() // set package varriable logger. - logger = NewLogger(sugar) - logger.zap.Infof("Success to read zap logger configuration: zaplogger." + *config.GetEnv() + ".yml") + logger := &Logger{Zap: sugar} + logger.Zap.Infof("Success to read zap logger configuration: zaplogger." + env + ".yml") _ = zap.Sync() + return logger +} + +// GetZapLogger is +func (log *Logger) GetZapLogger() *zap.SugaredLogger { + return log.Zap } diff --git a/main.go b/main.go index 83c8dfa0..47d9c9fb 100644 --- a/main.go +++ b/main.go @@ -6,6 +6,7 @@ import ( "github.com/ybkuroki/go-webapp-sample/logger" "github.com/ybkuroki/go-webapp-sample/middleware" "github.com/ybkuroki/go-webapp-sample/migration" + "github.com/ybkuroki/go-webapp-sample/mycontext" "github.com/ybkuroki/go-webapp-sample/repository" "github.com/ybkuroki/go-webapp-sample/router" ) @@ -13,22 +14,22 @@ import ( func main() { e := echo.New() - config.Load() - logger.InitLogger() - middleware.InitLoggerMiddleware(e) - logger.GetZapLogger().Infof("Loaded this configuration : application." + *config.GetEnv() + ".yml") + conf, env := config.Load() + logger := logger.NewLogger(env) + logger.GetZapLogger().Infof("Loaded this configuration : application." + env + ".yml") - repository.InitDB() - db := repository.GetDB() + rep := repository.NewBookRepository(logger, conf) + context := mycontext.NewContext(rep, conf, logger) - migration.CreateDatabase(config.GetConfig()) - migration.InitMasterData(config.GetConfig()) + migration.CreateDatabase(context) + migration.InitMasterData(context) - router.Init(e, config.GetConfig()) - middleware.InitSessionMiddleware(e, config.GetConfig()) + router.Init(e, context) + middleware.InitLoggerMiddleware(e, context) + middleware.InitSessionMiddleware(e, context) if err := e.Start(":8080"); err != nil { logger.GetZapLogger().Errorf(err.Error()) } - defer db.Close() + defer rep.Close() } diff --git a/middleware/middleware.go b/middleware/middleware.go index 712b33ef..1d73cd71 100644 --- a/middleware/middleware.go +++ b/middleware/middleware.go @@ -12,19 +12,21 @@ import ( "github.com/labstack/echo/v4" "github.com/valyala/fasttemplate" "github.com/ybkuroki/go-webapp-sample/config" - "github.com/ybkuroki/go-webapp-sample/logger" + "github.com/ybkuroki/go-webapp-sample/mycontext" mySession "github.com/ybkuroki/go-webapp-sample/session" "gopkg.in/boj/redistore.v1" ) // InitLoggerMiddleware initialize a middleware for logger. -func InitLoggerMiddleware(e *echo.Echo) { - e.Use(RequestLoggerMiddleware) - e.Use(ActionLoggerMiddleware) +func InitLoggerMiddleware(e *echo.Echo, context mycontext.Context) { + e.Use(RequestLoggerMiddleware(context)) + e.Use(ActionLoggerMiddleware(context)) } // InitSessionMiddleware initialize a middleware for session management. -func InitSessionMiddleware(e *echo.Echo, conf *config.Config) { +func InitSessionMiddleware(e *echo.Echo, context mycontext.Context) { + conf := context.GetConfig() + logger := context.GetLogger() if conf.Extension.SecurityEnabled { if conf.Redis.Enabled { logger.GetZapLogger().Infof("Try redis connection") @@ -43,49 +45,54 @@ func InitSessionMiddleware(e *echo.Echo, conf *config.Config) { } // RequestLoggerMiddleware is middleware for logging the contents of requests. -func RequestLoggerMiddleware(next echo.HandlerFunc) echo.HandlerFunc { - return func(c echo.Context) error { - req := c.Request() - res := c.Response() - if err := next(c); err != nil { - c.Error(err) - } +func RequestLoggerMiddleware(context mycontext.Context) echo.MiddlewareFunc { + return func(next echo.HandlerFunc) echo.HandlerFunc { + return func(c echo.Context) error { + req := c.Request() + res := c.Response() + if err := next(c); err != nil { + c.Error(err) + } - template := fasttemplate.New(config.GetConfig().Log.RequestLogFormat, "${", "}") - logstr := template.ExecuteFuncString(func(w io.Writer, tag string) (int, error) { - switch tag { - case "remote_ip": - return w.Write([]byte(c.RealIP())) - case "account_name": - if account := mySession.GetAccount(c); account != nil { - return w.Write([]byte(account.Name)) + template := fasttemplate.New(context.GetConfig().Log.RequestLogFormat, "${", "}") + logstr := template.ExecuteFuncString(func(w io.Writer, tag string) (int, error) { + switch tag { + case "remote_ip": + return w.Write([]byte(c.RealIP())) + case "account_name": + if account := mySession.GetAccount(c); account != nil { + return w.Write([]byte(account.Name)) + } + return w.Write([]byte("None")) + case "uri": + return w.Write([]byte(req.RequestURI)) + case "method": + return w.Write([]byte(req.Method)) + case "status": + return w.Write([]byte(strconv.Itoa(res.Status))) + default: + return w.Write([]byte("")) } - return w.Write([]byte("None")) - case "uri": - return w.Write([]byte(req.RequestURI)) - case "method": - return w.Write([]byte(req.Method)) - case "status": - return w.Write([]byte(strconv.Itoa(res.Status))) - default: - return w.Write([]byte("")) - } - }) - logger.GetZapLogger().Infof(logstr) - return nil + }) + context.GetLogger().GetZapLogger().Infof(logstr) + return nil + } } } // ActionLoggerMiddleware is middleware for logging the start and end of controller processes. // ref: https://echo.labstack.com/cookbook/middleware -func ActionLoggerMiddleware(next echo.HandlerFunc) echo.HandlerFunc { - return func(c echo.Context) error { - logger.GetZapLogger().Debugf(c.Path() + " Action Start") - if err := next(c); err != nil { - c.Error(err) +func ActionLoggerMiddleware(context mycontext.Context) echo.MiddlewareFunc { + return func(next echo.HandlerFunc) echo.HandlerFunc { + return func(c echo.Context) error { + logger := context.GetLogger() + logger.GetZapLogger().Debugf(c.Path() + " Action Start") + if err := next(c); err != nil { + c.Error(err) + } + logger.GetZapLogger().Debugf(c.Path() + " Action End") + return nil } - logger.GetZapLogger().Debugf(c.Path() + " Action End") - return nil } } diff --git a/migration/db_generator.go b/migration/db_generator.go index e2d53015..932fef45 100644 --- a/migration/db_generator.go +++ b/migration/db_generator.go @@ -1,15 +1,14 @@ package migration import ( - "github.com/ybkuroki/go-webapp-sample/config" "github.com/ybkuroki/go-webapp-sample/model" - "github.com/ybkuroki/go-webapp-sample/repository" + "github.com/ybkuroki/go-webapp-sample/mycontext" ) // CreateDatabase creates the tables used in this application. -func CreateDatabase(config *config.Config) { - if config.Database.Migration { - db := repository.GetDB() +func CreateDatabase(context mycontext.Context) { + if context.GetConfig().Database.Migration { + db := context.GetRepository() db.DropTableIfExists(&model.Book{}) db.DropTableIfExists(&model.Category{}) diff --git a/migration/master_generator.go b/migration/master_generator.go index cb0edf5b..e5c48490 100644 --- a/migration/master_generator.go +++ b/migration/master_generator.go @@ -1,15 +1,14 @@ package migration import ( - "github.com/ybkuroki/go-webapp-sample/config" "github.com/ybkuroki/go-webapp-sample/model" - "github.com/ybkuroki/go-webapp-sample/repository" + "github.com/ybkuroki/go-webapp-sample/mycontext" ) // InitMasterData creates the master data used in this application. -func InitMasterData(config *config.Config) { - if config.Extension.MasterGenerator { - rep := repository.GetRepository() +func InitMasterData(context mycontext.Context) { + if context.GetConfig().Extension.MasterGenerator { + rep := context.GetRepository() r := model.NewAuthority("Admin") _, _ = r.Create(rep) diff --git a/model/account.go b/model/account.go index 1fccbdd9..e9b35372 100644 --- a/model/account.go +++ b/model/account.go @@ -45,7 +45,7 @@ func NewAccountWithPlainPassword(name string, password string, authorityID uint) } // FindByName returns accounts full matched given account name. -func (a *Account) FindByName(rep *repository.Repository, name string) (*Account, error) { +func (a *Account) FindByName(rep repository.Repository, name string) (*Account, error) { var account *Account var rec RecordAccount @@ -56,7 +56,7 @@ func (a *Account) FindByName(rep *repository.Repository, name string) (*Account, } // Create persists this account data. -func (a *Account) Create(rep *repository.Repository) (*Account, error) { +func (a *Account) Create(rep repository.Repository) (*Account, error) { if error := rep.Select("name", "password", "authority_id").Create(a).Error; error != nil { return nil, error } diff --git a/model/authority.go b/model/authority.go index 99e91b52..09e228d5 100644 --- a/model/authority.go +++ b/model/authority.go @@ -23,7 +23,7 @@ func NewAuthority(name string) *Authority { } // Create persists this authority data. -func (a *Authority) Create(rep *repository.Repository) (*Authority, error) { +func (a *Authority) Create(rep repository.Repository) (*Authority, error) { if error := rep.Create(a).Error; error != nil { return nil, error } diff --git a/model/book.go b/model/book.go index 03e42aff..3c61c9e4 100644 --- a/model/book.go +++ b/model/book.go @@ -44,7 +44,7 @@ func NewBook(title string, isbn string, categoryID uint, formatID uint) *Book { } // FindByID returns a book full matched given book's ID. -func (b *Book) FindByID(rep *repository.Repository, id uint) (*Book, error) { +func (b *Book) FindByID(rep repository.Repository, id uint) (*Book, error) { var book *Book var rec RecordBook @@ -55,7 +55,7 @@ func (b *Book) FindByID(rep *repository.Repository, id uint) (*Book, error) { } // FindAll returns all books of the book table. -func (b *Book) FindAll(rep *repository.Repository) (*[]Book, error) { +func (b *Book) FindAll(rep repository.Repository) (*[]Book, error) { var books []Book var rec RecordBook @@ -76,7 +76,7 @@ func (b *Book) FindAll(rep *repository.Repository) (*[]Book, error) { } // FindAllByPage returns the page object of all books. -func (b *Book) FindAllByPage(rep *repository.Repository, page int, size int) (*Page, error) { +func (b *Book) FindAllByPage(rep repository.Repository, page int, size int) (*Page, error) { var books []Book var rec RecordBook @@ -98,7 +98,7 @@ func (b *Book) FindAllByPage(rep *repository.Repository, page int, size int) (*P } // FindByTitle returns the page object of books partially matched given book title. -func (b *Book) FindByTitle(rep *repository.Repository, title string, page int, size int) (*Page, error) { +func (b *Book) FindByTitle(rep repository.Repository, title string, page int, size int) (*Page, error) { var books []Book var rec RecordBook @@ -132,7 +132,7 @@ func createPage(books *[]Book, page int, size int) *Page { } // Save persists this book data. -func (b *Book) Save(rep *repository.Repository) (*Book, error) { +func (b *Book) Save(rep repository.Repository) (*Book, error) { if error := rep.Save(b).Error; error != nil { return nil, error } @@ -140,7 +140,7 @@ func (b *Book) Save(rep *repository.Repository) (*Book, error) { } // Update updates this book data. -func (b *Book) Update(rep *repository.Repository) (*Book, error) { +func (b *Book) Update(rep repository.Repository) (*Book, error) { if error := rep.Model(Book{}).Where("id = ?", b.ID).Select("title", "isbn", "category_id", "format_id").Updates(b).Error; error != nil { return nil, error } @@ -148,7 +148,7 @@ func (b *Book) Update(rep *repository.Repository) (*Book, error) { } // Create persists this book data. -func (b *Book) Create(rep *repository.Repository) (*Book, error) { +func (b *Book) Create(rep repository.Repository) (*Book, error) { if error := rep.Select("title", "isbn", "category_id", "format_id").Create(b).Error; error != nil { return nil, error } @@ -156,7 +156,7 @@ func (b *Book) Create(rep *repository.Repository) (*Book, error) { } // Delete deletes this book data. -func (b *Book) Delete(rep *repository.Repository) (*Book, error) { +func (b *Book) Delete(rep repository.Repository) (*Book, error) { if error := rep.Delete(b).Error; error != nil { return nil, error } diff --git a/model/category.go b/model/category.go index 9ee2139c..ff8229ee 100644 --- a/model/category.go +++ b/model/category.go @@ -23,7 +23,7 @@ func NewCategory(name string) *Category { } // FindByID returns a category full matched given category's ID. -func (c *Category) FindByID(rep *repository.Repository, id uint) (*Category, error) { +func (c *Category) FindByID(rep repository.Repository, id uint) (*Category, error) { var category Category if error := rep.Where("id = ?", id).Find(&category).Error; error != nil { return nil, error @@ -32,7 +32,7 @@ func (c *Category) FindByID(rep *repository.Repository, id uint) (*Category, err } // FindAll returns all categories of the category table. -func (c *Category) FindAll(rep *repository.Repository) (*[]Category, error) { +func (c *Category) FindAll(rep repository.Repository) (*[]Category, error) { var categories []Category if error := rep.Find(&categories).Error; error != nil { return nil, error @@ -41,7 +41,7 @@ func (c *Category) FindAll(rep *repository.Repository) (*[]Category, error) { } // Create persists this category data. -func (c *Category) Create(rep *repository.Repository) (*Category, error) { +func (c *Category) Create(rep repository.Repository) (*Category, error) { if error := rep.Create(c).Error; error != nil { return nil, error } diff --git a/model/format.go b/model/format.go index ec5d704a..58404b66 100644 --- a/model/format.go +++ b/model/format.go @@ -23,7 +23,7 @@ func NewFormat(name string) *Format { } // FindByID returns a format full matched given format's ID. -func (f *Format) FindByID(rep *repository.Repository, id uint) (*Format, error) { +func (f *Format) FindByID(rep repository.Repository, id uint) (*Format, error) { var format Format if error := rep.Where("id = ?", id).Find(&format).Error; error != nil { return nil, error @@ -32,7 +32,7 @@ func (f *Format) FindByID(rep *repository.Repository, id uint) (*Format, error) } // FindAll returns all formats of the format table. -func (f *Format) FindAll(rep *repository.Repository) (*[]Format, error) { +func (f *Format) FindAll(rep repository.Repository) (*[]Format, error) { var formats []Format if error := rep.Find(&formats).Error; error != nil { return nil, error @@ -41,7 +41,7 @@ func (f *Format) FindAll(rep *repository.Repository) (*[]Format, error) { } // Create persists this category data. -func (f *Format) Create(rep *repository.Repository) (*Format, error) { +func (f *Format) Create(rep repository.Repository) (*Format, error) { if error := rep.Create(f).Error; error != nil { return nil, error } diff --git a/mycontext/context.go b/mycontext/context.go new file mode 100644 index 00000000..199e80a8 --- /dev/null +++ b/mycontext/context.go @@ -0,0 +1,37 @@ +package mycontext + +import ( + "github.com/ybkuroki/go-webapp-sample/config" + "github.com/ybkuroki/go-webapp-sample/logger" + "github.com/ybkuroki/go-webapp-sample/repository" +) + +// Context is +type Context interface { + GetRepository() repository.Repository + GetConfig() *config.Config + GetLogger() *logger.Logger +} + +type context struct { + rep repository.Repository + config *config.Config + logger *logger.Logger +} + +// NewContext is +func NewContext(rep repository.Repository, config *config.Config, logger *logger.Logger) Context { + return &context{rep: rep, config: config, logger: logger} +} + +func (c *context) GetRepository() repository.Repository { + return c.rep +} + +func (c *context) GetConfig() *config.Config { + return c.config +} + +func (c *context) GetLogger() *logger.Logger { + return c.logger +} diff --git a/repository/repository.go b/repository/repository.go index 5e049e0c..cd07971c 100644 --- a/repository/repository.go +++ b/repository/repository.go @@ -13,11 +13,49 @@ import ( ) // Repository defines a repository for access the database. -type Repository struct { +type Repository interface { + Model(value interface{}) *gorm.DB + Select(query interface{}, args ...interface{}) *gorm.DB + Find(out interface{}, where ...interface{}) *gorm.DB + Exec(sql string, values ...interface{}) *gorm.DB + First(out interface{}, where ...interface{}) *gorm.DB + Raw(sql string, values ...interface{}) *gorm.DB + Create(value interface{}) *gorm.DB + Save(value interface{}) *gorm.DB + Update(value interface{}) *gorm.DB + Delete(value interface{}) *gorm.DB + Where(query interface{}, args ...interface{}) *gorm.DB + Preload(column string, conditions ...interface{}) *gorm.DB + Scopes(funcs ...func(*gorm.DB) *gorm.DB) *gorm.DB + ScanRows(rows *sql.Rows, result interface{}) error + Transaction(fc func(tx Repository) error) (err error) + Close() error + DropTableIfExists(value interface{}) *gorm.DB + AutoMigrate(value interface{}) *gorm.DB +} + +// repository defines a repository for access the database. +type repository struct { db *gorm.DB } -var rep *Repository +type bookRepository struct { + *repository +} + +// NewBookRepository is +func NewBookRepository(logger *logger.Logger, conf *config.Config) Repository { + logger.GetZapLogger().Infof("Try database connection") + db, err := gorm.Open(conf.Database.Dialect, getConnection(conf)) + if err != nil { + logger.GetZapLogger().Errorf("Failure database connection") + os.Exit(2) + } + logger.GetZapLogger().Infof("Success database connection, %s:%s", conf.Database.Host, conf.Database.Port) + db.LogMode(true) + db.SetLogger(logger) + return &bookRepository{&repository{db: db}} +} const ( // SQLITE represents SQLite3 @@ -37,107 +75,93 @@ func getConnection(config *config.Config) string { return config.Database.Host } -// InitDB initialize a database connection. -func InitDB() { - logger.GetZapLogger().Infof("Try database connection") - conf := config.GetConfig() - db, err := gorm.Open(conf.Database.Dialect, getConnection(conf)) - if err != nil { - logger.GetZapLogger().Errorf("Failure database connection") - os.Exit(2) - } - logger.GetZapLogger().Infof("Success database connection, %s:%s", conf.Database.Host, conf.Database.Port) - db.LogMode(true) - db.SetLogger(logger.GetLogger()) - rep = &Repository{} - rep.db = db -} - -// GetRepository returns the object of repository. -func GetRepository() *Repository { - return rep -} - -// GetDB returns the object of gorm.DB. -func GetDB() *gorm.DB { - return rep.db -} - // Model specify the model you would like to run db operations -func (rep *Repository) Model(value interface{}) *gorm.DB { +func (rep *repository) Model(value interface{}) *gorm.DB { return rep.db.Model(value) } // Select specify fields that you want to retrieve from database when querying, by default, will select all fields; -func (rep *Repository) Select(query interface{}, args ...interface{}) *gorm.DB { +func (rep *repository) Select(query interface{}, args ...interface{}) *gorm.DB { return rep.db.Select(query, args...) } // Find find records that match given conditions. -func (rep *Repository) Find(out interface{}, where ...interface{}) *gorm.DB { +func (rep *repository) Find(out interface{}, where ...interface{}) *gorm.DB { return rep.db.Find(out, where...) } // Exec exec given SQL using by gorm.DB. -func (rep *Repository) Exec(sql string, values ...interface{}) *gorm.DB { +func (rep *repository) Exec(sql string, values ...interface{}) *gorm.DB { return rep.db.Exec(sql, values...) } // First returns first record that match given conditions, order by primary key. -func (rep *Repository) First(out interface{}, where ...interface{}) *gorm.DB { +func (rep *repository) First(out interface{}, where ...interface{}) *gorm.DB { return rep.db.First(out, where...) } // Raw returns the record that executed the given SQL using gorm.DB. -func (rep *Repository) Raw(sql string, values ...interface{}) *gorm.DB { +func (rep *repository) Raw(sql string, values ...interface{}) *gorm.DB { return rep.db.Raw(sql, values...) } // Create insert the value into database. -func (rep *Repository) Create(value interface{}) *gorm.DB { +func (rep *repository) Create(value interface{}) *gorm.DB { return rep.db.Create(value) } // Save update value in database, if the value doesn't have primary key, will insert it. -func (rep *Repository) Save(value interface{}) *gorm.DB { +func (rep *repository) Save(value interface{}) *gorm.DB { return rep.db.Save(value) } // Update update value in database -func (rep *Repository) Update(value interface{}) *gorm.DB { +func (rep *repository) Update(value interface{}) *gorm.DB { return rep.db.Update(value) } // Delete delete value match given conditions. -func (rep *Repository) Delete(value interface{}) *gorm.DB { +func (rep *repository) Delete(value interface{}) *gorm.DB { return rep.db.Delete(value) } // Where returns a new relation. -func (rep *Repository) Where(query interface{}, args ...interface{}) *gorm.DB { +func (rep *repository) Where(query interface{}, args ...interface{}) *gorm.DB { return rep.db.Where(query, args...) } // Preload preload associations with given conditions. -func (rep *Repository) Preload(column string, conditions ...interface{}) *gorm.DB { +func (rep *repository) Preload(column string, conditions ...interface{}) *gorm.DB { return rep.db.Preload(column, conditions...) } // Scopes pass current database connection to arguments `func(*DB) *DB`, which could be used to add conditions dynamically -func (rep *Repository) Scopes(funcs ...func(*gorm.DB) *gorm.DB) *gorm.DB { +func (rep *repository) Scopes(funcs ...func(*gorm.DB) *gorm.DB) *gorm.DB { return rep.db.Scopes(funcs...) } // ScanRows scan `*sql.Rows` to give struct -func (rep *Repository) ScanRows(rows *sql.Rows, result interface{}) error { +func (rep *repository) ScanRows(rows *sql.Rows, result interface{}) error { return rep.db.ScanRows(rows, result) } +func (rep *repository) Close() error { + return rep.db.Close() +} + +func (rep *repository) DropTableIfExists(value interface{}) *gorm.DB { + return rep.db.DropTableIfExists(value) +} + +func (rep *repository) AutoMigrate(value interface{}) *gorm.DB { + return rep.db.AutoMigrate(value) +} + // Transaction start a transaction as a block. // If it is failed, will rollback and return error. // If it is sccuessed, will commit. // ref: https://github.com/jinzhu/gorm/blob/master/main.go#L533 -func (rep *Repository) Transaction(fc func(tx *Repository) error) (err error) { +func (rep *repository) Transaction(fc func(tx Repository) error) (err error) { panicked := true tx := rep.db.Begin() defer func() { @@ -146,7 +170,7 @@ func (rep *Repository) Transaction(fc func(tx *Repository) error) (err error) { } }() - txrep := &Repository{} + txrep := &repository{} txrep.db = tx err = fc(txrep) diff --git a/router/router.go b/router/router.go index 3fdce7b8..f7f94fd3 100644 --- a/router/router.go +++ b/router/router.go @@ -5,12 +5,13 @@ import ( "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" - "github.com/ybkuroki/go-webapp-sample/config" "github.com/ybkuroki/go-webapp-sample/controller" + "github.com/ybkuroki/go-webapp-sample/mycontext" ) // Init initialize the routing of this application. -func Init(e *echo.Echo, conf *config.Config) { +func Init(e *echo.Echo, context mycontext.Context) { + conf := context.GetConfig() if conf.Extension.CorsEnabled { e.Use(middleware.CORSWithConfig(middleware.CORSConfig{ AllowCredentials: true, @@ -35,20 +36,20 @@ func Init(e *echo.Echo, conf *config.Config) { e.HTTPErrorHandler = controller.JSONErrorHandler e.Use(middleware.Recover()) - e.GET(controller.APIBookList, controller.GetBookList()) - e.GET(controller.APIBookSearch, controller.GetBookSearch()) - e.POST(controller.APIBookRegist, controller.PostBookRegist()) - e.POST(controller.APIBookEdit, controller.PostBookEdit()) - e.POST(controller.APIBookDelete, controller.PostBookDelete()) + e.GET(controller.APIBookList, controller.GetBookList(context)) + e.GET(controller.APIBookSearch, controller.GetBookSearch(context)) + e.POST(controller.APIBookRegist, controller.PostBookRegist(context)) + e.POST(controller.APIBookEdit, controller.PostBookEdit(context)) + e.POST(controller.APIBookDelete, controller.PostBookDelete(context)) - e.GET(controller.APIMasterCategory, controller.GetCategoryList()) - e.GET(controller.APIMasterFormat, controller.GetFormatList()) + e.GET(controller.APIMasterCategory, controller.GetCategoryList(context)) + e.GET(controller.APIMasterFormat, controller.GetFormatList(context)) e.GET(controller.APIAccountLoginStatus, controller.GetLoginStatus()) - e.GET(controller.APIAccountLoginAccount, controller.GetLoginAccount()) + e.GET(controller.APIAccountLoginAccount, controller.GetLoginAccount(context)) if conf.Extension.SecurityEnabled { - e.POST(controller.APIAccountLogin, controller.PostLogin()) + e.POST(controller.APIAccountLogin, controller.PostLogin(context)) e.POST(controller.APIAccountLogout, controller.PostLogout()) } diff --git a/service/account.go b/service/account.go index 98caf284..5af7adf0 100644 --- a/service/account.go +++ b/service/account.go @@ -1,15 +1,15 @@ package service import ( - "github.com/ybkuroki/go-webapp-sample/logger" "github.com/ybkuroki/go-webapp-sample/model" - "github.com/ybkuroki/go-webapp-sample/repository" + "github.com/ybkuroki/go-webapp-sample/mycontext" "golang.org/x/crypto/bcrypt" ) // AuthenticateByUsernameAndPassword authenticates by using username and plain text password. -func AuthenticateByUsernameAndPassword(username string, password string) (bool, *model.Account) { - rep := repository.GetRepository() +func AuthenticateByUsernameAndPassword(context mycontext.Context, username string, password string) (bool, *model.Account) { + rep := context.GetRepository() + logger := context.GetLogger() account := model.Account{} result, err := account.FindByName(rep, username) if err != nil { diff --git a/service/book.go b/service/book.go index ebece1f3..736499f5 100644 --- a/service/book.go +++ b/service/book.go @@ -1,57 +1,57 @@ package service import ( - "github.com/ybkuroki/go-webapp-sample/logger" "github.com/ybkuroki/go-webapp-sample/model" "github.com/ybkuroki/go-webapp-sample/model/dto" + "github.com/ybkuroki/go-webapp-sample/mycontext" "github.com/ybkuroki/go-webapp-sample/repository" ) // FindAllBooks returns the list of all books. -func FindAllBooks() *[]model.Book { - rep := repository.GetRepository() +func FindAllBooks(context mycontext.Context) *[]model.Book { + rep := context.GetRepository() book := model.Book{} result, err := book.FindAll(rep) if err != nil { - logger.GetZapLogger().Errorf(err.Error()) + context.GetLogger().GetZapLogger().Errorf(err.Error()) return nil } return result } // FindAllBooksByPage returns the page object of all books. -func FindAllBooksByPage(page int, size int) *model.Page { - rep := repository.GetRepository() +func FindAllBooksByPage(context mycontext.Context, page int, size int) *model.Page { + rep := context.GetRepository() book := model.Book{} result, err := book.FindAllByPage(rep, page, size) if err != nil { - logger.GetZapLogger().Errorf(err.Error()) + context.GetLogger().GetZapLogger().Errorf(err.Error()) return nil } return result } // FindBooksByTitle returns the page object of books matched given book title. -func FindBooksByTitle(title string, page int, size int) *model.Page { - rep := repository.GetRepository() +func FindBooksByTitle(context mycontext.Context, title string, page int, size int) *model.Page { + rep := context.GetRepository() book := model.Book{} result, err := book.FindByTitle(rep, title, page, size) if err != nil { - logger.GetZapLogger().Errorf(err.Error()) + context.GetLogger().GetZapLogger().Errorf(err.Error()) return nil } return result } // RegisterBook register the given book data. -func RegisterBook(dto *dto.RegBookDto) (*model.Book, map[string]string) { +func RegisterBook(context mycontext.Context, dto *dto.RegBookDto) (*model.Book, map[string]string) { errors := dto.Validate() if errors == nil { - rep := repository.GetRepository() + rep := context.GetRepository() var result *model.Book - err := rep.Transaction(func(txrep *repository.Repository) error { + err := rep.Transaction(func(txrep repository.Repository) error { var err error book := dto.Create() @@ -73,7 +73,7 @@ func RegisterBook(dto *dto.RegBookDto) (*model.Book, map[string]string) { }) if err != nil { - logger.GetZapLogger().Errorf(err.Error()) + context.GetLogger().GetZapLogger().Errorf(err.Error()) return nil, map[string]string{"error": "transaction error"} } @@ -84,14 +84,14 @@ func RegisterBook(dto *dto.RegBookDto) (*model.Book, map[string]string) { } // EditBook updates the given book data. -func EditBook(dto *dto.ChgBookDto) (*model.Book, map[string]string) { +func EditBook(context mycontext.Context, dto *dto.ChgBookDto) (*model.Book, map[string]string) { errors := dto.Validate() if errors == nil { - rep := repository.GetRepository() + rep := context.GetRepository() var result *model.Book - err := rep.Transaction(func(txrep *repository.Repository) error { + err := rep.Transaction(func(txrep repository.Repository) error { var err error var book *model.Book @@ -123,7 +123,7 @@ func EditBook(dto *dto.ChgBookDto) (*model.Book, map[string]string) { }) if err != nil { - logger.GetZapLogger().Errorf(err.Error()) + context.GetLogger().GetZapLogger().Errorf(err.Error()) return nil, map[string]string{"error": "transaction error"} } @@ -134,14 +134,14 @@ func EditBook(dto *dto.ChgBookDto) (*model.Book, map[string]string) { } // DeleteBook deletes the given book data. -func DeleteBook(dto *dto.ChgBookDto) (*model.Book, map[string]string) { +func DeleteBook(context mycontext.Context, dto *dto.ChgBookDto) (*model.Book, map[string]string) { errors := dto.Validate() if errors == nil { - rep := repository.GetRepository() + rep := context.GetRepository() var result *model.Book - err := rep.Transaction(func(txrep *repository.Repository) error { + err := rep.Transaction(func(txrep repository.Repository) error { var err error var book *model.Book @@ -158,7 +158,7 @@ func DeleteBook(dto *dto.ChgBookDto) (*model.Book, map[string]string) { }) if err != nil { - logger.GetZapLogger().Errorf(err.Error()) + context.GetLogger().GetZapLogger().Errorf(err.Error()) return nil, map[string]string{"error": "transaction error"} } diff --git a/service/master.go b/service/master.go index aa5859b6..99cbb989 100644 --- a/service/master.go +++ b/service/master.go @@ -1,30 +1,29 @@ package service import ( - "github.com/ybkuroki/go-webapp-sample/logger" "github.com/ybkuroki/go-webapp-sample/model" - "github.com/ybkuroki/go-webapp-sample/repository" + "github.com/ybkuroki/go-webapp-sample/mycontext" ) // FindAllCategories returns the list of all categories. -func FindAllCategories() *[]model.Category { - rep := repository.GetRepository() +func FindAllCategories(context mycontext.Context) *[]model.Category { + rep := context.GetRepository() category := model.Category{} result, err := category.FindAll(rep) if err != nil { - logger.GetZapLogger().Errorf(err.Error()) + context.GetLogger().GetZapLogger().Errorf(err.Error()) return nil } return result } // FindAllFormats returns the list of all formats. -func FindAllFormats() *[]model.Format { - rep := repository.GetRepository() +func FindAllFormats(context mycontext.Context) *[]model.Format { + rep := context.GetRepository() format := model.Format{} result, err := format.FindAll(rep) if err != nil { - logger.GetZapLogger().Errorf(err.Error()) + context.GetLogger().GetZapLogger().Errorf(err.Error()) return nil } return result diff --git a/test/unittest_util.go b/test/unittest_util.go index 1dab2f78..7aba1724 100644 --- a/test/unittest_util.go +++ b/test/unittest_util.go @@ -9,13 +9,14 @@ import ( "github.com/ybkuroki/go-webapp-sample/logger" "github.com/ybkuroki/go-webapp-sample/middleware" "github.com/ybkuroki/go-webapp-sample/migration" + "github.com/ybkuroki/go-webapp-sample/mycontext" "github.com/ybkuroki/go-webapp-sample/repository" "go.uber.org/zap" "go.uber.org/zap/zapcore" ) // Prepare func is to prepare for unit test. -func Prepare() *echo.Echo { +func Prepare() (*echo.Echo, mycontext.Context) { e := echo.New() conf := &config.Config{} @@ -25,21 +26,21 @@ func Prepare() *echo.Echo { conf.Extension.MasterGenerator = true conf.Extension.SecurityEnabled = false conf.Log.RequestLogFormat = "${remote_ip} ${account_name} ${uri} ${method} ${status}" - config.SetConfig(conf) - initTestLogger() - middleware.InitLoggerMiddleware(e) + logger := initTestLogger() + rep := repository.NewBookRepository(logger, conf) + context := mycontext.NewContext(rep, conf, logger) - repository.InitDB() + middleware.InitLoggerMiddleware(e, context) - migration.CreateDatabase(config.GetConfig()) - migration.InitMasterData(config.GetConfig()) + migration.CreateDatabase(context) + migration.InitMasterData(context) - middleware.InitSessionMiddleware(e, config.GetConfig()) - return e + middleware.InitSessionMiddleware(e, context) + return e, context } -func initTestLogger() { +func initTestLogger() *logger.Logger { level := zap.NewAtomicLevel() level.SetLevel(zapcore.DebugLevel) @@ -67,10 +68,11 @@ func initTestLogger() { fmt.Printf("Error") } sugar := zap.Sugar() - log := logger.NewLogger(sugar) - logger.SetLogger(log) - logger.GetZapLogger().Infof("Success to construct zap logger.") + // set package varriable logger. + logger := &logger.Logger{Zap: sugar} + logger.GetZapLogger().Infof("Success to read zap logger configuration") _ = zap.Sync() + return logger } // ConvertToString func is convert model to string.