Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Product api #7

Open
wants to merge 127 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 35 commits
Commits
Show all changes
127 commits
Select commit Hold shift + click to select a range
5e308d4
product api get
RohitNalePUCSD Sep 10, 2020
d48f292
Product Creation API, Get Product By Category API, Delete Product API…
Sep 10, 2020
412d180
product api
RohitNalePUCSD Sep 11, 2020
11b4809
product api
RohitNalePUCSD Sep 11, 2020
807246d
add serial contraint
RohitNalePUCSD Sep 11, 2020
43de867
add insert migration file
RohitNalePUCSD Sep 11, 2020
fcf79b2
add change table variable
RohitNalePUCSD Sep 11, 2020
154ed77
Product's json tag names are changed as per UI side request. Migratio…
Sep 11, 2020
84b6a9c
add assets new images
RohitNalePUCSD Sep 11, 2020
737fbc9
createProduct function update change
RohitNalePUCSD Sep 11, 2020
1d2b55d
Brand, Color, Size added in product struct. Products Table migration …
Sep 11, 2020
d81f72f
paginations
RohitNalePUCSD Sep 12, 2020
fe6530d
Merge branch 'product_api' of https://github.com/joshsoftware/go-e-co…
RohitNalePUCSD Sep 12, 2020
aa31335
add paginations
RohitNalePUCSD Sep 12, 2020
0230648
Total Pages are also sent as response.Filters of categoryId, brand, s…
Sep 12, 2020
1af2b3a
Pagination for Product filter API added. getProductsBy CategoryId API…
Sep 12, 2020
b2bc045
error handle
RohitNalePUCSD Sep 12, 2020
315d9a8
update filter file
RohitNalePUCSD Sep 14, 2020
7348dd8
SQL Injection Attack are handled for product filters, using Regular E…
Sep 14, 2020
57ef73e
setup test case file
RohitNalePUCSD Sep 14, 2020
5a9e6c7
Merge branch 'product_api' of https://github.com/joshsoftware/go-e-co…
RohitNalePUCSD Sep 14, 2020
cfd9b57
Tax field added in Products. Migration of products changed for it. Al…
Sep 15, 2020
c037f05
add product_http_test cases
RohitNalePUCSD Sep 15, 2020
934d310
add product_http_test cases
RohitNalePUCSD Sep 15, 2020
66dbd00
add filter_http_test cases
RohitNalePUCSD Sep 15, 2020
a440959
Search By some pattern API added. Testing of filters added.
Sep 15, 2020
94f7ae5
add search handler
RohitNalePUCSD Sep 16, 2020
30d53d2
add search function handler
RohitNalePUCSD Sep 16, 2020
d592721
Search API for product has been modified, duplicate keywords handled…
Sep 16, 2020
8ca802e
Changed contents of .gitignore
Sep 16, 2020
c7b8b95
update search function
RohitNalePUCSD Sep 16, 2020
31ad133
Changes made in Search Product By text API, only fields on which user…
Sep 16, 2020
0285299
update search function
RohitNalePUCSD Sep 16, 2020
c8baf4b
Merge branch 'product_api' of https://github.com/joshsoftware/go-e-co…
RohitNalePUCSD Sep 16, 2020
397ef51
add new test case
RohitNalePUCSD Sep 16, 2020
2a8d0ba
Redundant code eliminated. Test Cases have been checked for equal exp…
Sep 17, 2020
a8e661b
Added API for Product Updation.
Sep 17, 2020
eb75d97
update create product handler
RohitNalePUCSD Sep 17, 2020
2f5faf0
change migration file
RohitNalePUCSD Sep 17, 2020
d9c220c
Removed Product Images Table. Storing ProductImages as an Array in Pr…
Sep 17, 2020
a9cdad9
change MR
RohitNalePUCSD Sep 17, 2020
5be5e77
Remove URL's scanning with for loop logic.
Sep 18, 2020
0b94cf1
migration change
RohitNalePUCSD Sep 18, 2020
406005f
Merge branch 'product_api' of https://github.com/joshsoftware/go-e-co…
RohitNalePUCSD Sep 18, 2020
46767ab
add new test case and delete product_image.go
RohitNalePUCSD Sep 18, 2020
22714ac
Removed Unnecessary Comments. Offset Calculation done in Program itse…
Sep 18, 2020
9362c17
Solved Merge Conflicts
Sep 18, 2020
bea4477
change MR
RohitNalePUCSD Sep 18, 2020
0494b8a
calculat offset and update handler function
RohitNalePUCSD Sep 18, 2020
99f3d8b
remove retrun by name in function
RohitNalePUCSD Sep 18, 2020
55fae1d
Reduced DB Calls in CreateProduct, updateStock, updateProduct. Rename…
Sep 18, 2020
7e50ce1
Defaults in Products migrations is changed. ListProducts now take lim…
Sep 18, 2020
e0cee44
update changes as per requird
RohitNalePUCSD Sep 18, 2020
dcb64e2
Added comments so that code will not panic when db isn't present.This…
Sep 20, 2020
41d5e84
Category table's id renamed to cid, name renamed to cname. Product ta…
Sep 20, 2020
90bab4e
HTTP Test cases are all made running.
Sep 20, 2020
31450ba
add new changes
RohitNalePUCSD Sep 21, 2020
c7c240d
add update code
RohitNalePUCSD Sep 24, 2020
be181f9
User can also add image when creating Product. gorilla's schema libra…
Sep 24, 2020
f8e7738
add update code
RohitNalePUCSD Sep 25, 2020
1c63b46
update api chnages add images in form value
RohitNalePUCSD Sep 25, 2020
13436c2
Added count- 1 > offset logic to avoid getting out of range pages as …
Sep 25, 2020
91d9238
Product Count Query Start made as one.
Sep 25, 2020
617261a
add delete images in update products
RohitNalePUCSD Sep 25, 2020
b9015e8
Merge branch 'product_api' of https://github.com/joshsoftware/go-e-co…
RohitNalePUCSD Sep 25, 2020
69c1fd9
add delete images function in update products api
RohitNalePUCSD Sep 25, 2020
4dd7881
Images moved to assets/productImages folder. Transactions removed in …
Sep 25, 2020
8ecb672
Images were renamed for proper insertions. Image insertion and updati…
Sep 25, 2020
7152444
Unnecessary images removed. product.
Sep 25, 2020
318e076
Just a change in migrations.sql
Sep 25, 2020
58bb9e5
We are also deleting images of Products whenever product is deleted.
Sep 25, 2020
b27f0ff
add delete images function and display create product data
RohitNalePUCSD Sep 26, 2020
5485466
Color and Size are just string than pointer to string. Their default …
Sep 26, 2020
d9227f5
add createproduct api in multiformvalue run test case
RohitNalePUCSD Sep 30, 2020
130d8bd
CreateProduct Test modified to work with mock request than real request.
Sep 30, 2020
d14af6a
add createproduct api
RohitNalePUCSD Sep 30, 2020
654684b
Update Product Failure Test Cases added along with Validation Failure…
Sep 30, 2020
d39968f
update product_test createProduct using mockdb
RohitNalePUCSD Sep 30, 2020
81dbe41
update product_test updateProductSuccess add test case
RohitNalePUCSD Sep 30, 2020
a4050b9
update product_http listProduct handler remove scan total count
RohitNalePUCSD Oct 1, 2020
ad96960
NaN's are handeled in all floating variable fields by Validate Method.
Oct 1, 2020
eacf607
check api
RohitNalePUCSD Oct 1, 2020
f808e22
Merge branch 'product_api' of https://github.com/joshsoftware/go-e-co…
RohitNalePUCSD Oct 1, 2020
8b5b630
remove print methods
RohitNalePUCSD Oct 1, 2020
8ecb804
Added Logic for Fetching Category Name in insert Query itself.
Oct 1, 2020
5860ba0
Merge branch 'product_api' of https://github.com/joshsoftware/go-e-co…
RohitNalePUCSD Oct 1, 2020
494a5cd
updateProductQuery changed from normal Exec to NamedQuery. Also Categ…
Oct 2, 2020
0ef02e9
Merge branch 'product_api' of https://github.com/joshsoftware/go-e-co…
RohitNalePUCSD Oct 5, 2020
06a84d4
add CHECK constraint and change test cases
RohitNalePUCSD Oct 5, 2020
849692f
Fine Grained the CHECK constraints. Deleted Wrangler and Poloshirt im…
Oct 6, 2020
d99da87
add Full URL of images and add statusConflict already exists product
RohitNalePUCSD Oct 6, 2020
3c9dff1
change migration
RohitNalePUCSD Oct 6, 2020
a7f4bee
Migration.sql's names chnaged along with solving merge conflicts.
Oct 6, 2020
13943e2
StatusConflict Code Added as per UI Side's Request.
Oct 6, 2020
2256b47
change migration
RohitNalePUCSD Oct 6, 2020
4ed8442
Merge branch 'product_api' of https://github.com/joshsoftware/go-e-co…
RohitNalePUCSD Oct 6, 2020
12faee9
Message Responses are made clear and to point.
Oct 6, 2020
62a4aa1
change migration
RohitNalePUCSD Oct 6, 2020
4557500
Merge branch 'product_api' of https://github.com/joshsoftware/go-e-co…
RohitNalePUCSD Oct 6, 2020
c4f7a8d
Test Cases for Update API are Updated.
Oct 6, 2020
97337be
remove switch case use default case
RohitNalePUCSD Oct 6, 2020
a18cbb7
Merge branch 'product_api' of github.com:joshsoftware/go-e-commerce i…
Oct 6, 2020
365a7ac
remove switch case use default case
RohitNalePUCSD Oct 6, 2020
aa31dd8
Blanks are handled for image url creation. If image isn't sent with f…
Oct 6, 2020
e667782
remove extra database call in UpdateProductStockById
RohitNalePUCSD Oct 7, 2020
6e975a4
Response messages are made more specific. In UpdateProductById Method…
Oct 7, 2020
eb7518c
remove redundant code in response msg
RohitNalePUCSD Oct 8, 2020
ad25b13
remove redundant code in response msg
RohitNalePUCSD Oct 9, 2020
72f8370
List Products DB calls reduced. TotalRecords variable added to Produc…
Oct 9, 2020
6ba69a2
Merge branch 'product_api' of https://github.com/joshsoftware/go-e-co…
RohitNalePUCSD Oct 9, 2020
ec8f629
Added new structure by name Records for holding totalRecords. Deleted…
Oct 9, 2020
357d499
Merge branch 'product_api' of https://github.com/joshsoftware/go-e-co…
RohitNalePUCSD Oct 9, 2020
0348281
Filter Product API is now only 1 database call!
Oct 9, 2020
fcd75ee
Merge branch 'product_api' of https://github.com/joshsoftware/go-e-co…
RohitNalePUCSD Oct 9, 2020
bc4427b
optimize database call in SearchProducts API
RohitNalePUCSD Oct 9, 2020
2e83ce2
Variable name change from isFiltered to searchQuery in Search Impleme…
Oct 9, 2020
e546f6c
Delete Product has QueryRowx instead of Queryx, this makes Scan possi…
Oct 9, 2020
e987b80
README.md Updated with Proper instructions.
Oct 9, 2020
ff5827c
Documentation added in docs folder.
Oct 9, 2020
1cca0b1
Test Cases updated to Run properly.
Oct 9, 2020
bbf93a4
Records type added. Products() Method is added to Records. This Metho…
Oct 9, 2020
9ff7ad3
Added TODOs which are capabilities and security issues.These are supp…
Oct 14, 2020
6e5683e
add new statusConflict in createProduct is product already exsits
RohitNalePUCSD Oct 16, 2020
eae3c48
add new validation conditions
RohitNalePUCSD Oct 16, 2020
1a33c88
Stored XSS attack is handeled in updateProduct and createProduct Hand…
Oct 16, 2020
47d9422
update test case conditions in product api
RohitNalePUCSD Oct 16, 2020
ade9366
Dockerfile added. README has instructions for image pulling directly …
Oct 31, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added assets/Android LED TV1.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/Android LED TV2.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/Android LED TV3.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/Apple iPhone 11 Pro1.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/Apple iPhone 11 Pro2.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/Apple iPhone 11 Pro3.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/Apple iPhone 11 Promax1.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/Apple iPhone 11 Promax2.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/Apple iPhone 11 Promax3.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/Apple iPhone XR1.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/Apple iPhone XR2.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/Apple iPhone XR3.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/Charger1.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/Charger2.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/Charger3.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/Dragon Jacket1.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/Dragon Jacket2.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/Dragon Jacket3.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/Football1.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/Football2.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/Football3.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/Football4.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/Football5.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/Football6.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/Mens Running Shoes1.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/Mens Running Shoes2.jpeg
Binary file added assets/Mens Running Shoes3.jpeg
Binary file added assets/Relax Watch1.jpeg
Binary file added assets/Relax Watch2.jpeg
Binary file added assets/Relax Watch3.jpeg
Binary file added assets/SonataWatch1.jpeg
Binary file added assets/SonataWatch2.jpeg
Binary file added assets/SonataWatch3.jpeg
Binary file added assets/Sony DSC1.jpeg
Binary file added assets/Sony DSC2.jpeg
Binary file added assets/Sony DSC3.jpeg
Binary file added assets/Titan Watch1.jpeg
Binary file added assets/Titan Watch2.jpeg
Binary file added assets/Titan Watch3.jpeg
Binary file added assets/Wings of Fire1.jpeg
Binary file added assets/Wings of Fire2.jpeg
Binary file added assets/Wrangler1.jpeg
Binary file added assets/Wrangler2.jpeg
Binary file added assets/Wrangler3.jpeg
Binary file added assets/poloshirt2.jpeg
Binary file added assets/poloshirt3.jpeg
Binary file added assets/poloshit1.jpeg
Binary file added assets/vivkananadbook1.jpeg
Binary file added assets/vivkananadbook2.jpeg
8 changes: 8 additions & 0 deletions db/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package db

