switched to gorm..
This commit is contained in:
@@ -1,12 +1,14 @@
|
||||
package repositories
|
||||
|
||||
import (
|
||||
"GoMembership/internal/constants"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
|
||||
"GoMembership/internal/models"
|
||||
"GoMembership/pkg/errors"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
type UserRepository interface {
|
||||
@@ -19,63 +21,32 @@ type UserRepository interface {
|
||||
}
|
||||
|
||||
type userRepository struct {
|
||||
db *sql.DB
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func NewUserRepository(db *sql.DB) UserRepository {
|
||||
func NewUserRepository(db *gorm.DB) UserRepository {
|
||||
return &userRepository{db}
|
||||
}
|
||||
|
||||
func (repo *userRepository) CreateUser(user *models.User) (int64, error) {
|
||||
query := "INSERT INTO users (first_name, last_name, email, phone, drivers_id_checked, role_id, payment_status, date_of_birth, address, profile_picture, notes, status, password, salt, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
|
||||
result, err := repo.db.Exec(query,
|
||||
user.FirstName,
|
||||
user.LastName,
|
||||
user.Email,
|
||||
user.Phone,
|
||||
user.DriversIDChecked,
|
||||
user.RoleID,
|
||||
user.PaymentStatus,
|
||||
user.DateOfBirth,
|
||||
user.Address,
|
||||
user.ProfilePicture,
|
||||
user.Notes,
|
||||
user.Status,
|
||||
user.Password,
|
||||
user.Salt,
|
||||
user.CreatedAt,
|
||||
user.UpdatedAt)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
result := repo.db.Create(user)
|
||||
if result.Error != nil {
|
||||
return 0, result.Error
|
||||
}
|
||||
|
||||
lastInsertID, err := result.LastInsertId()
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
return lastInsertID, err
|
||||
return user.ID, nil
|
||||
}
|
||||
|
||||
func (repo *userRepository) UpdateUser(userID int64, updates map[string]interface{}) error {
|
||||
if len(updates) == 0 {
|
||||
return errors.ErrNoData
|
||||
}
|
||||
|
||||
// Construct the query
|
||||
setClauses := make([]string, 0, len(updates))
|
||||
args := make([]interface{}, 0, len(updates)+1)
|
||||
for column, value := range updates {
|
||||
setClauses = append(setClauses, fmt.Sprintf("%s = ?", column))
|
||||
args = append(args, value)
|
||||
result := repo.db.Session(&gorm.Session{FullSaveAssociations: true}).Model(&models.User{}).Where("id = ?", userID).Updates(&updates)
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
args = append(args, userID)
|
||||
|
||||
query := fmt.Sprintf("UPDATE users SET %s WHERE id = ?", strings.Join(setClauses, ", "))
|
||||
|
||||
// Execute the query
|
||||
_, err := repo.db.Exec(query, args...)
|
||||
if err != nil {
|
||||
return err
|
||||
if result.RowsAffected == 0 {
|
||||
return errors.ErrNoRowsAffected
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -83,88 +54,76 @@ func (repo *userRepository) UpdateUser(userID int64, updates map[string]interfac
|
||||
|
||||
func (repo *userRepository) FindUserByID(id int64) (*models.User, error) {
|
||||
var user models.User
|
||||
query := "SELECT id, first_name, last_name, email, phone, drivers_id_checked, role_id, payment_status, date_of_birth, address, profile_picture, notes, status FROM users WHERE id = ?"
|
||||
err := repo.db.QueryRow(query, id).Scan(&user.ID,
|
||||
&user.FirstName,
|
||||
&user.LastName,
|
||||
&user.Email,
|
||||
&user.Phone,
|
||||
&user.DriversIDChecked,
|
||||
&user.RoleID,
|
||||
&user.PaymentStatus,
|
||||
&user.DateOfBirth,
|
||||
&user.Address,
|
||||
&user.ProfilePicture,
|
||||
&user.Notes,
|
||||
&user.Status)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, errors.ErrUserNotFound
|
||||
result := repo.db.First(&user, id)
|
||||
if result.Error != nil {
|
||||
if result.Error == gorm.ErrRecordNotFound {
|
||||
return nil, gorm.ErrRecordNotFound
|
||||
}
|
||||
return nil, err
|
||||
return nil, result.Error
|
||||
}
|
||||
return &user, nil
|
||||
}
|
||||
|
||||
func (repo *userRepository) FindUserByEmail(email string) (*models.User, error) {
|
||||
var user models.User
|
||||
query := "SELECT id, first_name, last_name, email FROM users WHERE email = ?"
|
||||
err := repo.db.QueryRow(query, email).Scan(&user.ID, &user.FirstName, &user.LastName, &user.Email)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, errors.ErrUserNotFound
|
||||
result := repo.db.Where("email = ?", email).First(&user)
|
||||
if result.Error != nil {
|
||||
if result.Error == gorm.ErrRecordNotFound {
|
||||
return nil, gorm.ErrRecordNotFound
|
||||
}
|
||||
return nil, err
|
||||
return nil, result.Error
|
||||
}
|
||||
return &user, nil
|
||||
}
|
||||
|
||||
func (repo *userRepository) IsVerified(userID *int64) (bool, error) {
|
||||
var status string
|
||||
query := "SELECT status FROM users where id = ?"
|
||||
err := repo.db.QueryRow(query, userID).Scan(&status)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return false, errors.ErrUserNotFound
|
||||
var user models.User
|
||||
result := repo.db.Select("status").First(&user, userID)
|
||||
if result.Error != nil {
|
||||
if result.Error == gorm.ErrRecordNotFound {
|
||||
return false, gorm.ErrRecordNotFound
|
||||
}
|
||||
return false, err
|
||||
return false, result.Error
|
||||
}
|
||||
return status != "unverified", nil
|
||||
return user.Status != constants.UnverifiedStatus, nil
|
||||
}
|
||||
|
||||
func (repo *userRepository) VerifyUserOfToken(token *string) (int64, error) {
|
||||
var userID int64
|
||||
err := repo.db.QueryRow("SELECT user_id FROM email_verifications WHERE verification_token = $1", token).Scan(&userID)
|
||||
if err == sql.ErrNoRows {
|
||||
return -1, errors.ErrTokenNotFound
|
||||
} else if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
verified, err := repo.IsVerified(&userID)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
if verified {
|
||||
return userID, errors.ErrAlreadyVerified
|
||||
}
|
||||
update := map[string]interface{}{
|
||||
"status": "active",
|
||||
var emailVerification models.Verification
|
||||
result := repo.db.Where("verification_token = ?", token).First(&emailVerification)
|
||||
if result.Error != nil {
|
||||
if result.Error == gorm.ErrRecordNotFound {
|
||||
return 0, gorm.ErrRecordNotFound
|
||||
}
|
||||
return 0, result.Error
|
||||
}
|
||||
|
||||
err = repo.UpdateUser(userID, update)
|
||||
// Check if the user is already verified
|
||||
verified, err := repo.IsVerified(&emailVerification.UserID)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
return 0, err
|
||||
}
|
||||
query := "UPDATE email_verifications SET verified_at = ? WHERE user_id = ?"
|
||||
_, err = repo.db.Exec(query, time.Now(), userID)
|
||||
if verified {
|
||||
return emailVerification.UserID, gorm.ErrRecordNotFound
|
||||
}
|
||||
|
||||
// Update user status to active
|
||||
t := time.Now()
|
||||
emailVerification.EmailVerifiedAt = &t
|
||||
update := map[string]interface{}{
|
||||
"status": constants.VerifiedStatus,
|
||||
"verifications": emailVerification,
|
||||
}
|
||||
err = repo.UpdateUser(emailVerification.UserID, update)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
return 0, err
|
||||
}
|
||||
return userID, nil
|
||||
|
||||
return emailVerification.UserID, nil
|
||||
}
|
||||
|
||||
func (repo *userRepository) SetVerificationToken(user *models.User, token *string) (int64, error) {
|
||||
// check if user already verified
|
||||
// Check if user is already verified
|
||||
verified, err := repo.IsVerified(&user.ID)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
@@ -173,15 +132,21 @@ func (repo *userRepository) SetVerificationToken(user *models.User, token *strin
|
||||
return -1, errors.ErrAlreadyVerified
|
||||
}
|
||||
|
||||
query := "INSERT OR REPLACE INTO email_verifications (user_id, verification_token, created_at) VALUES (?, ?, ?)"
|
||||
result, err := repo.db.Exec(query, user.ID, token, time.Now())
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
lastInsertID, err := result.LastInsertId()
|
||||
if err != nil {
|
||||
return -1, err
|
||||
// Prepare the Verification record
|
||||
verification := models.Verification{
|
||||
UserID: user.ID,
|
||||
VerificationToken: *token,
|
||||
}
|
||||
|
||||
return lastInsertID, nil
|
||||
// Use GORM to insert or update the Verification record
|
||||
result := repo.db.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "user_id"}},
|
||||
DoUpdates: clause.AssignmentColumns([]string{"verification_token", "created_at"}),
|
||||
}).Create(&verification)
|
||||
|
||||
if result.Error != nil {
|
||||
return -1, result.Error
|
||||
}
|
||||
|
||||
return verification.ID, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user