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  }