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  }