// ErrorResponse - a struct representing a response for an error

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

struct name itself suggest its purpose here, so we can avoid putting comment
same follow at other places in code

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed unnecessary comments.

type ErrorResponse struct {
Code string `json:"code"`
Message string `json:"message"`
Fields map[string]string `json:"fields"`
}
36 changes: 36 additions & 0 deletions db/common_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package db

import (
"testing"
"time"

"github.com/DATA-DOG/go-sqlmock"
"github.com/jmoiron/sqlx"
logger "github.com/sirupsen/logrus"
"github.com/stretchr/testify/suite"
)

var (
now time.Time
mockedRows *sqlmock.Rows
)

func InitMockDB() (s Storer, sqlConn *sqlx.DB, sqlmockInstance sqlmock.Sqlmock) {
mockDB, sqlmock, err := sqlmock.New()
if err != nil {
logger.WithField("err:", err).Error("error initializing mock db")
return
}

sqlmockInstance = sqlmock
sqlxDB := sqlx.NewDb(mockDB, "sqlmock")

var pgStoreConn pgStore
pgStoreConn.db = sqlxDB

return &pgStoreConn, sqlxDB, sqlmockInstance
}

func TestExampleTestSuite(t *testing.T) {
suite.Run(t, new(ProductTestSuite))
}
12 changes: 8 additions & 4 deletions db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@ import (
)

