refac: decouple persistence and image storage behind driver registries
This commit is contained in:
1 parent
421cfafec3
commit
81e299f09a
46 files changed
+1036
-374
No files matched your search
@@ -4,67 +4,24 @@ import (
|
||||
domain "RenewCMS/internal/domain/image"
|
||||
"RenewCMS/internal/infrastructure/persistence/mappers"
|
||||
entity "RenewCMS/internal/infrastructure/persistence/models"
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
const uploadedImagesURLPrefix = "/static/uploadedImages/"
|
||||
|
||||
type ImageRepository struct {
|
||||
db *gorm.DB
|
||||
uploadDir string
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func NewImageRepository(db *gorm.DB, uploadDir string) *ImageRepository {
|
||||
return &ImageRepository{db, uploadDir}
|
||||
func NewImageRepository(db *gorm.DB) *ImageRepository {
|
||||
return &ImageRepository{db}
|
||||
}
|
||||
|
||||
var contentTypeExtensions = map[string]string{
|
||||
"image/png": ".png",
|
||||
"image/jpeg": ".jpeg",
|
||||
"image/webp": ".webp",
|
||||
"image/svg+xml": ".svg",
|
||||
}
|
||||
|
||||
func (i ImageRepository) Create(input domain.ImageInput) (domain.Image, error) {
|
||||
fileBytes, err := io.ReadAll(input.Content)
|
||||
if err != nil {
|
||||
return domain.Image{}, err
|
||||
}
|
||||
|
||||
err = os.MkdirAll(i.uploadDir, 0755)
|
||||
if err != nil {
|
||||
return domain.Image{}, err
|
||||
}
|
||||
|
||||
newName := uuid.NewString() + contentTypeExtensions[input.ContentType]
|
||||
finalPath := filepath.Join(i.uploadDir, newName)
|
||||
err = os.WriteFile(finalPath, fileBytes, 0666)
|
||||
if err != nil {
|
||||
return domain.Image{}, err
|
||||
}
|
||||
|
||||
model := mappers.ImageToModel(domain.Image{
|
||||
Path: uploadedImagesURLPrefix + newName,
|
||||
Filename: input.Filename,
|
||||
Size: input.Size,
|
||||
ContentType: input.ContentType,
|
||||
Width: input.Width,
|
||||
Height: input.Height,
|
||||
SHA256: input.SHA256,
|
||||
UploadedByID: input.UploadedByID,
|
||||
})
|
||||
func (i ImageRepository) Create(image domain.Image) (domain.Image, error) {
|
||||
model := mappers.ImageToModel(image)
|
||||
if err := i.db.Create(&model).Error; err != nil {
|
||||
_ = os.Remove(finalPath)
|
||||
return domain.Image{}, err
|
||||
}
|
||||
|
||||
return mappers.ImageToDomain(model), nil
|
||||
}
|
||||
|
||||
@@ -78,24 +35,13 @@ func (i ImageRepository) Get(id uint32) (domain.Image, error) {
|
||||
}
|
||||
|
||||
func (i ImageRepository) Delete(id uint32) error {
|
||||
var model entity.Image
|
||||
err := i.db.First(&model, id).Error
|
||||
if err != nil {
|
||||
return mapNotFoundErr(err, domain.ErrImageNotFound)
|
||||
}
|
||||
|
||||
err = os.Remove(filepath.Join(i.uploadDir, filepath.Base(model.Path)))
|
||||
if err != nil && !errors.Is(err, os.ErrNotExist) {
|
||||
return err
|
||||
}
|
||||
|
||||
return i.db.Delete(&entity.Image{}, id).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("instr(lower(filename), ?) > 0", strings.ToLower(query.Search))
|
||||
statement = statement.Where("LOWER(filename) LIKE ? ESCAPE '!'", containsPattern(strings.ToLower(query.Search)))
|
||||
}
|
||||
if query.Hash != "" {
|
||||
statement = statement.Where("sha256 = ?", query.Hash)
|
||||
@@ -171,4 +117,24 @@ func imagesToDomain(models []entity.Image) []domain.Image {
|
||||
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{}
|
||||
Reference in new issue
Block a user