diff --git a/pkg/fx/gormfx/config.go b/pkg/fx/gormfx/config.go index a5bb03c..9481adf 100644 --- a/pkg/fx/gormfx/config.go +++ b/pkg/fx/gormfx/config.go @@ -1,21 +1,27 @@ package gormfx type Config struct { - DBDriver string `envconfig:"DB_DRIVER" default:""` - DBUser string `envconfig:"DB_USER" default:""` - DBPassword string `envconfig:"DB_PASSWORD" default:""` - DBHost string `envconfig:"DB_HOST" default:""` - DBName string `envconfig:"DB_NAME" default:""` - DBPort string `envconfig:"DB_PORT" default:""` + DBDriver string `envconfig:"DB_DRIVER" default:""` + DBUser string `envconfig:"DB_USER" default:""` + DBPassword string `envconfig:"DB_PASSWORD" default:""` + DBHost string `envconfig:"DB_HOST" default:""` + DBName string `envconfig:"DB_NAME" default:""` + DBPort string `envconfig:"DB_PORT" default:""` + ConnMaxLifetimeSeconds int64 `envconfig:"DB_CONN_MAX_LIFETIME_SECONDS" default:"0"` + MaxIdleConns int `envconfig:"DB_MAX_IDLE_CONNS" default:"0"` + MaxOpenConns int `envconfig:"DB_MAX_OPEN_CONNS" default:"0"` } func parseConfig() *Config { return &Config{ - DBDriver: "mysql", - DBUser: "root", - DBPassword: "password", - DBHost: "localhost", - DBName: "dittodining", - DBPort: "3306", + DBDriver: "mysql", + DBUser: "root", + DBPassword: "password", + DBHost: "localhost", + DBName: "dittodining", + DBPort: "3306", + ConnMaxLifetimeSeconds: 1800, + MaxIdleConns: 10, // TODO: DB 스펙에 따라 적절치로 조정 + MaxOpenConns: 10, } } diff --git a/pkg/fx/gormfx/gormfx.go b/pkg/fx/gormfx/gormfx.go index 31fa98d..1918e43 100644 --- a/pkg/fx/gormfx/gormfx.go +++ b/pkg/fx/gormfx/gormfx.go @@ -1,10 +1,12 @@ package gormfx import ( + "context" "fmt" "go.uber.org/fx" "gorm.io/driver/mysql" "gorm.io/gorm" + "time" ) type Params struct { @@ -22,7 +24,6 @@ type Result struct { var Module = fx.Module("gorm", fx.Provide(parseConfig), fx.Provide(New), - fx.Invoke(connectDB), ) func New(lc fx.Lifecycle, p Params) (Result, error) { @@ -45,7 +46,29 @@ func New(lc fx.Lifecycle, p Params) (Result, error) { return Result{}, err } + lc.Append( + fx.Hook{ + OnStart: func(ctx context.Context) error { + sqlDB, err := db.DB() + if err != nil { + return err + } + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + if err := sqlDB.PingContext(ctx); err != nil { + return fmt.Errorf("database connection timeout: %w", err) + } + + sqlDB.SetConnMaxLifetime(time.Duration(p.Config.ConnMaxLifetimeSeconds) * time.Second) + sqlDB.SetMaxIdleConns(p.Config.MaxIdleConns) + sqlDB.SetMaxOpenConns(p.Config.MaxOpenConns) + + return nil + }, + }, + ) + return Result{DB: db}, nil } - -func connectDB(db *gorm.DB) {} diff --git a/server/api/recommendation/recommendation_api.go b/server/api/recommendation/recommendation_api.go index 21b0917..0a511cc 100644 --- a/server/api/recommendation/recommendation_api.go +++ b/server/api/recommendation/recommendation_api.go @@ -64,6 +64,7 @@ func (c *RecommendationAPIController) requestRestaurantRecommendation() fiber.Ha } result, err := c.restaurantRecommendationService.RequestRestaurantRecommendation( + ctx.UserContext(), nil, recommendation.UserLocation{ Latitude: (*request).UserLocation.Latitude.Decimal, @@ -115,6 +116,7 @@ func (c *RecommendationAPIController) listRecommendedRestaurants() fiber.Handler } listRecommendedRestaurantsResult, err := c.restaurantRecommendationService.ListRecommendedRestaurants( + ctx.UserContext(), int64(restaurantRecommendationRequestID), cursorRestaurantRecommendationID, lo.ToPtr(int64(limit)), @@ -147,7 +149,7 @@ func (c *RecommendationAPIController) selectRestaurantRecommendations() fiber.Ha } } - if _, err := c.restaurantRecommendationService.SelectRestaurantRecommendation(int64(restaurantRecommendationRequestID), request.RestaurantRecommendationIDs); err != nil { + if _, err := c.restaurantRecommendationService.SelectRestaurantRecommendation(ctx.UserContext(), int64(restaurantRecommendationRequestID), request.RestaurantRecommendationIDs); err != nil { return err } @@ -165,7 +167,7 @@ func (c *RecommendationAPIController) getRestaurantRecommendationResult() fiber. } } - result, err := c.restaurantRecommendationService.GetRestaurantRecommendationResult(int64(restaurantRecommendationRequestID)) + result, err := c.restaurantRecommendationService.GetRestaurantRecommendationResult(ctx.UserContext(), int64(restaurantRecommendationRequestID)) if err != nil { return err } @@ -186,7 +188,7 @@ func (c *RecommendationAPIController) getRestaurantRecommendation() fiber.Handle } } - result, err := c.restaurantRecommendationService.GetRestaurantRecommendation(int64(restaurantRecommendationID)) + result, err := c.restaurantRecommendationService.GetRestaurantRecommendation(ctx.UserContext(), int64(restaurantRecommendationID)) if err != nil { if errors.Is(err, restaurant_repository.ErrRestaurantNotFound) { return &customerrors.ApplicationError{ diff --git a/server/repository/recommendation/restaurant_recommendation_repository.go b/server/repository/recommendation/restaurant_recommendation_repository.go index ea4b6c0..821fd9f 100644 --- a/server/repository/recommendation/restaurant_recommendation_repository.go +++ b/server/repository/recommendation/restaurant_recommendation_repository.go @@ -1,6 +1,7 @@ package recommendation import ( + "context" "github.com/BOAZ-LKVK/LKVK-server/server/domain/recommendation" "github.com/pkg/errors" "gorm.io/gorm" @@ -9,21 +10,21 @@ import ( var ErrRestaurantRecommendationNotFound = errors.New("restaurant recommendation not found") type RestaurantRecommendationRepository interface { - FindAllByRestaurantRecommendationRequestID(restaurantRecommendationRequestID int64, cursorRestaurantRecommendationRequestID *int64, limit *int64) ([]*recommendation.RestaurantRecommendation, error) - FindAllByIDs(restaurantRecommendationIDs []int64) ([]*recommendation.RestaurantRecommendation, error) - FindByID(restaurantRecommendationID int64) (*recommendation.RestaurantRecommendation, error) - SaveAll(recommendations []*recommendation.RestaurantRecommendation) error + FindAllByRestaurantRecommendationRequestID(ctx context.Context, db *gorm.DB, restaurantRecommendationRequestID int64, cursorRestaurantRecommendationRequestID *int64, limit *int64) ([]*recommendation.RestaurantRecommendation, error) + FindAllByIDs(ctx context.Context, db *gorm.DB, restaurantRecommendationIDs []int64) ([]*recommendation.RestaurantRecommendation, error) + FindByID(ctx context.Context, db *gorm.DB, restaurantRecommendationID int64) (*recommendation.RestaurantRecommendation, error) + SaveAll(ctx context.Context, db *gorm.DB, recommendations []*recommendation.RestaurantRecommendation) error } -func NewRestaurantRecommendationRepository(db *gorm.DB) RestaurantRecommendationRepository { - return &restaurantRecommendationRepository{db: db} +func NewRestaurantRecommendationRepository() RestaurantRecommendationRepository { + return &restaurantRecommendationRepository{} } -type restaurantRecommendationRepository struct { - db *gorm.DB -} +type restaurantRecommendationRepository struct{} func (r *restaurantRecommendationRepository) FindAllByRestaurantRecommendationRequestID( + ctx context.Context, + db *gorm.DB, restaurantRecommendationRequestID int64, cursorRestaurantRecommendationID *int64, limit *int64, @@ -40,7 +41,7 @@ func (r *restaurantRecommendationRepository) FindAllByRestaurantRecommendationRe limitQuery = int(*limit) } - result := r.db. + result := db. Where( recommendation.RestaurantRecommendation{ RestaurantRecommendationRequestID: restaurantRecommendationRequestID, @@ -56,10 +57,14 @@ func (r *restaurantRecommendationRepository) FindAllByRestaurantRecommendationRe return recommendations, nil } -func (r *restaurantRecommendationRepository) FindAllByIDs(restaurantRecommendationIDs []int64) ([]*recommendation.RestaurantRecommendation, error) { +func (r *restaurantRecommendationRepository) FindAllByIDs( + ctx context.Context, + db *gorm.DB, + restaurantRecommendationIDs []int64, +) ([]*recommendation.RestaurantRecommendation, error) { var recommendations []*recommendation.RestaurantRecommendation - result := r.db. + result := db. Where("restaurant_recommendation_id IN ?", restaurantRecommendationIDs). Find(&recommendations) if result.Error != nil { @@ -69,10 +74,14 @@ func (r *restaurantRecommendationRepository) FindAllByIDs(restaurantRecommendati return recommendations, nil } -func (r *restaurantRecommendationRepository) FindByID(restaurantRecommendationID int64) (*recommendation.RestaurantRecommendation, error) { +func (r *restaurantRecommendationRepository) FindByID( + ctx context.Context, + db *gorm.DB, + restaurantRecommendationID int64, +) (*recommendation.RestaurantRecommendation, error) { var existingRecommendation recommendation.RestaurantRecommendation - result := r.db. + result := db. Where(&recommendation.RestaurantRecommendation{ RestaurantRecommendationID: restaurantRecommendationID, }). @@ -88,8 +97,12 @@ func (r *restaurantRecommendationRepository) FindByID(restaurantRecommendationID return &existingRecommendation, nil } -func (r *restaurantRecommendationRepository) SaveAll(recommendations []*recommendation.RestaurantRecommendation) error { - result := r.db.Save(recommendations) +func (r *restaurantRecommendationRepository) SaveAll( + ctx context.Context, + db *gorm.DB, + recommendations []*recommendation.RestaurantRecommendation, +) error { + result := db.Save(recommendations) if result.Error != nil { return result.Error } diff --git a/server/repository/recommendation/restaurant_recommendation_request_repository.go b/server/repository/recommendation/restaurant_recommendation_request_repository.go index 40d0f49..55fcbd8 100644 --- a/server/repository/recommendation/restaurant_recommendation_request_repository.go +++ b/server/repository/recommendation/restaurant_recommendation_request_repository.go @@ -1,6 +1,7 @@ package recommendation import ( + "context" "errors" "github.com/BOAZ-LKVK/LKVK-server/server/domain/recommendation" "gorm.io/gorm" @@ -9,20 +10,20 @@ import ( var ErrRestaurantRecommendationRequestNotFound = errors.New("restaurant recommendation request not found") type RestaurantRecommendationRequestRepository interface { - Save(request *recommendation.RestaurantRecommendationRequest) (*recommendation.RestaurantRecommendationRequest, error) - FindByID(restaurantRecommendationRequestID int64) (*recommendation.RestaurantRecommendationRequest, error) + Save(ctx context.Context, db *gorm.DB, request *recommendation.RestaurantRecommendationRequest) (*recommendation.RestaurantRecommendationRequest, error) + FindByID(ctx context.Context, db *gorm.DB, restaurantRecommendationRequestID int64) (*recommendation.RestaurantRecommendationRequest, error) } -func NewRestaurantRecommendationRequestRepository(db *gorm.DB) RestaurantRecommendationRequestRepository { - return &restaurantRecommendationRequestRepository{db: db} +func NewRestaurantRecommendationRequestRepository() RestaurantRecommendationRequestRepository { + return &restaurantRecommendationRequestRepository{} } type restaurantRecommendationRequestRepository struct { db *gorm.DB } -func (r *restaurantRecommendationRequestRepository) Save(request *recommendation.RestaurantRecommendationRequest) (*recommendation.RestaurantRecommendationRequest, error) { - result := r.db.Create(request) +func (r *restaurantRecommendationRequestRepository) Save(ctx context.Context, db *gorm.DB, request *recommendation.RestaurantRecommendationRequest) (*recommendation.RestaurantRecommendationRequest, error) { + result := db.Create(request) if result.Error != nil { return nil, result.Error } @@ -30,7 +31,7 @@ func (r *restaurantRecommendationRequestRepository) Save(request *recommendation return request, nil } -func (r *restaurantRecommendationRequestRepository) FindByID(restaurantRecommendationRequestID int64) (*recommendation.RestaurantRecommendationRequest, error) { +func (r *restaurantRecommendationRequestRepository) FindByID(ctx context.Context, db *gorm.DB, restaurantRecommendationRequestID int64) (*recommendation.RestaurantRecommendationRequest, error) { var request *recommendation.RestaurantRecommendationRequest result := r.db.Where(recommendation.RestaurantRecommendationRequest{ diff --git a/server/repository/recommendation/selected_restaurant_recommendation_repository.go b/server/repository/recommendation/selected_restaurant_recommendation_repository.go index 0a73df1..1d1c174 100644 --- a/server/repository/recommendation/selected_restaurant_recommendation_repository.go +++ b/server/repository/recommendation/selected_restaurant_recommendation_repository.go @@ -1,25 +1,26 @@ package recommendation import ( + "context" recommendation_domain "github.com/BOAZ-LKVK/LKVK-server/server/domain/recommendation" "gorm.io/gorm" ) type SelectedRestaurantRecommendationRepository interface { - SaveAll(selectedRestaurantRecommendations []*recommendation_domain.SelectedRestaurantRecommendation) error - FindAllByRestaurantRecommendationRequestID(restaurantRecommendationRequestID int64) ([]*recommendation_domain.SelectedRestaurantRecommendation, error) + SaveAll(ctx context.Context, db *gorm.DB, selectedRestaurantRecommendations []*recommendation_domain.SelectedRestaurantRecommendation) error + FindAllByRestaurantRecommendationRequestID(ctx context.Context, db *gorm.DB, restaurantRecommendationRequestID int64) ([]*recommendation_domain.SelectedRestaurantRecommendation, error) } -func NewSelectedRestaurantRecommendationRepository(db *gorm.DB) SelectedRestaurantRecommendationRepository { - return &selectedRestaurantRecommendationRepository{db: db} +func NewSelectedRestaurantRecommendationRepository() SelectedRestaurantRecommendationRepository { + return &selectedRestaurantRecommendationRepository{} } type selectedRestaurantRecommendationRepository struct { db *gorm.DB } -func (r *selectedRestaurantRecommendationRepository) SaveAll(selectedRestaurantRecommendations []*recommendation_domain.SelectedRestaurantRecommendation) error { - result := r.db.Save(selectedRestaurantRecommendations) +func (r *selectedRestaurantRecommendationRepository) SaveAll(ctx context.Context, db *gorm.DB, selectedRestaurantRecommendations []*recommendation_domain.SelectedRestaurantRecommendation) error { + result := db.Save(selectedRestaurantRecommendations) if result.Error != nil { return result.Error } @@ -27,9 +28,9 @@ func (r *selectedRestaurantRecommendationRepository) SaveAll(selectedRestaurantR return nil } -func (r *selectedRestaurantRecommendationRepository) FindAllByRestaurantRecommendationRequestID(restaurantRecommendationRequestID int64) ([]*recommendation_domain.SelectedRestaurantRecommendation, error) { +func (r *selectedRestaurantRecommendationRepository) FindAllByRestaurantRecommendationRequestID(ctx context.Context, db *gorm.DB, restaurantRecommendationRequestID int64) ([]*recommendation_domain.SelectedRestaurantRecommendation, error) { var selectedRestaurantRecommendations []*recommendation_domain.SelectedRestaurantRecommendation - result := r.db. + result := db. Where(recommendation_domain.SelectedRestaurantRecommendation{ RestaurantRecommendationRequestID: restaurantRecommendationRequestID, }). diff --git a/server/repository/restaurant/restaurant_image_repository.go b/server/repository/restaurant/restaurant_image_repository.go index b5b252a..326d438 100644 --- a/server/repository/restaurant/restaurant_image_repository.go +++ b/server/repository/restaurant/restaurant_image_repository.go @@ -1,28 +1,25 @@ package restaurant import ( + "context" "github.com/BOAZ-LKVK/LKVK-server/server/domain/restaurant" "gorm.io/gorm" ) type RestaurantImageRepository interface { - FindAllByRestaurantID(restaurantID int64) ([]*restaurant.RestaurantImage, error) - FindAllByRestaurantIDs(restaurantIDs []int64) ([]*restaurant.RestaurantImage, error) + FindAllByRestaurantID(ctx context.Context, db *gorm.DB, restaurantID int64) ([]*restaurant.RestaurantImage, error) + FindAllByRestaurantIDs(ctx context.Context, db *gorm.DB, restaurantIDs []int64) ([]*restaurant.RestaurantImage, error) } -func NewRestaurantImageRepository(db *gorm.DB) RestaurantImageRepository { - return &restaurantImageRepository{ - db: db, - } +func NewRestaurantImageRepository() RestaurantImageRepository { + return &restaurantImageRepository{} } -type restaurantImageRepository struct { - db *gorm.DB -} +type restaurantImageRepository struct{} -func (r *restaurantImageRepository) FindAllByRestaurantID(restaurantID int64) ([]*restaurant.RestaurantImage, error) { +func (r *restaurantImageRepository) FindAllByRestaurantID(ctx context.Context, db *gorm.DB, restaurantID int64) ([]*restaurant.RestaurantImage, error) { var images []*restaurant.RestaurantImage - result := r.db. + result := db. Where(restaurant.RestaurantImage{ RestaurantID: restaurantID, }). @@ -34,9 +31,9 @@ func (r *restaurantImageRepository) FindAllByRestaurantID(restaurantID int64) ([ return images, nil } -func (r *restaurantImageRepository) FindAllByRestaurantIDs(restaurantIDs []int64) ([]*restaurant.RestaurantImage, error) { +func (r *restaurantImageRepository) FindAllByRestaurantIDs(ctx context.Context, db *gorm.DB, restaurantIDs []int64) ([]*restaurant.RestaurantImage, error) { var images []*restaurant.RestaurantImage - result := r.db. + result := db. Where("restaurant_id IN ?", restaurantIDs). Find(&images) if result.Error != nil { diff --git a/server/repository/restaurant/restaurant_menu_repository.go b/server/repository/restaurant/restaurant_menu_repository.go index 139f5ce..316c705 100644 --- a/server/repository/restaurant/restaurant_menu_repository.go +++ b/server/repository/restaurant/restaurant_menu_repository.go @@ -1,26 +1,25 @@ package restaurant import ( + "context" "github.com/BOAZ-LKVK/LKVK-server/server/domain/restaurant" "gorm.io/gorm" ) type RestaurantMenuRepository interface { - FindAllByRestaurantID(restaurantID int64) ([]*restaurant.RestaurantMenu, error) - FindAllByRestaurantIDs(restaurantIDs []int64) ([]*restaurant.RestaurantMenu, error) + FindAllByRestaurantID(ctx context.Context, db *gorm.DB, restaurantID int64) ([]*restaurant.RestaurantMenu, error) + FindAllByRestaurantIDs(ctx context.Context, db *gorm.DB, restaurantIDs []int64) ([]*restaurant.RestaurantMenu, error) } -func NewRestaurantMenuRepository(db *gorm.DB) RestaurantMenuRepository { - return &restaurantMenuRepository{db: db} +func NewRestaurantMenuRepository() RestaurantMenuRepository { + return &restaurantMenuRepository{} } -type restaurantMenuRepository struct { - db *gorm.DB -} +type restaurantMenuRepository struct{} -func (r *restaurantMenuRepository) FindAllByRestaurantID(restaurantID int64) ([]*restaurant.RestaurantMenu, error) { +func (r *restaurantMenuRepository) FindAllByRestaurantID(ctx context.Context, db *gorm.DB, restaurantID int64) ([]*restaurant.RestaurantMenu, error) { var menus []*restaurant.RestaurantMenu - result := r.db. + result := db. Where(restaurant.RestaurantMenu{ RestaurantID: restaurantID, }). @@ -32,10 +31,10 @@ func (r *restaurantMenuRepository) FindAllByRestaurantID(restaurantID int64) ([] return menus, nil } -func (r *restaurantMenuRepository) FindAllByRestaurantIDs(restaurantIDs []int64) ([]*restaurant.RestaurantMenu, error) { +func (r *restaurantMenuRepository) FindAllByRestaurantIDs(ctx context.Context, db *gorm.DB, restaurantIDs []int64) ([]*restaurant.RestaurantMenu, error) { var menus []*restaurant.RestaurantMenu - result := r.db. + result := db. Where("restaurant_id IN ?", restaurantIDs). Find(&menus) if result.Error != nil { diff --git a/server/repository/restaurant/restaurant_repository.go b/server/repository/restaurant/restaurant_repository.go index 292b2fa..2e57bba 100644 --- a/server/repository/restaurant/restaurant_repository.go +++ b/server/repository/restaurant/restaurant_repository.go @@ -1,6 +1,7 @@ package restaurant import ( + "context" "github.com/BOAZ-LKVK/LKVK-server/server/domain/restaurant" "github.com/pkg/errors" "gorm.io/gorm" @@ -9,22 +10,20 @@ import ( var ErrRestaurantNotFound = errors.New("restaurant not found") type RestaurantRepository interface { - FindByID(restaurantID int64) (*restaurant.Restaurant, error) - FindByIDs(restaurantIDs []int64) ([]*restaurant.Restaurant, error) - FindAllOrderByRecommendationScoreDesc(limit int) ([]*restaurant.Restaurant, error) + FindByID(ctx context.Context, db *gorm.DB, restaurantID int64) (*restaurant.Restaurant, error) + FindByIDs(ctx context.Context, db *gorm.DB, restaurantIDs []int64) ([]*restaurant.Restaurant, error) + FindAllOrderByRecommendationScoreDesc(ctx context.Context, db *gorm.DB, limit int) ([]*restaurant.Restaurant, error) } -func NewRestaurantRepository(db *gorm.DB) RestaurantRepository { - return &restaurantRepository{db: db} +func NewRestaurantRepository() RestaurantRepository { + return &restaurantRepository{} } -type restaurantRepository struct { - db *gorm.DB -} +type restaurantRepository struct{} -func (r *restaurantRepository) FindByID(restaurantID int64) (*restaurant.Restaurant, error) { +func (r *restaurantRepository) FindByID(ctx context.Context, db *gorm.DB, restaurantID int64) (*restaurant.Restaurant, error) { var existingRestaurant *restaurant.Restaurant - result := r.db. + result := db. Where(restaurant.Restaurant{ RestaurantID: restaurantID, }). @@ -40,9 +39,9 @@ func (r *restaurantRepository) FindByID(restaurantID int64) (*restaurant.Restaur return existingRestaurant, nil } -func (r *restaurantRepository) FindByIDs(restaurantIDs []int64) ([]*restaurant.Restaurant, error) { +func (r *restaurantRepository) FindByIDs(ctx context.Context, db *gorm.DB, restaurantIDs []int64) ([]*restaurant.Restaurant, error) { var existingRestaurants []*restaurant.Restaurant - result := r.db. + result := db. Where("restaurant_id IN ?", restaurantIDs). Find(&existingRestaurants) if result.Error != nil { @@ -52,9 +51,9 @@ func (r *restaurantRepository) FindByIDs(restaurantIDs []int64) ([]*restaurant.R return existingRestaurants, nil } -func (r *restaurantRepository) FindAllOrderByRecommendationScoreDesc(limit int) ([]*restaurant.Restaurant, error) { +func (r *restaurantRepository) FindAllOrderByRecommendationScoreDesc(ctx context.Context, db *gorm.DB, limit int) ([]*restaurant.Restaurant, error) { var existingRestaurants []*restaurant.Restaurant - result := r.db. + result := db. Order("recommendation_score DESC"). Limit(limit). Find(&existingRestaurants) diff --git a/server/repository/restaurant/restaurant_review_repository.go b/server/repository/restaurant/restaurant_review_repository.go index a71502a..e2722ff 100644 --- a/server/repository/restaurant/restaurant_review_repository.go +++ b/server/repository/restaurant/restaurant_review_repository.go @@ -1,29 +1,28 @@ package restaurant import ( + "context" "github.com/BOAZ-LKVK/LKVK-server/server/domain/restaurant" "gorm.io/gorm" ) type RestaurantReviewRepository interface { // TODO: limit 추가 - FindAllByRestaurantID(restaurantID int64) ([]*restaurant.RestaurantReview, error) + FindAllByRestaurantID(ctx context.Context, db *gorm.DB, restaurantID int64) ([]*restaurant.RestaurantReview, error) // TODO: limit 추가 - FindAllByRestaurantIDs(restaurantIDs []int64) ([]*restaurant.RestaurantReview, error) - CountByRestaurantID(restaurantID int64) (int64, error) + FindAllByRestaurantIDs(ctx context.Context, db *gorm.DB, restaurantIDs []int64) ([]*restaurant.RestaurantReview, error) + CountByRestaurantID(ctx context.Context, db *gorm.DB, restaurantID int64) (int64, error) } -func NewRestaurantReviewRepository(db *gorm.DB) RestaurantReviewRepository { - return &restaurantReviewRepository{db: db} +func NewRestaurantReviewRepository() RestaurantReviewRepository { + return &restaurantReviewRepository{} } -type restaurantReviewRepository struct { - db *gorm.DB -} +type restaurantReviewRepository struct{} -func (r *restaurantReviewRepository) FindAllByRestaurantID(restaurantID int64) ([]*restaurant.RestaurantReview, error) { +func (r *restaurantReviewRepository) FindAllByRestaurantID(ctx context.Context, db *gorm.DB, restaurantID int64) ([]*restaurant.RestaurantReview, error) { var reviews []*restaurant.RestaurantReview - result := r.db. + result := db. Where(restaurant.RestaurantReview{ RestaurantID: restaurantID, }). @@ -35,10 +34,10 @@ func (r *restaurantReviewRepository) FindAllByRestaurantID(restaurantID int64) ( return reviews, nil } -func (r *restaurantReviewRepository) FindAllByRestaurantIDs(restaurantIDs []int64) ([]*restaurant.RestaurantReview, error) { +func (r *restaurantReviewRepository) FindAllByRestaurantIDs(ctx context.Context, db *gorm.DB, restaurantIDs []int64) ([]*restaurant.RestaurantReview, error) { var reviews []*restaurant.RestaurantReview - result := r.db. + result := db. Where("restaurant_id IN ?", restaurantIDs). Find(&reviews) if result.Error != nil { @@ -48,9 +47,9 @@ func (r *restaurantReviewRepository) FindAllByRestaurantIDs(restaurantIDs []int6 return reviews, nil } -func (r *restaurantReviewRepository) CountByRestaurantID(restaurantID int64) (int64, error) { +func (r *restaurantReviewRepository) CountByRestaurantID(ctx context.Context, db *gorm.DB, restaurantID int64) (int64, error) { var count int64 - result := r.db. + result := db. Model(&restaurant.RestaurantReview{}). Where(restaurant.RestaurantReview{ RestaurantID: restaurantID, diff --git a/server/service/recommendation/restaurant_recommendation_service.go b/server/service/recommendation/restaurant_recommendation_service.go index 41914cd..cb50153 100644 --- a/server/service/recommendation/restaurant_recommendation_service.go +++ b/server/service/recommendation/restaurant_recommendation_service.go @@ -11,17 +11,19 @@ import ( restaurant_model "github.com/BOAZ-LKVK/LKVK-server/server/service/restaurant/model" "github.com/pkg/errors" "github.com/samber/lo" + "golang.org/x/net/context" + "gorm.io/gorm" "strconv" "time" ) type RestaurantRecommendationService interface { - RequestRestaurantRecommendation(userID *int64, userLocation recommendation_domain.UserLocation, now time.Time) (*recommendation_model.RequestRestaurantRecommendationResult, error) - GetRestaurantRecommendationRequest(restaurantRecommendationRequestID int64) (*recommendation_domain.RestaurantRecommendationRequest, error) - ListRecommendedRestaurants(restaurantRecommendationRequestID int64, cursorRestaurantRecommendationID *int64, limit *int64) (*recommendation_model.ListRecommendedRestaurantsResult, error) - SelectRestaurantRecommendation(restaurantRecommendationRequestID int64, restaurantRecommendationIDs []int64) (*recommendation_model.SelectRestaurantRecommendationResult, error) - GetRestaurantRecommendationResult(restaurantRecommendationRequestID int64) (*recommendation_model.GetRestaurantRecommendationResultResult, error) - GetRestaurantRecommendation(restaurantRecommendationID int64) (*recommendation_model.GetRestaurantRecommendationResult, error) + RequestRestaurantRecommendation(ctx context.Context, userID *int64, userLocation recommendation_domain.UserLocation, now time.Time) (*recommendation_model.RequestRestaurantRecommendationResult, error) + GetRestaurantRecommendationRequest(ctx context.Context, restaurantRecommendationRequestID int64) (*recommendation_domain.RestaurantRecommendationRequest, error) + ListRecommendedRestaurants(ctx context.Context, restaurantRecommendationRequestID int64, cursorRestaurantRecommendationID *int64, limit *int64) (*recommendation_model.ListRecommendedRestaurantsResult, error) + SelectRestaurantRecommendation(ctx context.Context, restaurantRecommendationRequestID int64, restaurantRecommendationIDs []int64) (*recommendation_model.SelectRestaurantRecommendationResult, error) + GetRestaurantRecommendationResult(ctx context.Context, restaurantRecommendationRequestID int64) (*recommendation_model.GetRestaurantRecommendationResultResult, error) + GetRestaurantRecommendation(ctx context.Context, restaurantRecommendationID int64) (*recommendation_model.GetRestaurantRecommendationResult, error) } func NewRestaurantRecommendationService( @@ -32,6 +34,7 @@ func NewRestaurantRecommendationService( restaurantMenuRepository restaurant_repository.RestaurantMenuRepository, restaurantReviewRepository restaurant_repository.RestaurantReviewRepository, restaurantImageRepository restaurant_repository.RestaurantImageRepository, + db *gorm.DB, ) RestaurantRecommendationService { return &restaurantRecommendationService{ restaurantRecommendationRequestRepository: restaurantRecommendationRequestRepository, @@ -41,6 +44,7 @@ func NewRestaurantRecommendationService( restaurantMenuRepository: restaurantMenuRepository, restaurantReviewRepository: restaurantReviewRepository, restaurantImageRepository: restaurantImageRepository, + db: db, } } @@ -52,60 +56,71 @@ type restaurantRecommendationService struct { restaurantMenuRepository restaurant_repository.RestaurantMenuRepository restaurantReviewRepository restaurant_repository.RestaurantReviewRepository restaurantImageRepository restaurant_repository.RestaurantImageRepository + db *gorm.DB } -func (s *restaurantRecommendationService) RequestRestaurantRecommendation(userID *int64, userLocation recommendation_domain.UserLocation, now time.Time) (*recommendation_model.RequestRestaurantRecommendationResult, error) { - recommendationRequest := recommendation_domain.NewRestaurantRecommendationRequest( - userID, - recommendation_domain.NewUserLocation( - userLocation.Latitude, userLocation.Longitude, - ), - // TODO: testablity를 위해 clock interface 개발 후 대체 - now, - ) - created, err := s.restaurantRecommendationRequestRepository.Save(recommendationRequest) - if err != nil { - return nil, err - } +func (s *restaurantRecommendationService) RequestRestaurantRecommendation(ctx context.Context, userID *int64, userLocation recommendation_domain.UserLocation, now time.Time) (*recommendation_model.RequestRestaurantRecommendationResult, error) { + var createdRecommendationRequest *recommendation_domain.RestaurantRecommendationRequest + if err := s.db.Transaction(func(tx *gorm.DB) error { + recommendationRequest := recommendation_domain.NewRestaurantRecommendationRequest( + userID, + recommendation_domain.NewUserLocation( + userLocation.Latitude, userLocation.Longitude, + ), + // TODO: testablity를 위해 clock interface 개발 후 대체 + now, + ) + created, err := s.restaurantRecommendationRequestRepository.Save(ctx, s.db, recommendationRequest) + if err != nil { + return err + } + createdRecommendationRequest = created - restaurantsOrderByRecommendationScoreDesc, err := s.restaurantRepository.FindAllOrderByRecommendationScoreDesc(10) - if err != nil { - return nil, err - } + restaurantsOrderByRecommendationScoreDesc, err := s.restaurantRepository.FindAllOrderByRecommendationScoreDesc(ctx, s.db, 10) + if err != nil { + return err + } - recommendations := make([]*recommendation_domain.RestaurantRecommendation, 0, len(restaurantsOrderByRecommendationScoreDesc)) - for _, r := range restaurantsOrderByRecommendationScoreDesc { - distanceInMeters := location.CalculateDistanceInMeters(userLocation.Latitude, userLocation.Longitude, r.Latitude, r.Longitude) + recommendations := make([]*recommendation_domain.RestaurantRecommendation, 0, len(restaurantsOrderByRecommendationScoreDesc)) + for _, r := range restaurantsOrderByRecommendationScoreDesc { + distanceInMeters := location.CalculateDistanceInMeters(userLocation.Latitude, userLocation.Longitude, r.Latitude, r.Longitude) + + recommendations = append(recommendations, + recommendation_domain.NewRestaurantRecommendation( + recommendationRequest.RestaurantRecommendationRequestID, + r.RestaurantID, + distanceInMeters, + ), + ) + } - recommendations = append(recommendations, - recommendation_domain.NewRestaurantRecommendation( - recommendationRequest.RestaurantRecommendationRequestID, - r.RestaurantID, - distanceInMeters, - ), - ) - } + if err := s.restaurantRecommendationRepository.SaveAll(ctx, s.db, recommendations); err != nil { + return err + } - if err := s.restaurantRecommendationRepository.SaveAll(recommendations); err != nil { + return nil + }); err != nil { return nil, err } return &recommendation_model.RequestRestaurantRecommendationResult{ - RestaurantRecommendationRequestID: created.RestaurantRecommendationRequestID, + RestaurantRecommendationRequestID: createdRecommendationRequest.RestaurantRecommendationRequestID, }, nil } -func (s *restaurantRecommendationService) GetRestaurantRecommendationRequest(restaurantRecommendationRequestID int64) (*recommendation_domain.RestaurantRecommendationRequest, error) { - return s.restaurantRecommendationRequestRepository.FindByID(restaurantRecommendationRequestID) +func (s *restaurantRecommendationService) GetRestaurantRecommendationRequest(ctx context.Context, restaurantRecommendationRequestID int64) (*recommendation_domain.RestaurantRecommendationRequest, error) { + return s.restaurantRecommendationRequestRepository.FindByID(ctx, s.db, restaurantRecommendationRequestID) } -func (s *restaurantRecommendationService) ListRecommendedRestaurants(restaurantRecommendationRequestID int64, cursorRestaurantRecommendationID *int64, limit *int64) (*recommendation_model.ListRecommendedRestaurantsResult, error) { - _, err := s.GetRestaurantRecommendationRequest(restaurantRecommendationRequestID) +func (s *restaurantRecommendationService) ListRecommendedRestaurants(ctx context.Context, restaurantRecommendationRequestID int64, cursorRestaurantRecommendationID *int64, limit *int64) (*recommendation_model.ListRecommendedRestaurantsResult, error) { + _, err := s.GetRestaurantRecommendationRequest(ctx, restaurantRecommendationRequestID) if err != nil { return nil, err } recommendations, err := s.restaurantRecommendationRepository.FindAllByRestaurantRecommendationRequestID( + ctx, + s.db, restaurantRecommendationRequestID, cursorRestaurantRecommendationID, limit, @@ -120,7 +135,7 @@ func (s *restaurantRecommendationService) ListRecommendedRestaurants(restaurantR return item.RestaurantID }) - restaurants, err := s.restaurantRepository.FindByIDs(restaurantIDs) + restaurants, err := s.restaurantRepository.FindByIDs(ctx, s.db, restaurantIDs) if err != nil { return nil, err } @@ -128,7 +143,7 @@ func (s *restaurantRecommendationService) ListRecommendedRestaurants(restaurantR return item.RestaurantID, item }) - restaurantImages, err := s.restaurantImageRepository.FindAllByRestaurantIDs(restaurantIDs) + restaurantImages, err := s.restaurantImageRepository.FindAllByRestaurantIDs(ctx, s.db, restaurantIDs) if err != nil { return nil, err } @@ -136,7 +151,7 @@ func (s *restaurantRecommendationService) ListRecommendedRestaurants(restaurantR return item.RestaurantID }) - menus, err := s.restaurantMenuRepository.FindAllByRestaurantIDs(restaurantIDs) + menus, err := s.restaurantMenuRepository.FindAllByRestaurantIDs(ctx, s.db, restaurantIDs) if err != nil { return nil, err } @@ -144,7 +159,7 @@ func (s *restaurantRecommendationService) ListRecommendedRestaurants(restaurantR return item.RestaurantID }) - reviews, err := s.restaurantReviewRepository.FindAllByRestaurantIDs(restaurantIDs) + reviews, err := s.restaurantReviewRepository.FindAllByRestaurantIDs(ctx, s.db, restaurantIDs) if err != nil { return nil, err } @@ -179,13 +194,13 @@ func (s *restaurantRecommendationService) ListRecommendedRestaurants(restaurantR }, nil } -func (s *restaurantRecommendationService) SelectRestaurantRecommendation(restaurantRecommendationRequestID int64, restaurantRecommendationIDs []int64) (*recommendation_model.SelectRestaurantRecommendationResult, error) { - request, err := s.GetRestaurantRecommendationRequest(restaurantRecommendationRequestID) +func (s *restaurantRecommendationService) SelectRestaurantRecommendation(ctx context.Context, restaurantRecommendationRequestID int64, restaurantRecommendationIDs []int64) (*recommendation_model.SelectRestaurantRecommendationResult, error) { + request, err := s.GetRestaurantRecommendationRequest(ctx, restaurantRecommendationRequestID) if err != nil { return nil, err } - recommendations, err := s.restaurantRecommendationRepository.FindAllByIDs(restaurantRecommendationIDs) + recommendations, err := s.restaurantRecommendationRepository.FindAllByIDs(ctx, s.db, restaurantRecommendationIDs) if err != nil { return nil, err } @@ -202,15 +217,15 @@ func (s *restaurantRecommendationService) SelectRestaurantRecommendation(restaur )) } - if err := s.selectedRestaurantRecommendationRepository.SaveAll(selectedRestaurantRecommendations); err != nil { + if err := s.selectedRestaurantRecommendationRepository.SaveAll(ctx, s.db, selectedRestaurantRecommendations); err != nil { return nil, err } return &recommendation_model.SelectRestaurantRecommendationResult{}, nil } -func (s *restaurantRecommendationService) GetRestaurantRecommendationResult(restaurantRecommendationRequestID int64) (*recommendation_model.GetRestaurantRecommendationResultResult, error) { - selectedRestaurantRecommendations, err := s.selectedRestaurantRecommendationRepository.FindAllByRestaurantRecommendationRequestID(restaurantRecommendationRequestID) +func (s *restaurantRecommendationService) GetRestaurantRecommendationResult(ctx context.Context, restaurantRecommendationRequestID int64) (*recommendation_model.GetRestaurantRecommendationResultResult, error) { + selectedRestaurantRecommendations, err := s.selectedRestaurantRecommendationRepository.FindAllByRestaurantRecommendationRequestID(ctx, s.db, restaurantRecommendationRequestID) if err != nil { return nil, err } @@ -219,7 +234,7 @@ func (s *restaurantRecommendationService) GetRestaurantRecommendationResult(rest return item.RestaurantID }) - restaurants, err := s.restaurantRepository.FindByIDs(restaurantIDs) + restaurants, err := s.restaurantRepository.FindByIDs(ctx, s.db, restaurantIDs) if err != nil { return nil, err } @@ -227,7 +242,7 @@ func (s *restaurantRecommendationService) GetRestaurantRecommendationResult(rest return item.RestaurantID, item }) - restaurantImages, err := s.restaurantImageRepository.FindAllByRestaurantIDs(restaurantIDs) + restaurantImages, err := s.restaurantImageRepository.FindAllByRestaurantIDs(ctx, s.db, restaurantIDs) if err != nil { return nil, err } @@ -235,7 +250,7 @@ func (s *restaurantRecommendationService) GetRestaurantRecommendationResult(rest return item.RestaurantID }) - menus, err := s.restaurantMenuRepository.FindAllByRestaurantIDs(restaurantIDs) + menus, err := s.restaurantMenuRepository.FindAllByRestaurantIDs(ctx, s.db, restaurantIDs) if err != nil { return nil, err } @@ -243,7 +258,7 @@ func (s *restaurantRecommendationService) GetRestaurantRecommendationResult(rest return item.RestaurantID }) - reviews, err := s.restaurantReviewRepository.FindAllByRestaurantIDs(restaurantIDs) + reviews, err := s.restaurantReviewRepository.FindAllByRestaurantIDs(ctx, s.db, restaurantIDs) if err != nil { return nil, err } @@ -255,7 +270,7 @@ func (s *restaurantRecommendationService) GetRestaurantRecommendationResult(rest return item.RestaurantRecommendationID }) - restaurantRecommendations, err := s.restaurantRecommendationRepository.FindAllByIDs(restaurantRecommendationIDs) + restaurantRecommendations, err := s.restaurantRecommendationRepository.FindAllByIDs(ctx, s.db, restaurantRecommendationIDs) if err != nil { return nil, err } @@ -294,28 +309,28 @@ func (s *restaurantRecommendationService) GetRestaurantRecommendationResult(rest }, nil } -func (s *restaurantRecommendationService) GetRestaurantRecommendation(restaurantRecommendationID int64) (*recommendation_model.GetRestaurantRecommendationResult, error) { - existingRecommendation, err := s.restaurantRecommendationRepository.FindByID(restaurantRecommendationID) +func (s *restaurantRecommendationService) GetRestaurantRecommendation(ctx context.Context, restaurantRecommendationID int64) (*recommendation_model.GetRestaurantRecommendationResult, error) { + existingRecommendation, err := s.restaurantRecommendationRepository.FindByID(ctx, s.db, restaurantRecommendationID) if err != nil { return nil, err } - restaurant, err := s.restaurantRepository.FindByID(existingRecommendation.RestaurantID) + restaurant, err := s.restaurantRepository.FindByID(ctx, s.db, existingRecommendation.RestaurantID) if err != nil { return nil, err } - menuItems, err := s.restaurantMenuRepository.FindAllByRestaurantID(existingRecommendation.RestaurantID) + menuItems, err := s.restaurantMenuRepository.FindAllByRestaurantID(ctx, s.db, existingRecommendation.RestaurantID) if err != nil { return nil, err } - reviewItems, err := s.restaurantReviewRepository.FindAllByRestaurantID(existingRecommendation.RestaurantID) + reviewItems, err := s.restaurantReviewRepository.FindAllByRestaurantID(ctx, s.db, existingRecommendation.RestaurantID) if err != nil { return nil, err } - restaurantImageItems, err := s.restaurantImageRepository.FindAllByRestaurantID(existingRecommendation.RestaurantID) + restaurantImageItems, err := s.restaurantImageRepository.FindAllByRestaurantID(ctx, s.db, existingRecommendation.RestaurantID) if err != nil { return nil, err } diff --git a/server/service/restaurant/restaurant_service.go b/server/service/restaurant/restaurant_service.go index ef41b75..3118fb2 100644 --- a/server/service/restaurant/restaurant_service.go +++ b/server/service/restaurant/restaurant_service.go @@ -6,12 +6,14 @@ import ( "github.com/BOAZ-LKVK/LKVK-server/server/repository/restaurant" restaurant_model "github.com/BOAZ-LKVK/LKVK-server/server/service/restaurant/model" "github.com/pkg/errors" + "golang.org/x/net/context" + "gorm.io/gorm" ) type RestaurantService interface { - GetRestaurant(restaurantID int64) (*restaurant_model.Restaurant, error) - ListRestaurantMenus(restaurantID int64) ([]*restaurant_model.RestaurantMenu, error) - GetRestaurantReview(restaurantID int64) (*restaurant_model.RestaurantReview, error) + GetRestaurant(ctx context.Context, restaurantID int64) (*restaurant_model.Restaurant, error) + ListRestaurantMenus(ctx context.Context, restaurantID int64) ([]*restaurant_model.RestaurantMenu, error) + GetRestaurantReview(ctx context.Context, restaurantID int64) (*restaurant_model.RestaurantReview, error) } func NewRestaurantService( @@ -19,12 +21,14 @@ func NewRestaurantService( restaurantMenuRepository restaurant.RestaurantMenuRepository, restaurantReviewRepository restaurant.RestaurantReviewRepository, restaurantImageRepository restaurant.RestaurantImageRepository, + db *gorm.DB, ) RestaurantService { return &restaurantService{ restaurantRepository: restaurantRepository, restaurantMenuRepository: restaurantMenuRepository, restaurantReviewRepository: restaurantReviewRepository, restaurantImageRepository: restaurantImageRepository, + db: db, } } @@ -33,10 +37,11 @@ type restaurantService struct { restaurantMenuRepository restaurant.RestaurantMenuRepository restaurantReviewRepository restaurant.RestaurantReviewRepository restaurantImageRepository restaurant.RestaurantImageRepository + db *gorm.DB } -func (s *restaurantService) GetRestaurant(restaurantID int64) (*restaurant_model.Restaurant, error) { - r, err := s.restaurantRepository.FindByID(restaurantID) +func (s *restaurantService) GetRestaurant(ctx context.Context, restaurantID int64) (*restaurant_model.Restaurant, error) { + r, err := s.restaurantRepository.FindByID(ctx, s.db, restaurantID) if err != nil { return nil, err } @@ -46,7 +51,7 @@ func (s *restaurantService) GetRestaurant(restaurantID int64) (*restaurant_model return nil, errors.Wrap(err, "failed to unmarshal business hours") } - images, err := s.restaurantImageRepository.FindAllByRestaurantID(restaurantID) + images, err := s.restaurantImageRepository.FindAllByRestaurantID(ctx, s.db, restaurantID) if err != nil { return nil, err } @@ -70,8 +75,8 @@ func (s *restaurantService) GetRestaurant(restaurantID int64) (*restaurant_model }, nil } -func (s *restaurantService) ListRestaurantMenus(restaurantID int64) ([]*restaurant_model.RestaurantMenu, error) { - menus, err := s.restaurantMenuRepository.FindAllByRestaurantID(restaurantID) +func (s *restaurantService) ListRestaurantMenus(ctx context.Context, restaurantID int64) ([]*restaurant_model.RestaurantMenu, error) { + menus, err := s.restaurantMenuRepository.FindAllByRestaurantID(ctx, s.db, restaurantID) if err != nil { return nil, err } @@ -90,13 +95,13 @@ func (s *restaurantService) ListRestaurantMenus(restaurantID int64) ([]*restaura return modelMenus, nil } -func (s *restaurantService) GetRestaurantReview(restaurantID int64) (*restaurant_model.RestaurantReview, error) { - r, err := s.restaurantRepository.FindByID(restaurantID) +func (s *restaurantService) GetRestaurantReview(ctx context.Context, restaurantID int64) (*restaurant_model.RestaurantReview, error) { + r, err := s.restaurantRepository.FindByID(ctx, s.db, restaurantID) if err != nil { return nil, err } - reviews, err := s.restaurantReviewRepository.FindAllByRestaurantID(restaurantID) + reviews, err := s.restaurantReviewRepository.FindAllByRestaurantID(ctx, s.db, restaurantID) if err != nil { return nil, err }