github.com/e154/smart-home@v0.17.2-0.20240311175135-e530a6e5cd45/db/variable.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 "fmt" 24 "strings" 25 "time" 26 27 "github.com/pkg/errors" 28 "gorm.io/gorm" 29 30 "github.com/e154/smart-home/common" 31 "github.com/e154/smart-home/common/apperr" 32 ) 33 34 // Variables ... 35 type Variables struct { 36 Db *gorm.DB 37 } 38 39 // Variable ... 40 type Variable struct { 41 Name string `gorm:"primary_key"` 42 Value string 43 System bool 44 EntityId *common.EntityId 45 Tags []*Tag `gorm:"many2many:variable_tags;"` 46 CreatedAt time.Time `gorm:"<-:create"` 47 UpdatedAt time.Time 48 } 49 50 // TableName ... 51 func (d *Variable) TableName() string { 52 return "variables" 53 } 54 55 // Add ... 56 func (n Variables) Add(ctx context.Context, variable Variable) (err error) { 57 if err = n.Db.WithContext(ctx).Omit("Tags.*").Create(&variable).Error; err != nil { 58 err = errors.Wrap(apperr.ErrVariableAdd, err.Error()) 59 } 60 return 61 } 62 63 // CreateOrUpdate ... 64 func (n *Variables) CreateOrUpdate(ctx context.Context, v Variable) (err error) { 65 params := map[string]interface{}{ 66 "name": v.Name, 67 "value": v.Value, 68 } 69 if n.Db.WithContext(ctx).Omit("Tags.*").Model(&v).Where("name = ?", v.Name).Updates(params).RowsAffected == 0 { 70 err = n.Db.WithContext(ctx).Create(&v).Error 71 } 72 return 73 } 74 75 // GetByName ... 76 func (n Variables) GetByName(ctx context.Context, name string) (variable Variable, err error) { 77 variable = Variable{} 78 err = n.Db.WithContext(ctx).Model(&Variable{}). 79 Where("name = ?", name). 80 Preload("Tags"). 81 First(&variable). 82 Error 83 if err != nil { 84 if errors.Is(err, gorm.ErrRecordNotFound) { 85 err = errors.Wrap(apperr.ErrVariableNotFound, fmt.Sprintf("name \"%s\"", name)) 86 return 87 } 88 err = errors.Wrap(apperr.ErrVariableGet, err.Error()) 89 } 90 return 91 } 92 93 // GetAllSystem ... 94 func (n Variables) GetAllSystem(ctx context.Context) (list []Variable, err error) { 95 list = make([]Variable, 0) 96 err = n.Db.WithContext(ctx).Where("system = ?", true). 97 Preload("Tags"). 98 Find(&list).Error 99 if err != nil { 100 err = errors.Wrap(apperr.ErrVariableList, err.Error()) 101 } 102 return 103 } 104 105 // Update ... 106 func (n Variables) Update(ctx context.Context, m Variable) (err error) { 107 err = n.Db.WithContext(ctx). 108 Omit("Tags.*"). 109 Model(&Variable{Name: m.Name}). 110 Updates(map[string]interface{}{ 111 "value": m.Value, 112 "system": m.System, 113 "entity_id": m.EntityId, 114 }).Error 115 if err != nil { 116 err = errors.Wrap(apperr.ErrVariableUpdate, err.Error()) 117 } 118 return 119 } 120 121 // Delete ... 122 func (n Variables) Delete(ctx context.Context, name string) (err error) { 123 if err = n.Db.WithContext(ctx).Delete(&Variable{Name: name}).Error; err != nil { 124 err = errors.Wrap(apperr.ErrVariableDelete, err.Error()) 125 } 126 return 127 } 128 129 // List ... 130 func (n *Variables) List(ctx context.Context, limit, offset int, orderBy, sort string, system bool, name string) (list []Variable, total int64, err error) { 131 132 q := n.Db.WithContext(ctx).Model(&Variable{}). 133 Preload("Tags"). 134 Where("system = ?", system) 135 136 if strings.Contains(name, ",") { 137 names := strings.Split(name, ",") 138 if len(names) > 0 { 139 q = q.Where("name IN (?)", names) 140 } 141 } 142 143 if err = q.Count(&total).Error; err != nil { 144 err = errors.Wrap(apperr.ErrVariableList, err.Error()) 145 return 146 } 147 148 if sort != "" && orderBy != "" { 149 q = q.Order(fmt.Sprintf("%s %s", sort, orderBy)) 150 } 151 152 list = make([]Variable, 0) 153 err = q. 154 Limit(limit). 155 Offset(offset). 156 Find(&list). 157 Error 158 if err != nil { 159 err = errors.Wrap(apperr.ErrVariableList, err.Error()) 160 } 161 return 162 } 163 164 // Search ... 165 func (s *Variables) Search(ctx context.Context, query string, limit, offset int) (list []Variable, total int64, err error) { 166 167 q := s.Db.WithContext(ctx).Model(&Variable{}). 168 Where("name LIKE ?", "%"+query+"%") 169 170 if err = q.Count(&total).Error; err != nil { 171 err = errors.Wrap(apperr.ErrVariableGet, err.Error()) 172 return 173 } 174 175 q = q. 176 Limit(limit). 177 Offset(offset). 178 Order("name ASC") 179 180 list = make([]Variable, 0) 181 if err = q.Find(&list).Error; err != nil { 182 err = errors.Wrap(apperr.ErrVariableGet, err.Error()) 183 } 184 return 185 } 186 187 // DeleteTags ... 188 func (n Variables) DeleteTags(ctx context.Context, name string) (err error) { 189 if err = n.Db.WithContext(ctx).Model(&Variable{Name: name}).Association("Tags").Clear(); err != nil { 190 err = errors.Wrap(apperr.ErrVariableDeleteTag, err.Error()) 191 } 192 return 193 }