github.com/e154/smart-home@v0.17.2-0.20240311175135-e530a6e5cd45/db/trigger.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 "time" 25 26 "github.com/e154/smart-home/common/apperr" 27 "github.com/pkg/errors" 28 "gorm.io/gorm" 29 ) 30 31 // Triggers ... 32 type Triggers struct { 33 Db *gorm.DB 34 } 35 36 // Trigger ... 37 type Trigger struct { 38 Id int64 `gorm:"primary_key"` 39 Name string 40 Entities []*Entity `gorm:"many2many:trigger_entities;"` 41 Script *Script 42 ScriptId *int64 43 PluginName string 44 Payload string 45 Enabled bool 46 AreaId *int64 47 Area *Area 48 Description string 49 CreatedAt time.Time `gorm:"<-:create"` 50 UpdatedAt time.Time 51 } 52 53 // TableName ... 54 func (*Trigger) TableName() string { 55 return "triggers" 56 } 57 58 // Add ... 59 func (t Triggers) Add(ctx context.Context, trigger *Trigger) (id int64, err error) { 60 if err = t.Db.WithContext(ctx). 61 Omit("Entities.*"). 62 Create(&trigger).Error; err != nil { 63 err = errors.Wrap(apperr.ErrTriggerAdd, err.Error()) 64 return 65 } 66 id = trigger.Id 67 return 68 } 69 70 // GetById ... 71 func (t Triggers) GetById(ctx context.Context, id int64) (trigger *Trigger, err error) { 72 trigger = &Trigger{} 73 err = t.Db.WithContext(ctx).Model(trigger). 74 Where("id = ?", id). 75 Preload("Entities"). 76 Preload("Script"). 77 Preload("Area"). 78 First(&trigger). 79 Error 80 if err != nil { 81 if errors.Is(err, gorm.ErrRecordNotFound) { 82 err = errors.Wrap(apperr.ErrTriggerNotFound, fmt.Sprintf("id \"%d\"", id)) 83 return 84 } 85 err = errors.Wrap(apperr.ErrTriggerGet, err.Error()) 86 } 87 88 return 89 } 90 91 // Update ... 92 func (t Triggers) Update(ctx context.Context, trigger *Trigger) (err error) { 93 err = t.Db.WithContext(ctx). 94 Omit("Entities.*"). 95 Save(trigger).Error 96 if err != nil { 97 err = errors.Wrap(apperr.ErrTriggerUpdate, err.Error()) 98 } 99 return 100 } 101 102 // Delete ... 103 func (t Triggers) Delete(ctx context.Context, id int64) (err error) { 104 if err = t.Db.WithContext(ctx).Delete(&Trigger{}, "id = ?", id).Error; err != nil { 105 err = errors.Wrap(apperr.ErrTriggerDelete, err.Error()) 106 } 107 return 108 } 109 110 // List ... 111 func (t Triggers) List(ctx context.Context, limit, offset int, orderBy, sort string, onlyEnabled bool) (list []*Trigger, total int64, err error) { 112 113 if err = t.Db.WithContext(ctx).Model(Trigger{}).Count(&total).Error; err != nil { 114 err = errors.Wrap(apperr.ErrTriggerList, err.Error()) 115 return 116 } 117 118 list = make([]*Trigger, 0) 119 q := t.Db.WithContext(ctx).Model(&Trigger{}) 120 121 if onlyEnabled { 122 q = q.Where("enabled = ?", true) 123 } 124 125 q = q. 126 Preload("Entities"). 127 Preload("Script"). 128 Preload("Area"). 129 Limit(limit). 130 Offset(offset) 131 132 if sort != "" && orderBy != "" { 133 q = q. 134 Order(fmt.Sprintf("%s %s", sort, orderBy)) 135 } 136 137 if err = q.Find(&list).Error; err != nil { 138 err = errors.Wrap(apperr.ErrTriggerList, err.Error()) 139 } 140 return 141 } 142 143 // ListPlain ... 144 func (t Triggers) ListPlain(ctx context.Context, limit, offset int, orderBy, sort string, onlyEnabled bool, ids *[]uint64) (list []*Trigger, total int64, err error) { 145 146 if err = t.Db.WithContext(ctx).Model(Trigger{}).Count(&total).Error; err != nil { 147 err = errors.Wrap(apperr.ErrTriggerList, err.Error()) 148 return 149 } 150 151 list = make([]*Trigger, 0) 152 q := t.Db.WithContext(ctx).Model(&Trigger{}) 153 154 if onlyEnabled { 155 q = q.Where("enabled = ?", true) 156 } 157 158 q = q. 159 Preload("Area"). 160 Limit(limit). 161 Offset(offset) 162 163 if sort != "" && orderBy != "" { 164 q = q. 165 Order(fmt.Sprintf("%s %s", sort, orderBy)) 166 } 167 if ids != nil { 168 q = q.Where("id IN (?)", *ids) 169 } 170 if err = q.Find(&list).Error; err != nil { 171 err = errors.Wrap(apperr.ErrTriggerList, err.Error()) 172 } 173 return 174 } 175 176 // Search ... 177 func (t Triggers) Search(ctx context.Context, query string, limit, offset int) (list []*Trigger, total int64, err error) { 178 179 q := t.Db.WithContext(ctx).Model(&Trigger{}). 180 Where("name LIKE ?", "%"+query+"%") 181 182 if err = q.Count(&total).Error; err != nil { 183 err = errors.Wrap(apperr.ErrTriggerSearch, err.Error()) 184 return 185 } 186 187 q = q. 188 Limit(limit). 189 Offset(offset). 190 Order("name ASC") 191 192 list = make([]*Trigger, 0) 193 err = q.Find(&list).Error 194 if err != nil { 195 err = errors.Wrap(apperr.ErrTriggerSearch, err.Error()) 196 } 197 return 198 } 199 200 // Enable ... 201 func (t Triggers) Enable(ctx context.Context, id int64) (err error) { 202 if err = t.Db.Model(&Trigger{Id: id}).Updates(map[string]interface{}{"enabled": true}).Error; err != nil { 203 err = errors.Wrap(apperr.ErrTriggerUpdate, err.Error()) 204 return 205 } 206 return 207 } 208 209 // Disable ... 210 func (t Triggers) Disable(ctx context.Context, id int64) (err error) { 211 if err = t.Db.Model(&Trigger{Id: id}).Updates(map[string]interface{}{"enabled": false}).Error; err != nil { 212 err = errors.Wrap(apperr.ErrTriggerUpdate, err.Error()) 213 return 214 } 215 return 216 } 217 218 // DeleteEntity ... 219 func (t Triggers) DeleteEntity(ctx context.Context, id int64) (err error) { 220 if err = t.Db.WithContext(ctx).Model(&Trigger{Id: id}).Association("Entities").Clear(); err != nil { 221 err = errors.Wrap(apperr.ErrTriggerDeleteEntity, err.Error()) 222 } 223 return 224 }