type Storer interface {
ListUsers(context.Context) ([]User, error)
//Create(context.Context, User) error
//GetUser(context.Context) (User, error)
//Delete(context.Context, string) error
ListProducts(context.Context, string, string) (int, []Product, error)
FilteredProducts(context.Context, Filter, string, string) (int, []Product, error)
SearchRecords(context.Context, string, string, string) (int, []Product, error)
CreateNewProduct(context.Context, Product) (Product, error)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can rename it to CreateProduct

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done change

DeleteProductById(context.Context, int) error
UpdateProductStockById(context.Context, Product, int) (Product, error)
GetProductImagesByID(context.Context, int) ([]ProductImage, error)
GetProductByID(context.Context, int) (Product, error)
}
296 changes: 296 additions & 0 deletions db/filters.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,296 @@
package db

import (
"context"
"fmt"
"regexp"
"strconv"
"strings"

logger "github.com/sirupsen/logrus"
)

// Filter struct is used to help us in Generating a dynamic Filter Query
type Filter struct {
// Below fields are what we may receive as Parameters in request body
CategoryId string
Price string
Brand string
Size string
Color string
// These Flags will help us format our query, true means that field exists in Request Parameters
CategoryFlag bool
PriceFlag bool
BrandFlag bool
SizeFlag bool
ColorFlag bool
}

