github.com/e154/smart-home@v0.17.2-0.20240311175135-e530a6e5cd45/db/image.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 "database/sql" 24 "fmt" 25 "strings" 26 "time" 27 28 "github.com/jackc/pgerrcode" 29 "github.com/jackc/pgx/v5/pgconn" 30 31 "github.com/e154/smart-home/common/apperr" 32 33 "github.com/pkg/errors" 34 "gorm.io/gorm" 35 ) 36 37 // Images ... 38 type Images struct { 39 Db *gorm.DB 40 } 41 42 // Image ... 43 type Image struct { 44 Id int64 `gorm:"primary_key"` 45 Thumb string 46 Image string 47 MimeType string 48 Title string 49 Size int64 50 Name string 51 CreatedAt time.Time `gorm:"<-:create"` 52 } 53 54 // TableName ... 55 func (m *Image) TableName() string { 56 return "images" 57 } 58 59 // Add ... 60 func (n Images) Add(ctx context.Context, v *Image) (id int64, err error) { 61 if err = n.Db.WithContext(ctx).Create(&v).Error; err != nil { 62 var pgErr *pgconn.PgError 63 if errors.As(err, &pgErr) { 64 switch pgErr.Code { 65 case pgerrcode.UniqueViolation: 66 if strings.Contains(pgErr.Message, "images_pkey") { 67 err = errors.Wrap(apperr.ErrImageAdd, fmt.Sprintf("image name \"%d\" not unique", v.Id)) 68 return 69 } 70 default: 71 fmt.Printf("unknown code \"%s\"\n", pgErr.Code) 72 } 73 } 74 err = errors.Wrap(apperr.ErrImageAdd, err.Error()) 75 return 76 } 77 id = v.Id 78 return 79 } 80 81 // GetById ... 82 func (n Images) GetById(ctx context.Context, id int64) (v *Image, err error) { 83 v = &Image{Id: id} 84 if err = n.Db.WithContext(ctx).First(&v).Error; err != nil { 85 if errors.Is(err, gorm.ErrRecordNotFound) { 86 err = errors.Wrap(apperr.ErrImageNotFound, fmt.Sprintf("id \"%d\"", id)) 87 return 88 } 89 err = errors.Wrap(apperr.ErrImageGet, err.Error()) 90 } 91 return 92 } 93 94 // GetByImageName ... 95 func (n Images) GetByImageName(ctx context.Context, imageName string) (v *Image, err error) { 96 v = &Image{} 97 if err = n.Db.WithContext(ctx).Model(v).Where("image = ?", imageName).First(&v).Error; err != nil { 98 if errors.Is(err, gorm.ErrRecordNotFound) { 99 err = errors.Wrap(apperr.ErrImageNotFound, fmt.Sprintf("name \"%s\"", imageName)) 100 return 101 } 102 err = errors.Wrap(apperr.ErrImageGet, err.Error()) 103 return 104 } 105 return 106 } 107 108 // Update ... 109 func (n Images) Update(ctx context.Context, m *Image) (err error) { 110 err = n.Db.WithContext(ctx).Model(&Image{Id: m.Id}).Updates(map[string]interface{}{ 111 "title": m.Title, 112 "Name": m.Name, 113 }).Error 114 if err != nil { 115 err = errors.Wrap(apperr.ErrImageUpdate, err.Error()) 116 return 117 } 118 return 119 } 120 121 // Delete ... 122 func (n Images) Delete(ctx context.Context, mapId int64) (err error) { 123 if err = n.Db.WithContext(ctx).Delete(&Image{Id: mapId}).Error; err != nil { 124 err = errors.Wrap(apperr.ErrImageDelete, err.Error()) 125 return 126 } 127 return 128 } 129 130 // List ... 131 func (n *Images) List(ctx context.Context, limit, offset int, orderBy, sort string) (list []*Image, total int64, err error) { 132 133 if err = n.Db.WithContext(ctx).Model(Image{}).Count(&total).Error; err != nil { 134 err = errors.Wrap(apperr.ErrImageList, err.Error()) 135 return 136 } 137 138 list = make([]*Image, 0) 139 err = n.Db.WithContext(ctx). 140 Limit(limit). 141 Offset(offset). 142 Order(fmt.Sprintf("%s %s", sort, orderBy)). 143 Find(&list). 144 Error 145 146 if err != nil { 147 err = errors.Wrap(apperr.ErrImageList, err.Error()) 148 return 149 } 150 return 151 } 152 153 // ImageFilterList ... 154 type ImageFilterList struct { 155 Date string `json:"date"` 156 Count int `json:"count"` 157 } 158 159 // GetFilterList ... 160 func (n *Images) GetFilterList(ctx context.Context) (images []*ImageFilterList, err error) { 161 162 image := &Image{} 163 var rows *sql.Rows 164 rows, err = n.Db.WithContext(ctx).Raw(` 165 SELECT 166 to_char(created_at,'YYYY-mm-dd') as date, COUNT( created_at) as count 167 FROM ` + image.TableName() + ` 168 GROUP BY date 169 ORDER BY date`).Rows() 170 171 if err != nil { 172 err = errors.Wrap(apperr.ErrImageList, err.Error()) 173 return 174 } 175 176 for rows.Next() { 177 item := &ImageFilterList{} 178 _ = rows.Scan(&item.Date, &item.Count) 179 images = append(images, item) 180 } 181 182 return 183 } 184 185 // GetAllByDate ... 186 func (n *Images) GetAllByDate(ctx context.Context, filter string) (images []*Image, err error) { 187 188 //fmt.Println("filter", filter) 189 190 images = make([]*Image, 0) 191 image := &Image{} 192 err = n.Db.WithContext(ctx).Raw(` 193 SELECT * 194 FROM `+image.TableName()+` 195 WHERE to_char(created_at,'YYYY-mm-dd') = ? 196 ORDER BY created_at`, filter). 197 Find(&images). 198 Error 199 200 if err != nil { 201 err = errors.Wrap(apperr.ErrImageList, err.Error()) 202 } 203 return 204 } 205 206 // AddMultiple ... 207 func (n *Images) AddMultiple(ctx context.Context, images []*Image) (err error) { 208 if err = n.Db.WithContext(ctx).Create(&images).Error; err != nil { 209 var pgErr *pgconn.PgError 210 if errors.As(err, &pgErr) { 211 switch pgErr.Code { 212 case pgerrcode.UniqueViolation: 213 if strings.Contains(pgErr.Message, "images_pkey") { 214 err = errors.Wrap(apperr.ErrImageAdd, "multiple insert") 215 return 216 } 217 default: 218 fmt.Printf("unknown code \"%s\"\n", pgErr.Code) 219 } 220 } 221 err = errors.Wrap(apperr.ErrImageAdd, err.Error()) 222 } 223 return 224 }