aboutsummaryrefslogtreecommitdiff
path: root/pkg/database/sql/media.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/database/sql/media.go')
-rw-r--r--pkg/database/sql/media.go238
1 files changed, 238 insertions, 0 deletions
diff --git a/pkg/database/sql/media.go b/pkg/database/sql/media.go
new file mode 100644
index 0000000..835e262
--- /dev/null
+++ b/pkg/database/sql/media.go
@@ -0,0 +1,238 @@
+package sql
+
+import (
+ "context"
+ "time"
+
+ "gorm.io/gorm"
+
+ "git.sr.ht/~gabrielgio/img/pkg/components/media"
+ "git.sr.ht/~gabrielgio/img/pkg/list"
+)
+
+type (
+ Media struct {
+ gorm.Model
+ Name string `gorm:"not null"`
+ Path string `gorm:"not null;unique"`
+ PathHash string `gorm:"not null;unique"`
+ MIMEType string `gorm:"not null"`
+ }
+
+ MediaEXIF struct {
+ gorm.Model
+ MediaID uint
+ Media Media
+ Description *string
+ Camera *string
+ Maker *string
+ Lens *string
+ DateShot *time.Time
+ Exposure *float64
+ Aperture *float64
+ Iso *int64
+ FocalLength *float64
+ Flash *int64
+ Orientation *int64
+ ExposureProgram *int64
+ GPSLatitude *float64
+ GPSLongitude *float64
+ }
+
+ MediaRepository struct {
+ db *gorm.DB
+ }
+)
+
+var _ media.Repository = &MediaRepository{}
+
+func (self *Media) ToModel() *media.Media {
+ return &media.Media{
+ ID: self.ID,
+ Path: self.Path,
+ PathHash: self.PathHash,
+ Name: self.Name,
+ MIMEType: self.MIMEType,
+ }
+}
+
+func (m *MediaEXIF) ToModel() *media.MediaEXIF {
+ return &media.MediaEXIF{
+ Description: m.Description,
+ Camera: m.Camera,
+ Maker: m.Maker,
+ Lens: m.Lens,
+ DateShot: m.DateShot,
+ Exposure: m.Exposure,
+ Aperture: m.Aperture,
+ Iso: m.Iso,
+ FocalLength: m.FocalLength,
+ Flash: m.Flash,
+ Orientation: m.Orientation,
+ ExposureProgram: m.ExposureProgram,
+ GPSLatitude: m.GPSLatitude,
+ GPSLongitude: m.GPSLongitude,
+ }
+}
+
+func NewMediaRepository(db *gorm.DB) *MediaRepository {
+ return &MediaRepository{
+ db: db,
+ }
+}
+
+func (self *MediaRepository) Create(ctx context.Context, createMedia *media.CreateMedia) error {
+ media := &Media{
+ Name: createMedia.Name,
+ Path: createMedia.Path,
+ PathHash: createMedia.PathHash,
+ MIMEType: createMedia.MIMEType,
+ }
+
+ result := self.db.
+ WithContext(ctx).
+ Create(media)
+ if result.Error != nil {
+ return result.Error
+ }
+
+ return nil
+}
+
+func (self *MediaRepository) Exists(ctx context.Context, path string) (bool, error) {
+ var exists bool
+ result := self.db.
+ WithContext(ctx).
+ Model(&Media{}).
+ Select("count(id) > 0").
+ Where("path_hash = ?", path).
+ Find(&exists)
+
+ if result.Error != nil {
+ return false, result.Error
+ }
+
+ return exists, nil
+}
+
+func (self *MediaRepository) List(ctx context.Context, pagination *media.Pagination) ([]*media.Media, error) {
+ medias := make([]*Media, 0)
+ result := self.db.
+ WithContext(ctx).
+ Model(&Media{}).
+ Offset(pagination.Page * pagination.Size).
+ Limit(pagination.Size).
+ Order("created_at DESC").
+ Find(&medias)
+
+ if result.Error != nil {
+ return nil, result.Error
+ }
+
+ m := list.Map(medias, func(s *Media) *media.Media {
+ return s.ToModel()
+ })
+
+ return m, nil
+}
+
+func (self *MediaRepository) Get(ctx context.Context, pathHash string) (*media.Media, error) {
+ m := &Media{}
+ result := self.db.
+ WithContext(ctx).
+ Model(&Media{}).
+ Where("path_hash = ?", pathHash).
+ Limit(1).
+ Take(m)
+
+ if result.Error != nil {
+ return nil, result.Error
+ }
+
+ return m.ToModel(), nil
+}
+
+func (self *MediaRepository) GetPath(ctx context.Context, pathHash string) (string, error) {
+ var path string
+ result := self.db.
+ WithContext(ctx).
+ Model(&Media{}).
+ Select("path").
+ Where("path_hash = ?", pathHash).
+ Limit(1).
+ Find(&path)
+
+ if result.Error != nil {
+ return "", result.Error
+ }
+
+ return path, nil
+}
+
+func (m *MediaRepository) GetEXIF(ctx context.Context, mediaID uint) (*media.MediaEXIF, error) {
+ exif := &MediaEXIF{}
+ result := m.db.
+ WithContext(ctx).
+ Model(&Media{}).
+ Where("media_id = ?", mediaID).
+ Limit(1).
+ Take(m)
+
+ if result.Error != nil {
+ return nil, result.Error
+ }
+
+ return exif.ToModel(), nil
+}
+
+func (s *MediaRepository) CreateEXIF(ctx context.Context, id uint, info *media.MediaEXIF) error {
+ media := &MediaEXIF{
+ MediaID: id,
+ Description: info.Description,
+ Camera: info.Camera,
+ Maker: info.Maker,
+ Lens: info.Lens,
+ DateShot: info.DateShot,
+ Exposure: info.Exposure,
+ Aperture: info.Aperture,
+ Iso: info.Iso,
+ FocalLength: info.FocalLength,
+ Flash: info.Flash,
+ Orientation: info.Orientation,
+ ExposureProgram: info.ExposureProgram,
+ GPSLatitude: info.GPSLatitude,
+ GPSLongitude: info.GPSLongitude,
+ }
+
+ result := s.db.
+ WithContext(ctx).
+ Create(media)
+ if result.Error != nil {
+ return result.Error
+ }
+
+ return nil
+}
+
+func (r *MediaRepository) GetEmptyEXIF(ctx context.Context, pagination *media.Pagination) ([]*media.Media, error) {
+ medias := make([]*Media, 0)
+ result := r.db.
+ WithContext(ctx).
+ Model(&Media{}).
+ Joins("left join media_exifs on media.id = media_exifs.media_id").
+ Where("media_exifs.media_id IS NULL").
+ Offset(pagination.Page * pagination.Size).
+ Limit(pagination.Size).
+ Order("created_at DESC").
+ Find(&medias)
+
+ if result.Error != nil {
+ return nil, result.Error
+ }
+
+ m := list.Map(medias, func(s *Media) *media.Media {
+ return s.ToModel()
+ })
+
+ return m, nil
+}