-
Notifications
You must be signed in to change notification settings - Fork 4
/
user.go
288 lines (217 loc) · 10.2 KB
/
user.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
package repository
import (
"context"
"errors"
"fmt"
"time"
"github.com/nikhilnarayanan623/ecommerce-gin-clean-arch/pkg/api/handler/response"
"github.com/nikhilnarayanan623/ecommerce-gin-clean-arch/pkg/domain"
"github.com/nikhilnarayanan623/ecommerce-gin-clean-arch/pkg/repository/interfaces"
"gorm.io/gorm"
)
type userDatabase struct {
DB *gorm.DB
}
func NewUserRepository(DB *gorm.DB) interfaces.UserRepository {
return &userDatabase{DB: DB}
}
func (c *userDatabase) FindUserByUserID(ctx context.Context, userID uint) (user domain.User, err error) {
query := `SELECT * FROM users WHERE id = $1`
err = c.DB.Raw(query, userID).Scan(&user).Error
return user, err
}
func (c *userDatabase) FindUserByEmail(ctx context.Context, email string) (user domain.User, err error) {
query := `SELECT * FROM users WHERE email = $1`
err = c.DB.Raw(query, email).Scan(&user).Error
return user, err
}
func (c *userDatabase) FindUserByPhoneNumber(ctx context.Context, phoneNumber string) (user domain.User, err error) {
query := `SELECT * FROM users WHERE phone = $1`
err = c.DB.Raw(query, phoneNumber).Scan(&user).Error
return user, err
}
func (c *userDatabase) FindUserByUserName(ctx context.Context, userName string) (user domain.User, err error) {
query := `SELECT * FROM users WHERE user_name = $1`
err = c.DB.Raw(query, userName).Scan(&user).Error
return user, err
}
func (c *userDatabase) FindUserByUserNameEmailOrPhoneNotID(ctx context.Context,
userDetails domain.User) (user domain.User, err error) {
query := `SELECT * FROM users WHERE (user_name = $1 OR email = $2 OR phone = $3) AND id != $4`
err = c.DB.Raw(query, userDetails.UserName, userDetails.Email, userDetails.Phone, userDetails.ID).Scan(&user).Error
return
}
func (c *userDatabase) SaveUser(ctx context.Context, user domain.User) (userID uint, err error) {
//save the user details
query := `INSERT INTO users (user_name, first_name,
last_name, age, email, phone, password, google_image, created_at)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9 ) RETURNING id`
createdAt := time.Now()
err = c.DB.Raw(query, user.UserName, user.FirstName, user.LastName,
user.Age, user.Email, user.Phone, user.Password, user.GoogleImage, createdAt).Scan(&userID).Error
return userID, err
}
func (c *userDatabase) UpdateVerified(ctx context.Context, userID uint) error {
query := `UPDATE users SET verified = 'T' WHERE id = $1`
err := c.DB.Exec(query, userID).Error
return err
}
func (c *userDatabase) UpdateUser(ctx context.Context, user domain.User) (err error) {
updatedAt := time.Now()
// check password need to update or not
if user.Password != "" {
query := `UPDATE users SET user_name = $1, first_name = $2, last_name = $3,age = $4,
email = $5, phone = $6, password = $7, updated_at = $8 WHERE id = $9`
err = c.DB.Exec(query, user.UserName, user.FirstName, user.LastName, user.Age, user.Email,
user.Phone, user.Password, updatedAt, user.ID).Error
} else {
query := `UPDATE users SET user_name = $1, first_name = $2, last_name = $3,age = $4,
email = $5, phone = $6, updated_at = $7 WHERE id = $8`
err = c.DB.Exec(query, user.UserName, user.FirstName, user.LastName, user.Age, user.Email,
user.Phone, updatedAt, user.ID).Error
}
if err != nil {
return fmt.Errorf("filed to update user detail of user with user_id %d", user.ID)
}
return nil
}
func (c *userDatabase) UpdateBlockStatus(ctx context.Context, userID uint, blockStatus bool) error {
query := `UPDATE users SET block_status = $1 WHERE id = $2`
err := c.DB.Exec(query, blockStatus, userID).Error
return err
}
func (c *userDatabase) IsAddressIDExist(ctx context.Context, addressID uint) (exist bool, err error) {
query := `SELECT EXISTS(SELECT 1 FROM addresses WHERE id = $1) AS exist FROM addresses`
err = c.DB.Raw(query, addressID).Scan(&exist).Error
return
}
func (c *userDatabase) FindAddressByID(ctx context.Context, addressID uint) (address response.Address, err error) {
query := `SELECT adrs.id, adrs.house, adrs.name, adrs.phone_number, adrs.area, adrs.land_mark,
adrs.city, adrs.pincode, country_id, country_name FROM addresses adrs
INNER JOIN countries c ON c.id = adrs.country_id
INNER JOIN user_addresses uadrs ON uadrs.address_id = adrs.id
WHERE adrs.id = $1 `
err = c.DB.Raw(query, addressID).Scan(&address).Error
return
}
func (c *userDatabase) IsAddressAlreadyExistForUser(ctx context.Context, address domain.Address, userID uint) (exist bool, err error) {
address.CountryID = 1 // hardcoded !!!! should change
query := `SELECT DISTINCT CASE WHEN adrs.id != 0 THEN 'T' ELSE 'F' END AS exist
FROM addresses adrs
INNER JOIN user_addresses urs ON adrs.id = urs.address_id
WHERE adrs.name = $1 AND adrs.house = $2 AND adrs.land_mark = $3
AND adrs.pincode = $4 AND adrs.country_id = $5 AND urs.user_id = $6`
err = c.DB.Raw(query, address.Name, address.House, address.LandMark, address.Pincode, address.CountryID, userID).Scan(&exist).Error
return
}
func (c *userDatabase) FindAllAddressByUserID(ctx context.Context, userID uint) (addresses []response.Address, err error) {
query := `SELECT a.id, a.house,a.name, a.phone_number, a.area, a.land_mark,a.city,
a.pincode, a.country_id, c.country_name, ua.is_default
FROM user_addresses ua JOIN addresses a ON ua.address_id=a.id
INNER JOIN countries c ON a.country_id=c.id AND ua.user_id = $1`
err = c.DB.Raw(query, userID).Scan(&addresses).Error
return addresses, err
}
func (c *userDatabase) FindCountryByID(ctx context.Context, countryID uint) (domain.Country, error) {
var country domain.Country
if c.DB.Raw("SELECT * FROM countries WHERE id = ?", countryID).Scan(&country).Error != nil {
return country, errors.New("filed to find the country")
}
return country, nil
}
// save address
func (c *userDatabase) SaveAddress(ctx context.Context, address domain.Address) (addressID uint, err error) {
address.CountryID = 1 // hardcoded !!!! should change
query := `INSERT INTO addresses (name, phone_number, house,area, land_mark, city, pincode, country_id, created_at)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING id`
createdAt := time.Now()
if c.DB.Raw(query, address.Name, address.PhoneNumber,
address.House, address.Area, address.LandMark, address.City,
address.Pincode, address.CountryID, createdAt,
).Scan(&address).Error != nil {
return addressID, errors.New("filed to insert address on database")
}
return address.ID, nil
}
// update address
func (c *userDatabase) UpdateAddress(ctx context.Context, address domain.Address) error {
address.CountryID = 1 // hardcoded !!!! should change
query := `UPDATE addresses SET name=$1, phone_number=$2, house=$3, area=$4, land_mark=$5,
city=$6, pincode=$7,country_id=$8, updated_at = $9 WHERE id=$10`
updatedAt := time.Now()
if c.DB.Raw(query, address.Name, address.PhoneNumber, address.House,
address.Area, address.LandMark, address.City, address.Pincode,
address.CountryID, updatedAt, address.ID).Scan(&address).Error != nil {
return errors.New("filed to update the address for edit address")
}
return nil
}
func (c *userDatabase) SaveUserAddress(ctx context.Context, userAddress domain.UserAddress) error {
// first check user's first address is this or not
var userID uint
query := `SELECT address_id FROM user_addresses WHERE user_id = $1`
err := c.DB.Raw(query, userAddress.UserID).Scan(&userID).Error
if err != nil {
return fmt.Errorf("filed to check user have already address exit or not with user_id %v", userAddress.UserID)
}
// if the given address is need to set default then remove all other from default
if userID == 0 { // it means user have no other addresses
userAddress.IsDefault = true
} else if userAddress.IsDefault {
query := `UPDATE user_addresses SET is_default = 'f' WHERE user_id = ?`
if c.DB.Raw(query, userAddress.UserID).Scan(&userAddress).Error != nil {
return errors.New("filed to remove default status of address")
}
}
query = `INSERT INTO user_addresses (user_id,address_id,is_default) VALUES ($1, $2, $3)`
err = c.DB.Exec(query, userAddress.UserID, userAddress.AddressID, userAddress.IsDefault).Error
if err != nil {
return errors.New("filed to insert userAddress on database")
}
return nil
}
func (c *userDatabase) UpdateUserAddress(ctx context.Context, userAddress domain.UserAddress) error {
// if it need to set default the change the old default
if userAddress.IsDefault {
query := `UPDATE user_addresses SET is_default = 'f' WHERE user_id = ?`
if c.DB.Raw(query, userAddress.UserID).Scan(&userAddress).Error != nil {
return errors.New("filed to remove default status of address")
}
}
// update the user address
query := `UPDATE user_addresses SET is_default = ? WHERE address_id=? AND user_id=?`
if c.DB.Raw(query, userAddress.IsDefault, userAddress.AddressID, userAddress.UserID).Scan(&userAddress).Error != nil {
return errors.New("filed to update user address")
}
return nil
}
// wish list
func (c *userDatabase) FindWishListItem(ctx context.Context, productID, userID uint) (domain.WishList, error) {
var wishList domain.WishList
query := `SELECT * FROM wish_lists WHERE user_id=? AND product_item_id=?`
if c.DB.Raw(query, userID, productID).Scan(&wishList).Error != nil {
return wishList, errors.New("filed to find wishlist item")
}
return wishList, nil
}
func (c *userDatabase) FindAllWishListItemsByUserID(ctx context.Context, userID uint) (productItems []response.WishListItem, err error) {
query := `SELECT p.name, wl.id, pi.id AS product_item_id, pi.product_id, pi.price, pi.discount_price,
pi.qty_in_stock, sku FROM wish_lists wl
INNER JOIN product_items pi ON wl.product_item_id = pi.id
INNER JOIN products p ON pi.product_id = p.id
AND wl.user_id = $1`
err = c.DB.Raw(query, userID).Scan(&productItems).Error
return
}
func (c *userDatabase) SaveWishListItem(ctx context.Context, wishList domain.WishList) error {
query := `INSERT INTO wish_lists (user_id,product_item_id) VALUES ($1,$2) RETURNING *`
if c.DB.Raw(query, wishList.UserID, wishList.ProductItemID).Scan(&wishList).Error != nil {
return errors.New("filed to insert new wishlist on database")
}
return nil
}
func (c *userDatabase) RemoveWishListItem(ctx context.Context, userID, productItemID uint) error {
query := `DELETE FROM wish_lists WHERE product_item_id = $1 AND user_id = $2`
err := c.DB.Exec(query, productItemID, userID).Error
return err
}