github.com/e154/smart-home@v0.17.2-0.20240311175135-e530a6e5cd45/db/metric.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  	"encoding/json"
    24  	"fmt"
    25  	"time"
    26  
    27  	"github.com/e154/smart-home/common/apperr"
    28  
    29  	"github.com/e154/smart-home/common"
    30  	"github.com/pkg/errors"
    31  	"gorm.io/gorm"
    32  )
    33  
    34  // Metrics ...
    35  type Metrics struct {
    36  	Db *gorm.DB
    37  }
    38  
    39  // Metric ...
    40  type Metric struct {
    41  	Id          int64 `gorm:"primary_key"`
    42  	Data        []*MetricBucket
    43  	Name        string
    44  	Description string
    45  	Options     json.RawMessage `gorm:"type:jsonb;not null"`
    46  	Type        common.MetricType
    47  	UpdatedAt   time.Time
    48  	CreatedAt   time.Time `gorm:"<-:create"`
    49  }
    50  
    51  // TableName ...
    52  func (Metric) TableName() string {
    53  	return "metrics"
    54  }
    55  
    56  // Add ...
    57  func (n Metrics) Add(ctx context.Context, metric *Metric) (id int64, err error) {
    58  	if err = n.Db.WithContext(ctx).Create(&metric).Error; err != nil {
    59  		err = errors.Wrap(apperr.ErrMetricAdd, err.Error())
    60  		return
    61  	}
    62  	id = metric.Id
    63  	return
    64  }
    65  
    66  // GetById ...
    67  func (n Metrics) GetById(ctx context.Context, id int64) (metric *Metric, err error) {
    68  	metric = &Metric{Id: id}
    69  	if err = n.Db.WithContext(ctx).First(&metric).Error; err != nil {
    70  		if errors.Is(err, gorm.ErrRecordNotFound) {
    71  			err = errors.Wrap(apperr.ErrMetricNotFound, fmt.Sprintf("id \"%d\"", id))
    72  			return
    73  		}
    74  		err = errors.Wrap(apperr.ErrMetricGet, err.Error())
    75  	}
    76  	return
    77  }
    78  
    79  // Update ...
    80  func (n Metrics) Update(ctx context.Context, m *Metric) (err error) {
    81  	q := map[string]interface{}{
    82  		"name":        m.Name,
    83  		"description": m.Description,
    84  		"options":     m.Options,
    85  		"type":        m.Type,
    86  	}
    87  	if err = n.Db.WithContext(ctx).Model(&Metric{}).Where("id = ?", m.Id).Updates(q).Error; err != nil {
    88  		err = errors.Wrap(apperr.ErrMetricUpdate, err.Error())
    89  	}
    90  	return
    91  }
    92  
    93  // Delete ...
    94  func (n Metrics) Delete(ctx context.Context, id int64) (err error) {
    95  	if err = n.Db.WithContext(ctx).Delete(&Metric{}, "id = ?", id).Error; err != nil {
    96  		err = errors.Wrap(apperr.ErrMetricDelete, err.Error())
    97  	}
    98  	return
    99  }
   100  
   101  // List ...
   102  func (n *Metrics) List(ctx context.Context, limit, offset int, orderBy, sort string) (list []*Metric, total int64, err error) {
   103  
   104  	if err = n.Db.WithContext(ctx).Model(Metric{}).Count(&total).Error; err != nil {
   105  		err = errors.Wrap(apperr.ErrMetricList, err.Error())
   106  		return
   107  	}
   108  
   109  	list = make([]*Metric, 0)
   110  	q := n.Db.WithContext(ctx).Model(&Metric{}).
   111  		Limit(limit).
   112  		Offset(offset)
   113  
   114  	if sort != "" && orderBy != "" {
   115  		q = q.
   116  			Order(fmt.Sprintf("%s %s", sort, orderBy))
   117  	}
   118  
   119  	if err = q.Find(&list).Error; err != nil {
   120  		err = errors.Wrap(apperr.ErrMetricList, err.Error())
   121  	}
   122  	return
   123  }
   124  
   125  // Search ...q
   126  func (n *Metrics) Search(ctx context.Context, query string, limit, offset int) (list []*Metric, total int64, err error) {
   127  
   128  	q := n.Db.WithContext(ctx).Model(&Metric{}).
   129  		Where("name LIKE ?", "%"+query+"%")
   130  
   131  	if err = q.Count(&total).Error; err != nil {
   132  		err = errors.Wrap(apperr.ErrMetricSearch, err.Error())
   133  		return
   134  	}
   135  
   136  	q = q.
   137  		Limit(limit).
   138  		Offset(offset).
   139  		Order("name ASC")
   140  
   141  	list = make([]*Metric, 0)
   142  	err = q.Find(&list).Error
   143  	if err != nil {
   144  		err = errors.Wrap(apperr.ErrMetricSearch, err.Error())
   145  	}
   146  	return
   147  }
   148  
   149  // AddMultiple ...
   150  func (n *Metrics) AddMultiple(ctx context.Context, metrics []*Metric) (err error) {
   151  	if err = n.Db.WithContext(ctx).Create(&metrics).Error; err != nil {
   152  		err = errors.Wrap(apperr.ErrMetricAdd, err.Error())
   153  	}
   154  	return
   155  }