github.com/e154/smart-home@v0.17.2-0.20240311175135-e530a6e5cd45/db/dashboard.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/jackc/pgerrcode" 28 "github.com/jackc/pgx/v5/pgconn" 29 "github.com/pkg/errors" 30 "gorm.io/gorm" 31 32 "github.com/e154/smart-home/common/apperr" 33 ) 34 35 // Dashboards ... 36 type Dashboards struct { 37 Db *gorm.DB 38 } 39 40 // Dashboard ... 41 type Dashboard struct { 42 Id int64 `gorm:"primary_key"` 43 Name string 44 Description string 45 Enabled bool 46 AreaId *int64 47 Area *Area 48 Tabs []*DashboardTab 49 CreatedAt time.Time `gorm:"<-:create"` 50 UpdatedAt time.Time 51 } 52 53 // TableName ... 54 func (d *Dashboard) TableName() string { 55 return "dashboards" 56 } 57 58 // Add ... 59 func (n Dashboards) Add(ctx context.Context, board *Dashboard) (id int64, err error) { 60 if err = n.Db.WithContext(ctx).Create(&board).Error; err != nil { 61 var pgErr *pgconn.PgError 62 if errors.As(err, &pgErr) { 63 switch pgErr.Code { 64 case pgerrcode.UniqueViolation: 65 if strings.Contains(pgErr.Message, "name_at_dashboards_unq") { 66 err = errors.Wrap(apperr.ErrDashboardAdd, fmt.Sprintf("dashboard name \"%s\" not unique", board.Name)) 67 return 68 } 69 default: 70 fmt.Printf("unknown code \"%s\"\n", pgErr.Code) 71 } 72 } 73 err = errors.Wrap(apperr.ErrDashboardAdd, err.Error()) 74 return 75 } 76 id = board.Id 77 return 78 } 79 80 // GetById ... 81 func (n Dashboards) GetById(ctx context.Context, id int64) (board *Dashboard, err error) { 82 board = &Dashboard{} 83 err = n.Db.WithContext(ctx).Model(board). 84 Where("id = ?", id). 85 Preload("Area"). 86 Preload("Tabs"). 87 Preload("Tabs.Cards"). 88 Preload("Tabs.Cards.Items"). 89 First(&board).Error 90 91 if err != nil { 92 if errors.Is(err, gorm.ErrRecordNotFound) { 93 err = errors.Wrap(apperr.ErrDashboardNotFound, fmt.Sprintf("id \"%d\"", id)) 94 return 95 } 96 err = errors.Wrap(apperr.ErrDashboardGet, err.Error()) 97 return 98 } 99 return 100 } 101 102 // Update ... 103 func (n Dashboards) Update(ctx context.Context, board *Dashboard) (err error) { 104 q := map[string]interface{}{ 105 "name": board.Name, 106 "description": board.Description, 107 "enabled": board.Enabled, 108 "area_id": board.AreaId, 109 } 110 111 if err = n.Db.WithContext(ctx).Model(&Dashboard{Id: board.Id}).Updates(q).Error; err != nil { 112 var pgErr *pgconn.PgError 113 if errors.As(err, &pgErr) { 114 switch pgErr.Code { 115 case pgerrcode.UniqueViolation: 116 if strings.Contains(pgErr.Message, "name_at_dashboards_unq") { 117 err = errors.Wrap(apperr.ErrDashboardUpdate, fmt.Sprintf("dashboard name \"%s\" not unique", board.Name)) 118 return 119 } 120 default: 121 fmt.Printf("unknown code \"%s\"\n", pgErr.Code) 122 } 123 } 124 err = errors.Wrap(apperr.ErrDashboardUpdate, err.Error()) 125 } 126 return 127 } 128 129 // Delete ... 130 func (n Dashboards) Delete(ctx context.Context, id int64) (err error) { 131 if id == 0 { 132 return 133 } 134 if err = n.Db.WithContext(ctx).Delete(&Dashboard{Id: id}).Error; err != nil { 135 err = errors.Wrap(apperr.ErrDashboardDelete, err.Error()) 136 } 137 return 138 } 139 140 // List ... 141 func (n *Dashboards) List(ctx context.Context, limit, offset int, orderBy, sort string) (list []*Dashboard, total int64, err error) { 142 143 if err = n.Db.WithContext(ctx).Model(Dashboard{}).Count(&total).Error; err != nil { 144 err = errors.Wrap(apperr.ErrDashboardGet, err.Error()) 145 return 146 } 147 148 list = make([]*Dashboard, 0) 149 q := n.Db.WithContext(ctx). 150 Preload("Area"). 151 Limit(limit). 152 Offset(offset) 153 154 if sort != "" && orderBy != "" { 155 q = q.Order(fmt.Sprintf("%s %s", sort, orderBy)) 156 } 157 158 err = q. 159 Find(&list). 160 Error 161 162 if err != nil { 163 err = errors.Wrap(apperr.ErrDashboardList, err.Error()) 164 } 165 166 return 167 } 168 169 // Search ... 170 func (d *Dashboards) Search(ctx context.Context, query string, limit, offset int) (list []*Dashboard, total int64, err error) { 171 172 q := d.Db.Model(&Dashboard{}). 173 Where("name LIKE ?", "%"+query+"%") 174 175 if err = q.Count(&total).Error; err != nil { 176 err = errors.Wrap(apperr.ErrDashboardSearch, err.Error()) 177 return 178 } 179 180 q = q. 181 Limit(limit). 182 Offset(offset). 183 Order("name ASC") 184 185 list = make([]*Dashboard, 0) 186 if err = q.Find(&list).Error; err != nil { 187 err = errors.Wrap(apperr.ErrDashboardSearch, err.Error()) 188 } 189 return 190 }