// @Title FilteredProducts
// @Description Get the products that are filtered as per request Parameters
// @Accept request.Context, Filter struct's object
// @Success total= (count of filtered products), error=nil
// @Failure total=0, error= "Some Error"
func (s *pgStore) FilteredProducts(ctx context.Context, filter Filter, limit string, page string) (count int, products []Product, err error) {
// We will be checking for SQL Injection as well in this Method only
// found flag will help us find out if any of Filter flags were true
var found bool
// helper will be used in making query dynamic.
// See how it's getting concatanation added in case a flag was Filter Flag is true
injection := ` `
helper := ` `
if filter.CategoryFlag == true {
helper += ` category_id = ` + filter.CategoryId + ` AND`
injection += filter.CategoryId
found = true
}
if filter.BrandFlag == true {
// Since ' existed, we had to use ` instead of " , as compiler gave error otherwise
helper += ` LOWER(brand) = LOWER('` + filter.Brand + `') AND`
injection += filter.Brand
found = true
}
if filter.SizeFlag == true {
// Since ' existed, we had to use ` instead of " , as compiler gave error otherwise
helper += ` LOWER(size) = LOWER('` + filter.Size + `') AND`
injection += filter.Size
found = true
}
if filter.ColorFlag == true {
// Since ' existed, we had to use ` instead of " , as compiler gave error otherwise
helper += ` LOWER(color) =LOWER('` + filter.Color + `') AND`
injection += filter.Color
found = true
}
if found == true {
// check for SQL Injection
// Only allow words characters like [a-z0-9A-Z] and a space [ ]
var validParameters = regexp.MustCompile(`^[\w ]+$`)
// if There are other chracters than word and space
if validParameters.MatchString(injection) == false {
err = fmt.Errorf("Possible SQL Injection Attack.")
logger.WithField("err", err.Error()).Error("Error In Parameters, special Characters are present.")
return
}
// remove that last AND as it will make query invalid
helper = ` WHERE ` + helper[:len(helper)-3]
}

getFilterProductCount := `SELECT COUNT(id) FROM products ` + helper + `;`
fmt.Println("getFilterProductCount---->", getFilterProductCount)

resultCount, err := s.db.Query(getFilterProductCount)
if err != nil {
logger.WithField("err", err.Error()).Error("Error getting Count of Filtered Products from database")
return
}

// resultCount set should have only 1 record
for resultCount.Next() {
err = resultCount.Scan(&count)
if err != nil {
logger.WithField("err", err.Error()).Error("Error fetching count of getFilterProductCount from database")
return
}
break
}

fmt.Println(count)

if count == 0 {
err = fmt.Errorf("No records present")
logger.WithField("err", err.Error()).Error("No records were in db for Products")
return
}

// error already handled in filters_http
ls, _ := strconv.Atoi(limit)
ps, _ := strconv.Atoi(page)

if (count - 1) < (int(ls) * (int(ps) - 1)) {
err = fmt.Errorf("Desired Page not found")
logger.WithField("err", err.Error()).Error("Page Out Of range")
return
}

getFilterProduct := `SELECT id from Products` + helper

if filter.PriceFlag == true {
getFilterProduct += ` ORDER BY price ` + filter.Price
}

//fmt.Println(limit, page)
getFilterProduct += ` LIMIT ` + limit + ` OFFSET (` + page + ` -1) * ` + limit + ` ;`
fmt.Println("getFilterProduct---->", getFilterProduct)

result, err := s.db.Query(getFilterProduct)
if err != nil {
logger.WithField("err", err.Error()).Error("Error fetching Product Ids from database")
return
}

// idArr stores id's of all products
var idArr []int

for result.Next() {
var Id int
err = result.Scan(&Id)
if err != nil {
logger.WithField("err", err.Error()).Error("Couldn't Scan Resulted Product Ids into Id variable")
return
}
idArr = append(idArr, Id)
}

// get All Filtered Products by their ids
for i := 0; i < len(idArr); i++ {
var product Product
product, err = s.GetProductByID(ctx, int(idArr[i]))
if err != nil {
logger.WithField("err", err.Error()).Error("Error selecting Product from database by id " + string(idArr[i]))
return
}
products = append(products, product)
}

return

}

