github.com/e154/smart-home@v0.17.2-0.20240311175135-e530a6e5cd45/db/role.go (about) 1 // This file is part of the Smart Home 2 // Program complex distribution https://github.com/e154/smart-home 3 // Copyright (C) 2016-2023, Filippov Alex 4 // 5 // This library is free software: you can redistribute it and/or 6 // modify it under the terms of the GNU Lesser General Public 7 // License as published by the Free Software Foundation; either 8 // version 3 of the License, or (at your option) any later version. 9 // 10 // This library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 // Library General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public 16 // License along with this library. If not, see 17 // <https://www.gnu.org/licenses/>. 18 19 package db 20 21 import ( 22 "context" 23 "database/sql" 24 "fmt" 25 "time" 26 27 "github.com/e154/smart-home/common/apperr" 28 29 "github.com/pkg/errors" 30 "gorm.io/gorm" 31 ) 32 33 // Roles ... 34 type Roles struct { 35 Db *gorm.DB 36 } 37 38 // Role ... 39 type Role struct { 40 Name string `gorm:"primary_key"` 41 Description string 42 Role *Role 43 RoleName sql.NullString `gorm:"column:parent"` 44 Children []*Role 45 Permissions []*Permission 46 CreatedAt time.Time `gorm:"<-:create"` 47 UpdatedAt time.Time 48 } 49 50 // TableName ... 51 func (m *Role) TableName() string { 52 return "roles" 53 } 54 55 // Add ... 56 func (n Roles) Add(ctx context.Context, role *Role) (err error) { 57 if err = n.Db.WithContext(ctx).Create(&role).Error; err != nil { 58 err = errors.Wrap(apperr.ErrRoleAdd, err.Error()) 59 return 60 } 61 return 62 } 63 64 // GetByName ... 65 func (n Roles) GetByName(ctx context.Context, name string) (role *Role, err error) { 66 67 role = &Role{Name: name} 68 err = n.Db.WithContext(ctx).First(&role).Error 69 if err != nil { 70 if errors.Is(err, gorm.ErrRecordNotFound) { 71 err = errors.Wrap(apperr.ErrRoleNotFound, fmt.Sprintf("name \"%s\"", name)) 72 return 73 } 74 err = errors.Wrap(apperr.ErrRoleGet, err.Error()) 75 return 76 } 77 78 err = n.RelData(ctx, role) 79 80 return 81 } 82 83 // Update ... 84 func (n Roles) Update(ctx context.Context, m *Role) (err error) { 85 err = n.Db.WithContext(ctx).Model(&Role{Name: m.Name}).Updates(map[string]interface{}{ 86 "description": m.Description, 87 "parent": m.RoleName, 88 }).Error 89 if err != nil { 90 err = errors.Wrap(apperr.ErrRoleUpdate, err.Error()) 91 } 92 93 return 94 } 95 96 // Delete ... 97 func (n Roles) Delete(ctx context.Context, name string) (err error) { 98 if err = n.Db.WithContext(ctx).Delete(&Role{Name: name}).Error; err != nil { 99 err = errors.Wrap(apperr.ErrRoleDelete, err.Error()) 100 } 101 return 102 } 103 104 // List ... 105 func (n *Roles) List(ctx context.Context, limit, offset int, orderBy, sort string) (list []*Role, total int64, err error) { 106 107 if err = n.Db.WithContext(ctx).Model(Role{}).Count(&total).Error; err != nil { 108 err = errors.Wrap(apperr.ErrRoleList, err.Error()) 109 return 110 } 111 112 list = make([]*Role, 0) 113 err = n.Db.WithContext(ctx). 114 Limit(limit). 115 Offset(offset). 116 Order(fmt.Sprintf("%s %s", sort, orderBy)). 117 Find(&list). 118 Error 119 120 if err != nil { 121 err = errors.Wrap(apperr.ErrRoleList, err.Error()) 122 return 123 } 124 125 for _, role := range list { 126 _ = n.RelData(ctx, role) 127 } 128 129 return 130 } 131 132 // Search ... 133 func (n *Roles) Search(ctx context.Context, query string, limit, offset int) (list []*Role, total int64, err error) { 134 135 q := n.Db.WithContext(ctx).Model(&Role{}). 136 Where("name LIKE ?", "%"+query+"%") 137 138 if err = q.Count(&total).Error; err != nil { 139 err = errors.Wrap(apperr.ErrRoleSearch, err.Error()) 140 return 141 } 142 143 q = q. 144 Limit(limit). 145 Offset(offset). 146 Order("name ASC") 147 148 list = make([]*Role, 0) 149 if err = q.Find(&list).Error; err != nil { 150 err = errors.Wrap(apperr.ErrRoleSearch, err.Error()) 151 } 152 153 return 154 } 155 156 // RelData ... 157 func (n *Roles) RelData(ctx context.Context, role *Role) (err error) { 158 159 // get parent 160 if role.RoleName.Valid { 161 role.Role = &Role{} 162 err = n.Db.WithContext(ctx).Model(role). 163 Where("name = ?", role.RoleName.String). 164 Find(&role.Role). 165 Error 166 if err != nil { 167 err = errors.Wrap(apperr.ErrRoleGet, err.Error()) 168 } 169 } 170 171 // get children 172 role.Children = make([]*Role, 0) 173 err = n.Db.WithContext(ctx).Model(role). 174 Where("parent = ?", role.Name). 175 Find(&role.Children). 176 Error 177 if err != nil { 178 err = errors.Wrap(apperr.ErrRoleGet, err.Error()) 179 } 180 181 return 182 }