-
Notifications
You must be signed in to change notification settings - Fork 29
Expand file tree
/
Copy pathdb.go
More file actions
107 lines (87 loc) · 2.37 KB
/
Copy pathdb.go
File metadata and controls
107 lines (87 loc) · 2.37 KB
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
package internal
import (
"errors"
"time"
"github.com/go-sql-driver/mysql"
"gorm.io/gorm"
)
var (
ErrUserNotFound = errors.New("user not found")
ErrEmailAlreadyExists = errors.New("email already exists")
)
type UserDBModel struct {
ID int `gorm:"column:id;primaryKey"`
FirstName string `gorm:"column:first_name"`
LastName string `gorm:"column:last_name"`
Emails []EmailDBModel `gorm:"foreignKey:UserID;constraint:OnDelete:CASCADE"`
PasswordHash string `gorm:"column:password_hash"`
LastIP string `gorm:"column:last_ip"`
CreatedAt *time.Time `gorm:"column:created_at"`
UpdatedAt *time.Time `gorm:"column:updated_at"`
}
func (UserDBModel) TableName() string {
return "users"
}
type EmailDBModel struct {
ID int `gorm:"column:id;primaryKey"`
Address string `gorm:"column:address;size:256;uniqueIndex"`
Primary bool `gorm:"column:primary"`
UserID int `gorm:"column:user_id"`
}
func (EmailDBModel) TableName() string {
return "emails"
}
type UserStorage struct {
db *gorm.DB
}
func NewUserStorage(db *gorm.DB) UserStorage {
return UserStorage{
db: db,
}
}
func (s UserStorage) All() ([]UserDBModel, error) {
var users []UserDBModel
result := s.db.Preload("Emails").Find(&users)
if result.Error != nil {
return nil, result.Error
}
return users, nil
}
func (s UserStorage) ByID(id int) (UserDBModel, error) {
var user UserDBModel
result := s.db.Preload("Emails").First(&user, id)
if result.Error != nil {
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
return UserDBModel{}, ErrUserNotFound
}
return UserDBModel{}, result.Error
}
return user, nil
}
func (s UserStorage) Add(user UserDBModel) error {
return s.db.Transaction(func(tx *gorm.DB) error {
result := tx.Omit("Emails").Create(&user)
if result.Error != nil {
return result.Error
}
email := &user.Emails[0]
email.UserID = user.ID
result = tx.Create(&email)
if result.Error != nil {
var mysqlErr *mysql.MySQLError
if errors.As(result.Error, &mysqlErr) && mysqlErr.Number == 1062 {
return ErrEmailAlreadyExists
}
return result.Error
}
return nil
})
}
func (s UserStorage) Update(user UserDBModel) error {
result := s.db.Save(user)
return result.Error
}
func (s UserStorage) Delete(id int) error {
result := s.db.Delete(&UserDBModel{}, id)
return result.Error
}