github.com/e154/smart-home@v0.17.2-0.20240311175135-e530a6e5cd45/db/log.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  // Logs ...
    34  type Logs struct {
    35  	Db *gorm.DB
    36  }
    37  
    38  // Log ...
    39  type Log struct {
    40  	Id        int64 `gorm:"primary_key"`
    41  	Body      string
    42  	Level     common.LogLevel
    43  	Owner     string
    44  	CreatedAt time.Time `gorm:"<-:create"`
    45  }
    46  
    47  // LogQuery ...
    48  type LogQuery struct {
    49  	StartDate *time.Time `json:"start_date"`
    50  	EndDate   *time.Time `json:"end_date"`
    51  	Levels    []string   `json:"levels"`
    52  }
    53  
    54  // TableName ...
    55  func (m *Log) TableName() string {
    56  	return "logs"
    57  }
    58  
    59  // Add ...
    60  func (n Logs) Add(ctx context.Context, v *Log) (id int64, err error) {
    61  	if err = n.Db.WithContext(ctx).Create(&v).Error; err != nil {
    62  		err = errors.Wrap(apperr.ErrLogAdd, err.Error())
    63  		return
    64  	}
    65  	id = v.Id
    66  	return
    67  }
    68  
    69  // GetById ...
    70  func (n Logs) GetById(ctx context.Context, id int64) (v *Log, err error) {
    71  	v = &Log{Id: id}
    72  	if err = n.Db.WithContext(ctx).First(&v).Error; err != nil {
    73  		if errors.Is(err, gorm.ErrRecordNotFound) {
    74  			err = errors.Wrap(apperr.ErrLogNotFound, fmt.Sprintf("id \"%d\"", id))
    75  			return
    76  		}
    77  		err = errors.Wrap(apperr.ErrLogGet, err.Error())
    78  	}
    79  	return
    80  }
    81  
    82  // Delete ...
    83  func (n Logs) Delete(ctx context.Context, mapId int64) (err error) {
    84  	if err = n.Db.WithContext(ctx).Delete(&Log{Id: mapId}).Error; err != nil {
    85  		err = errors.Wrap(apperr.ErrLogDelete, err.Error())
    86  	}
    87  	return
    88  }
    89  
    90  // List ...
    91  func (n *Logs) List(ctx context.Context, limit, offset int, orderBy, sort string, queryObj *LogQuery) (list []*Log, total int64, err error) {
    92  
    93  	q := n.Db.WithContext(ctx).Model(Log{})
    94  
    95  	if queryObj != nil {
    96  		if queryObj.StartDate != nil {
    97  			q = q.Where("created_at >= ?", &queryObj.StartDate)
    98  		}
    99  		if queryObj.EndDate != nil {
   100  			q = q.Where("created_at <= ?", &queryObj.EndDate)
   101  		}
   102  		if len(queryObj.Levels) > 0 {
   103  			q = q.Where("level in (?)", queryObj.Levels)
   104  		}
   105  	}
   106  
   107  	if err = q.Count(&total).Error; err != nil {
   108  		err = errors.Wrap(apperr.ErrLogList, err.Error())
   109  		return
   110  	}
   111  
   112  	list = make([]*Log, 0)
   113  	err = q.
   114  		Limit(limit).
   115  		Offset(offset).
   116  		Order(fmt.Sprintf("%s %s", sort, orderBy)).
   117  		Find(&list).Error
   118  
   119  	if err != nil {
   120  		err = errors.Wrap(apperr.ErrLogList, err.Error())
   121  	}
   122  
   123  	return
   124  }
   125  
   126  // Search ...
   127  func (n *Logs) Search(ctx context.Context, query string, limit, offset int) (list []*Log, total int64, err error) {
   128  
   129  	q := n.Db.WithContext(ctx).Model(&Log{}).
   130  		Where("body LIKE ?", "%"+query+"%")
   131  
   132  	if err = q.Count(&total).Error; err != nil {
   133  		err = errors.Wrap(apperr.ErrLogList, err.Error())
   134  		return
   135  	}
   136  
   137  	q = q.
   138  		Limit(limit).
   139  		Offset(offset).
   140  		Order("body ASC")
   141  
   142  	list = make([]*Log, 0)
   143  	if err = q.Find(&list).Error; err != nil {
   144  		err = errors.Wrap(apperr.ErrLogList, err.Error())
   145  	}
   146  
   147  	return
   148  }
   149  
   150  // DeleteOldest ...
   151  func (n *Logs) DeleteOldest(ctx context.Context, days int) (err error) {
   152  
   153  	log := &Log{}
   154  	if err = n.Db.WithContext(ctx).Last(&log).Error; err != nil {
   155  		err = errors.Wrap(apperr.ErrLogDelete, err.Error())
   156  		return
   157  	}
   158  	err = n.Db.WithContext(ctx).Delete(&Log{},
   159  		fmt.Sprintf(`created_at < CAST('%s' AS DATE) - interval '%d days'`,
   160  			log.CreatedAt.UTC().Format("2006-01-02 15:04:05"), days)).Error
   161  	if err != nil {
   162  		err = errors.Wrap(apperr.ErrLogDelete, err.Error())
   163  	}
   164  	return
   165  }
   166  
   167  // AddMultiple ...
   168  func (n *Logs) AddMultiple(ctx context.Context, logs []*Log) (err error) {
   169  	if err = n.Db.WithContext(ctx).Create(&logs).Error; err != nil {
   170  		err = errors.Wrap(apperr.ErrLogAdd, err.Error())
   171  	}
   172  	return
   173  }