141 lines
3.9 KiB
Go
141 lines
3.9 KiB
Go
package persistence
|
|
|
|
import (
|
|
domain "RenewCMS/internal/domain/image"
|
|
"RenewCMS/internal/infrastructure/persistence/mappers"
|
|
entity "RenewCMS/internal/infrastructure/persistence/models"
|
|
"strings"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type ImageRepository struct {
|
|
db *gorm.DB
|
|
}
|
|
|
|
func NewImageRepository(db *gorm.DB) *ImageRepository {
|
|
return &ImageRepository{db}
|
|
}
|
|
|
|
func (i ImageRepository) Create(image domain.Image) (domain.Image, error) {
|
|
model := mappers.ImageToModel(image)
|
|
if err := i.db.Create(&model).Error; err != nil {
|
|
return domain.Image{}, err
|
|
}
|
|
return mappers.ImageToDomain(model), nil
|
|
}
|
|
|
|
func (i ImageRepository) Get(id uint32) (domain.Image, error) {
|
|
var model entity.Image
|
|
err := i.db.First(&model, id).Error
|
|
if err != nil {
|
|
return domain.Image{}, mapNotFoundErr(err, domain.ErrImageNotFound)
|
|
}
|
|
return mappers.ImageToDomain(model), nil
|
|
}
|
|
|
|
func (i ImageRepository) Delete(id uint32) error {
|
|
return deleteOrNotFound(i.db.Delete(&entity.Image{}, id), domain.ErrImageNotFound)
|
|
}
|
|
|
|
func (i ImageRepository) List(query domain.SearchQuery) ([]domain.Image, error) {
|
|
statement := i.db.Model(&entity.Image{})
|
|
if query.Search != "" {
|
|
statement = statement.Where("LOWER(filename) LIKE ? ESCAPE '!'", containsPattern(strings.ToLower(query.Search)))
|
|
}
|
|
if query.Hash != "" {
|
|
statement = statement.Where("sha256 = ?", query.Hash)
|
|
}
|
|
|
|
var models []entity.Image
|
|
if err := statement.Order("id asc").Find(&models).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
return imagesToDomain(models), nil
|
|
}
|
|
|
|
func (i ImageRepository) FindByHash(hash string) ([]domain.Image, error) {
|
|
if hash == "" {
|
|
return []domain.Image{}, nil
|
|
}
|
|
var models []entity.Image
|
|
if err := i.db.Where("sha256 = ?", hash).Order("id asc").Find(&models).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
return imagesToDomain(models), nil
|
|
}
|
|
|
|
func (i ImageRepository) Rename(id uint32, filename string) (domain.Image, error) {
|
|
var model entity.Image
|
|
err := i.db.First(&model, id).Error
|
|
if err != nil {
|
|
return domain.Image{}, mapNotFoundErr(err, domain.ErrImageNotFound)
|
|
}
|
|
|
|
model.Filename = filename
|
|
if err := i.db.Save(&model).Error; err != nil {
|
|
return domain.Image{}, err
|
|
}
|
|
return mappers.ImageToDomain(model), nil
|
|
}
|
|
|
|
func (i ImageRepository) ListDuplicates() ([]domain.Image, error) {
|
|
var models []entity.Image
|
|
err := i.db.Where("sha256 IN (?)", i.duplicatedHashes()).Order("sha256 asc, id asc").Find(&models).Error
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return imagesToDomain(models), nil
|
|
}
|
|
|
|
func (i ImageRepository) Counts() (domain.Counts, error) {
|
|
var all int64
|
|
if err := i.db.Model(&entity.Image{}).Count(&all).Error; err != nil {
|
|
return domain.Counts{}, err
|
|
}
|
|
|
|
var groups int64
|
|
if err := i.db.Table("(?) as duplicated", i.duplicatedHashes()).Count(&groups).Error; err != nil {
|
|
return domain.Counts{}, err
|
|
}
|
|
return domain.Counts{All: int(all), DuplicateGroups: int(groups)}, nil
|
|
}
|
|
|
|
func (i ImageRepository) duplicatedHashes() *gorm.DB {
|
|
return i.db.Model(&entity.Image{}).
|
|
Select("sha256").
|
|
Where("sha256 <> ''").
|
|
Group("sha256").
|
|
Having("COUNT(*) > 1")
|
|
}
|
|
|
|
func imagesToDomain(models []entity.Image) []domain.Image {
|
|
images := make([]domain.Image, 0, len(models))
|
|
for _, model := range models {
|
|
images = append(images, mappers.ImageToDomain(model))
|
|
}
|
|
return images
|
|
}
|
|
|
|
func (i ImageRepository) ListMissingMetadata() ([]domain.Image, error) {
|
|
var models []entity.Image
|
|
err := i.db.Where("filename = '' OR filename IS NULL").Order("id asc").Find(&models).Error
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return imagesToDomain(models), nil
|
|
}
|
|
|
|
func (i ImageRepository) UpdateMetadata(id uint32, metadata domain.Metadata) error {
|
|
return i.db.Model(&entity.Image{}).Where("id = ?", id).UpdateColumns(map[string]any{
|
|
"filename": metadata.Filename,
|
|
"size": metadata.Size,
|
|
"content_type": metadata.ContentType,
|
|
"width": metadata.Width,
|
|
"height": metadata.Height,
|
|
"sha256": metadata.SHA256,
|
|
}).Error
|
|
}
|
|
|
|
var _ domain.Repository = &ImageRepository{}
|