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