// @Title SearchRecords
// @Description Get records that are searched as per request Parameter "text" along with count
// @Accept request.Context, text as string, limit, page
// @Success total= (count of search qualifying records), error=nil
// @Failure total=0, error= "Some Error"
func (s *pgStore) SearchRecords(ctx context.Context, text string, limit string, page string) (count int, products []Product, err error) {
// check for SQL Injection
// Only allow words characters like [a-z0-9A-Z] and a space [ ]
var validParameters = regexp.MustCompile(`^[\w ]+$`)
// if There are other chracters than word and space
if validParameters.MatchString(text) == false {
err = fmt.Errorf("Possible SQL Injection Attack.")
logger.WithField("err", err.Error()).Error("Error In Parameters, special Characters are present.")
return
}

// Split the text into slice of strings, max 10 first words will be considered
textSlice := strings.SplitN(text, " ", 11)

// If there are more than 10 words in search, ask user to be less verbose
if len(textSlice) > 10 {
err = fmt.Errorf("Unnecessary detailed text given.")
logger.WithField("err", err.Error()).Error("Error In Parameters, very detailed!.")
return
}

// Removing Duplicate words from textSlice
textMap := make(map[string]bool, 10)
for i := 0; i < len(textSlice); i++ {
textMap[textSlice[i]] = true
}

// Query to help us get count of all such results
getSearchCount := `SELECT COUNT(p.id) from products p
INNER JOIN category c
ON p.category_id = c.id
WHERE
`

helper := ` `

// iterate over all the textMap
for key, _ := range textMap {
helper += `
LOWER(p.name) LIKE LOWER('%` + key + `%') OR
LOWER(p.brand) LIKE LOWER('%` + key + `%') OR
LOWER(c.name) LIKE LOWER('%` + key + `%') OR`
}

// remove that last OR
helper = helper[:len(helper)-2]

getSearchCount += helper + ` ;`
countResult, err := s.db.Query(getSearchCount)

if err != nil {
logger.WithField("err", err.Error()).Error("Error fetching count of getSearchCount from database")
return
}

// countResult set should have only 1 record
// It counts the number of records with the search results.
for countResult.Next() {
err = countResult.Scan(&count)
if err != nil {
logger.WithField("err", err.Error()).Error("Error fetching count of getSearchCount from database")
return
}
break
}

fmt.Println(count)

if count == 0 {
err = fmt.Errorf("No records present")
logger.WithField("err", err.Error()).Error("No records were present for that search keyword")
return
}

// error already handled in filters_http
ls, _ := strconv.Atoi(limit)
ps, _ := strconv.Atoi(page)

if (count - 1) < (int(ls) * (int(ps) - 1)) {
err = fmt.Errorf("Desired Page not found")
logger.WithField("err", err.Error()).Error("Page Out Of range")
return
}

// Query to return Id's of Products where we may find a match in
// product's name, description, brand, size, color or in
// the category of that products category's name or description
getSearchRecordIds := `SELECT p.id from products p
INNER JOIN category c
ON p.category_id = c.id
WHERE
`

getSearchRecordIds += helper

getSearchRecordIds += ` LIMIT ` + limit + ` OFFSET ( ` + page + ` -1) * ` + limit + ` ;`

fmt.Println("getSearchRecordIds---->", getSearchRecordIds)

result, err := s.db.Query(getSearchRecordIds)
if err != nil {
logger.WithField("err", err.Error()).Error("Error fetching Product Results from database")
return
}

// idArr stores id's of all products
var idArr []int

for result.Next() {
var Id int
err = result.Scan(&Id)
if err != nil {
logger.WithField("err", err.Error()).Error("Couldn't Scan Resulted Product Ids into Id variable")
return
}
idArr = append(idArr, Id)
}

// get All Filtered Products by their ids
for i := 0; i < len(idArr); i++ {
var product Product
product, err = s.GetProductByID(ctx, int(idArr[i]))
if err != nil {
logger.WithField("err", err.Error()).Error("Error selecting Product from database by id " + string(idArr[i]))
return
}
products = append(products, product)
}

return

}
27 changes: 27 additions & 0 deletions db/filters_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package db

import (
"github.com/DATA-DOG/go-sqlmock"
"github.com/jmoiron/sqlx"
"github.com/stretchr/testify/suite"
)

// Needs to be implemented using https://github.com/DATA-DOG/go-sqlmock

type ProductTestSuite struct {
suite.Suite
dbStore Storer
db *sqlx.DB
sqlmock sqlmock.Sqlmock
}

func (suite *ProductTestSuite) SetupTest() {
dbStore, dbConn, sqlmock := InitMockDB()
suite.dbStore = dbStore
suite.db = dbConn
suite.sqlmock = sqlmock
}

func (suite *ProductTestSuite) TearDownTest() {
suite.db.Close()
}
Loading