Skip to content

Commit

Permalink
Added new structure by name Records for holding totalRecords. Deleted…
Browse files Browse the repository at this point in the history
… TotalRecords field from Product structure as it is a bad practice.
  • Loading branch information
santoshkavhar committed Oct 9, 2020
1 parent 72f8370 commit ec8f629
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 30 deletions.
2 changes: 1 addition & 1 deletion db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
)

type Storer interface {
ListProducts(context.Context, int, int) ([]Product, error)
ListProducts(context.Context, int, int) (int, []Product, error)
FilteredProducts(context.Context, Filter, string, string) (int, []Product, error)
SearchProductsByText(context.Context, string, string, string) (int, []Product, error)
CreateProduct(context.Context, Product, []*multipart.FileHeader) (Product, error)
Expand Down
36 changes: 16 additions & 20 deletions db/product.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ type Product struct {
Color string `db:"color" json:"color,*" schema:"color,*"`
Size string `db:"size" json:"size,*" schema:"size,*"`
URLs pq.StringArray `db:"image_urls" json:"image_urls,*" schema:"images"`
TotalRecords int `db:"total" json:"-"`
}

// Pagination helps to return UI side with number of pages given a limitStr and pageStr number from Query Parameters
Expand All @@ -61,6 +60,11 @@ type Pagination struct {
TotalPages int `json:"total_pages"`
}

type Record struct {
TotalRecords int `db:"total"`
Product
}

func (product *Product) Validate() (map[string]ErrorResponse, bool) {
var errorResponse map[string]ErrorResponse
var valid bool
Expand Down Expand Up @@ -183,34 +187,26 @@ func (s *pgStore) GetProductByID(ctx context.Context, id int) (Product, error) {
// @Description Get limited number of Products of particular pageStr
// @Params req.Context , limitStr, pageStr
// @Returns Count of Records, error if any
func (s *pgStore) ListProducts(ctx context.Context, limit int, offset int) ([]Product, error) {
func (s *pgStore) ListProducts(ctx context.Context, limit int, offset int) (int, []Product, error) {

var products []Product
var records []Record

result, err := s.db.Queryx(getProductQuery, limit, offset)
err := s.db.Select(&records, getProductQuery, limit, offset)
if err != nil {
logger.WithField("err", err.Error()).Error("Error fetching Products from database")
return []Product{}, err
}
for result.Next() {
var product Product
err = result.StructScan(&product)
if err != nil {
logger.WithField("err", err.Error()).Error("Error scanning Products from database")
return []Product{}, err
}
products = append(products, product)
return 0, []Product{}, err
} else if len(records) == 0 {
err = fmt.Errorf("Either Offset was big or No Records Present in database!")
logger.WithField("err", err.Error()).Error("database Returned total record count as 0")
return 0, []Product{}, err
}
//fmt.Println(products)

if len(products) > 0 && products[0].TotalRecords-1 >= offset {
return products, nil
} else {
err = fmt.Errorf("Page out of Range or No Records Present!")
logger.WithField("err", err.Error()).Error("Error Offset is greater than total records")
return []Product{}, err
for _, record := range records {
products = append(products, record.Product)
}

return records[0].TotalRecords, products, nil
}

func (s *pgStore) CreateProduct(ctx context.Context, product Product, images []*multipart.FileHeader) (Product, error) {
Expand Down
10 changes: 4 additions & 6 deletions service/filters_http.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,12 +174,12 @@ func getProductBySearchHandler(deps Dependencies) http.HandlerFunc {
offsetStr := strconv.Itoa(offset)
if text == "" {
// Behave same as List All Products and return
products, err = deps.Store.ListProducts(req.Context(), limit, offset)
totalRecords, products, err = deps.Store.ListProducts(req.Context(), limit, offset)

if err != nil || products[0].TotalRecords == 0 {
if err != nil {
logger.WithField("err", err.Error()).Error("Error Couldn't find any Product records or Page out of range")
Message := "Couldn't find any Products records or Page out of range"
responseMsg(rw, http.StatusBadRequest, Message)
responseMsg(rw, http.StatusInternalServerError, Message)
return
}
goto Skip
Expand All @@ -191,13 +191,11 @@ func getProductBySearchHandler(deps Dependencies) http.HandlerFunc {
Message := "Couldn't find any matching search records or Page out of range"
responseMsg(rw, http.StatusBadRequest, Message)
return
} else {
products[0].TotalRecords = totalRecords
}

Skip:
var pagination db.Pagination
pagination.TotalPages = int(math.Ceil(float64(products[0].TotalRecords) / float64(limit)))
pagination.TotalPages = int(math.Ceil(float64(totalRecords) / float64(limit)))
pagination.Products = products
response(rw, http.StatusOK, pagination)
return
Expand Down
6 changes: 3 additions & 3 deletions service/product_http.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,17 @@ func listProductsHandler(deps Dependencies) http.HandlerFunc {
return
}
offset := (page - 1) * limit
products, err := deps.Store.ListProducts(req.Context(), limit, offset)
totalRecords, products, err := deps.Store.ListProducts(req.Context(), limit, offset)

if err != nil || products[0].TotalRecords == 0 {
if err != nil {
logger.WithField("err", err.Error()).Error("Error Couldn't find any Product records or Page out of range")
Message := "Couldn't find any Products records or Page out of range"
responseMsg(rw, http.StatusInternalServerError, Message)
return
}

var pagination db.Pagination
pagination.TotalPages = int(math.Ceil(float64(products[0].TotalRecords) / float64(limit)))
pagination.TotalPages = int(math.Ceil(float64(totalRecords) / float64(limit)))
pagination.Products = products
response(rw, http.StatusOK, pagination)
return
Expand Down

0 comments on commit ec8f629

Please sign in to comment.