Skip to content

Instantly share code, notes, and snippets.

@shyamvlmna
Created August 14, 2022 21:45
Show Gist options
  • Save shyamvlmna/d85344d4cc4c7ccd7db11afb287da31b to your computer and use it in GitHub Desktop.
Save shyamvlmna/d85344d4cc4c7ccd7db11afb287da31b to your computer and use it in GitHub Desktop.
definition and methods for a user model using golang and postgresql with validation
package models
import (
"errors"
"html"
"log"
"strings"
"time"
validator "github.com/asaskevich/govalidator"
"golang.org/x/crypto/bcrypt"
"gorm.io/gorm"
)
type User struct {
gorm.Model
ID uint32 `gorm:"primary_key;auto_increment" json:"id"`
Name string `gorm:"size:255;not null;unique" json:"nickname"`
Email string `gorm:"size:100;not null;unique" json:"email"`
Password string `gorm:"size:100;not null;" json:"password"`
}
func Hash(password string) ([]byte, error) {
return bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
}
func VerifyPassword(hashedPassword, password string) error {
return bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(password))
}
func (u *User) BeforeSave() error {
hashedPassword, err := Hash(u.Password)
if err != nil {
return err
}
u.Password = string(hashedPassword)
return nil
}
func (u *User) Prepare() {
u.ID = 0
u.Name = html.EscapeString(strings.TrimSpace(u.Name))
u.Email = html.EscapeString(strings.TrimSpace(u.Email))
u.CreatedAt = time.Now()
u.UpdatedAt = time.Now()
}
func (u *User) Validate(action string) error {
switch strings.ToLower(action) {
case "update":
if u.Name == "" {
return errors.New("required nickname")
}
if u.Password == "" {
return errors.New("required password")
}
if u.Email == "" {
return errors.New("required email")
}
if !validator.IsExistingEmail(u.Email) {
return errors.New("invalid email")
}
return nil
case "login":
if u.Password == "" {
return errors.New("required password")
}
if u.Email == "" {
return errors.New("required email")
}
if !validator.IsExistingEmail(u.Email) {
return errors.New("invalid email")
}
return nil
default:
if u.Name == "" {
return errors.New("required nickname")
}
if u.Password == "" {
return errors.New("required password")
}
if u.Email == "" {
return errors.New("required email")
}
if !validator.IsExistingEmail(u.Email) {
return errors.New("invalid email")
}
return nil
}
}
func (u *User) SaveUser(db *gorm.DB) (*User, error) {
err := db.Debug().Create(&u).Error
if err != nil {
return &User{}, err
}
return u, nil
}
func (u *User) FindAllUsers(db *gorm.DB) (*[]User, error) {
users := []User{}
err := db.Debug().Model(&User{}).Limit(100).Find(&users).Error
if err != nil {
return &[]User{}, err
}
return &users, err
}
func (u *User) FindUserByID(db *gorm.DB, uid uint32) (*User, error) {
err := db.Debug().Model(&User{}).Where("id = ?", uid).Take(&u).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
return &User{}, errors.New("user not found")
}
return &User{}, err
}
return u, err
}
func (u *User) UpdateUser(db *gorm.DB, uid uint32) (*User, error) {
// To hash the password
err := u.BeforeSave()
if err != nil {
log.Fatal(err)
}
db = db.Debug().Model(&User{}).Where("id = ?", uid).Take(&User{}).UpdateColumns(
map[string]interface{}{
"password": u.Password,
"nickname": u.Name,
"email": u.Email,
"updated_at": time.Now(),
},
)
if db.Error != nil {
return &User{}, db.Error
}
// This is the display the updated user
err = db.Debug().Model(&User{}).Where("id = ?", uid).Take(&u).Error
if err != nil {
return &User{}, err
}
return u, nil
}
func (u *User) DeleteUser(db *gorm.DB, uid uint32) (int64, error) {
db = db.Debug().Model(&User{}).Where("id = ?", uid).Take(&User{}).Delete(&User{})
if db.Error != nil {
return 0, db.Error
}
return db.RowsAffected, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment