github.com/e154/smart-home@v0.17.2-0.20240311175135-e530a6e5cd45/db/entity_storage.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  // EntityStorages ...
    35  type EntityStorages struct {
    36  	Db *gorm.DB
    37  }
    38  
    39  // EntityStorage ...
    40  type EntityStorage struct {
    41  	Id         int64 `gorm:"primary_key"`
    42  	EntityId   common.EntityId
    43  	State      string
    44  	Attributes json.RawMessage `gorm:"type:jsonb;not null"`
    45  	CreatedAt  time.Time       `gorm:"<-:create"`
    46  }
    47  
    48  // TableName ...
    49  func (d *EntityStorage) TableName() string {
    50  	return "entity_storage"
    51  }
    52  
    53  // Add ...
    54  func (n *EntityStorages) Add(ctx context.Context, v *EntityStorage) (id int64, err error) {
    55  	if err = n.Db.WithContext(ctx).Create(&v).Error; err != nil {
    56  		err = errors.Wrap(apperr.ErrEntityStorageAdd, err.Error())
    57  		return
    58  	}
    59  	id = v.Id
    60  	return
    61  }
    62  
    63  // GetLastByEntityId ...
    64  func (n *EntityStorages) GetLastByEntityId(ctx context.Context, entityId common.EntityId) (v *EntityStorage, err error) {
    65  	v = &EntityStorage{}
    66  	err = n.Db.WithContext(ctx).Model(&EntityStorage{}).
    67  		Order("created_at desc").
    68  		First(&v, "entity_id = ?", entityId).
    69  		Error
    70  
    71  	if err != nil {
    72  		if errors.Is(err, gorm.ErrRecordNotFound) {
    73  			err = errors.Wrap(apperr.ErrEntityNotFound, fmt.Sprintf("id \"%s\"", entityId))
    74  			return
    75  		}
    76  		err = errors.Wrap(apperr.ErrEntityStorageGet, err.Error())
    77  		return
    78  	}
    79  	return
    80  }
    81  
    82  // List ...
    83  func (n *EntityStorages) List(ctx context.Context, limit, offset int, orderBy, sort string, entityIds []common.EntityId, startDate, endDate *time.Time) (list []*EntityStorage, total int64, err error) {
    84  
    85  	q := n.Db.WithContext(ctx).Model(&EntityStorage{})
    86  
    87  	if len(entityIds) > 0 {
    88  		q = q.Where("entity_id in (?)", entityIds)
    89  	}
    90  
    91  	if startDate != nil {
    92  		q = q.Where("created_at > ?", startDate.UTC().Format(time.RFC3339))
    93  	}
    94  	if endDate != nil {
    95  		q = q.Where("created_at <= ?", endDate.UTC().Format(time.RFC3339))
    96  	}
    97  
    98  	if err = q.Count(&total).Error; err != nil {
    99  		err = errors.Wrap(apperr.ErrEntityStorageList, err.Error())
   100  		return
   101  	}
   102  
   103  	list = make([]*EntityStorage, 0)
   104  	q = q.
   105  		Limit(limit).
   106  		Offset(offset)
   107  
   108  	if sort != "" && orderBy != "" {
   109  		q = q.
   110  			Order(fmt.Sprintf("%s %s", sort, orderBy))
   111  	}
   112  
   113  	err = q.
   114  		Find(&list).
   115  		Error
   116  	if err != nil {
   117  		err = errors.Wrap(apperr.ErrEntityStorageList, err.Error())
   118  		return
   119  	}
   120  	return
   121  }
   122  
   123  // DeleteOldest ...
   124  func (n *EntityStorages) DeleteOldest(ctx context.Context, days int) (err error) {
   125  	storage := &EntityStorage{}
   126  	if err = n.Db.WithContext(ctx).Last(&storage).Error; err != nil {
   127  		err = errors.Wrap(apperr.ErrLogDelete, err.Error())
   128  		return
   129  	}
   130  	err = n.Db.WithContext(ctx).Delete(&EntityStorage{},
   131  		fmt.Sprintf(`created_at < CAST('%s' AS DATE) - interval '%d days'`,
   132  			storage.CreatedAt.UTC().Format("2006-01-02 15:04:05"), days)).Error
   133  	if err != nil {
   134  		err = errors.Wrap(apperr.ErrEntityStorageDelete, err.Error())
   135  	}
   136  	return
   137  }