Backend: Code clean-up #225
Signed-off-by: Michael Mayer <michael@liquidbytes.net>
This commit is contained in:
parent
a28144f953
commit
c98ed8a125
17 changed files with 186 additions and 185 deletions
|
@ -2,10 +2,10 @@ package form
|
|||
|
||||
// AccountSearch represents search form fields for "/api/v1/accounts".
|
||||
type AccountSearch struct {
|
||||
Query string `form:"q"`
|
||||
Count int `form:"count" binding:"required"`
|
||||
Offset int `form:"offset"`
|
||||
Order string `form:"order"`
|
||||
Query string `form:"q"`
|
||||
Count int `form:"count" binding:"required"`
|
||||
Offset int `form:"offset"`
|
||||
Order string `form:"order"`
|
||||
}
|
||||
|
||||
func (f *AccountSearch) GetQuery() string {
|
||||
|
|
|
@ -5,9 +5,9 @@ import (
|
|||
"github.com/photoprism/photoprism/internal/form"
|
||||
)
|
||||
|
||||
// FindAccounts returns a list of accounts.
|
||||
func (s *Query) Accounts(f form.AccountSearch) (result []entity.Account, err error) {
|
||||
if err := s.db.Where(&entity.Account{}).Limit(f.Count).Offset(f.Offset).Find(&result).Error; err != nil {
|
||||
// Accounts returns a list of accounts.
|
||||
func (q *Query) Accounts(f form.AccountSearch) (result []entity.Account, err error) {
|
||||
if err := q.db.Where(&entity.Account{}).Limit(f.Count).Offset(f.Offset).Find(&result).Error; err != nil {
|
||||
return result, err
|
||||
}
|
||||
|
||||
|
@ -15,8 +15,8 @@ func (s *Query) Accounts(f form.AccountSearch) (result []entity.Account, err err
|
|||
}
|
||||
|
||||
// AccountByID finds an account by primary key.
|
||||
func (s *Query) AccountByID(id uint) (result entity.Account, err error) {
|
||||
if err := s.db.Where("id = ?", id).First(&result).Error; err != nil {
|
||||
func (q *Query) AccountByID(id uint) (result entity.Account, err error) {
|
||||
if err := q.db.Where("id = ?", id).First(&result).Error; err != nil {
|
||||
return result, err
|
||||
}
|
||||
|
||||
|
|
|
@ -26,8 +26,8 @@ type AlbumResult struct {
|
|||
}
|
||||
|
||||
// AlbumByUUID returns a Album based on the UUID.
|
||||
func (s *Query) AlbumByUUID(albumUUID string) (album entity.Album, err error) {
|
||||
if err := s.db.Where("album_uuid = ?", albumUUID).First(&album).Error; err != nil {
|
||||
func (q *Query) AlbumByUUID(albumUUID string) (album entity.Album, err error) {
|
||||
if err := q.db.Where("album_uuid = ?", albumUUID).First(&album).Error; err != nil {
|
||||
return album, err
|
||||
}
|
||||
|
||||
|
@ -35,10 +35,10 @@ func (s *Query) AlbumByUUID(albumUUID string) (album entity.Album, err error) {
|
|||
}
|
||||
|
||||
// AlbumThumbByUUID returns a album preview file based on the uuid.
|
||||
func (s *Query) AlbumThumbByUUID(albumUUID string) (file entity.File, err error) {
|
||||
// s.db.LogMode(true)
|
||||
func (q *Query) AlbumThumbByUUID(albumUUID string) (file entity.File, err error) {
|
||||
// q.db.LogMode(true)
|
||||
|
||||
if err := s.db.Where("files.file_primary AND files.deleted_at IS NULL").
|
||||
if err := q.db.Where("files.file_primary AND files.deleted_at IS NULL").
|
||||
Joins("JOIN albums ON albums.album_uuid = ?", albumUUID).
|
||||
Joins("JOIN photos_albums pa ON pa.album_uuid = albums.album_uuid AND pa.photo_uuid = files.photo_uuid").
|
||||
First(&file).Error; err != nil {
|
||||
|
@ -49,25 +49,25 @@ func (s *Query) AlbumThumbByUUID(albumUUID string) (file entity.File, err error)
|
|||
}
|
||||
|
||||
// Albums searches albums based on their name.
|
||||
func (s *Query) Albums(f form.AlbumSearch) (results []AlbumResult, err error) {
|
||||
func (q *Query) Albums(f form.AlbumSearch) (results []AlbumResult, err error) {
|
||||
if err := f.ParseQueryString(); err != nil {
|
||||
return results, err
|
||||
}
|
||||
|
||||
defer log.Debug(capture.Time(time.Now(), fmt.Sprintf("albums: %+v", f)))
|
||||
|
||||
q := s.db.NewScope(nil).DB()
|
||||
s := q.db.NewScope(nil).DB()
|
||||
|
||||
q = q.Table("albums").
|
||||
s = s.Table("albums").
|
||||
Select(`albums.*, COUNT(photos_albums.album_uuid) AS album_count`).
|
||||
Joins("LEFT JOIN photos_albums ON photos_albums.album_uuid = albums.album_uuid").
|
||||
Where("albums.deleted_at IS NULL").
|
||||
Group("albums.id")
|
||||
|
||||
if f.ID != "" {
|
||||
q = q.Where("albums.album_uuid = ?", f.ID)
|
||||
s = s.Where("albums.album_uuid = ?", f.ID)
|
||||
|
||||
if result := q.Scan(&results); result.Error != nil {
|
||||
if result := s.Scan(&results); result.Error != nil {
|
||||
return results, result.Error
|
||||
}
|
||||
|
||||
|
@ -76,27 +76,27 @@ func (s *Query) Albums(f form.AlbumSearch) (results []AlbumResult, err error) {
|
|||
|
||||
if f.Query != "" {
|
||||
likeString := "%" + strings.ToLower(f.Query) + "%"
|
||||
q = q.Where("LOWER(albums.album_name) LIKE ?", likeString)
|
||||
s = s.Where("LOWER(albums.album_name) LIKE ?", likeString)
|
||||
}
|
||||
|
||||
if f.Favorites {
|
||||
q = q.Where("albums.album_favorite = 1")
|
||||
s = s.Where("albums.album_favorite = 1")
|
||||
}
|
||||
|
||||
switch f.Order {
|
||||
case "slug":
|
||||
q = q.Order("albums.album_favorite DESC, album_slug ASC")
|
||||
s = s.Order("albums.album_favorite DESC, album_slug ASC")
|
||||
default:
|
||||
q = q.Order("albums.album_favorite DESC, album_count DESC, albums.created_at DESC")
|
||||
s = s.Order("albums.album_favorite DESC, album_count DESC, albums.created_at DESC")
|
||||
}
|
||||
|
||||
if f.Count > 0 && f.Count <= 1000 {
|
||||
q = q.Limit(f.Count).Offset(f.Offset)
|
||||
s = s.Limit(f.Count).Offset(f.Offset)
|
||||
} else {
|
||||
q = q.Limit(100).Offset(0)
|
||||
s = s.Limit(100).Offset(0)
|
||||
}
|
||||
|
||||
if result := q.Scan(&results); result.Error != nil {
|
||||
if result := s.Scan(&results); result.Error != nil {
|
||||
return results, result.Error
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
"github.com/photoprism/photoprism/internal/config"
|
||||
)
|
||||
|
||||
func TestRepo_FindAlbumByUUID(t *testing.T) {
|
||||
func TestQuery_AlbumByUUID(t *testing.T) {
|
||||
conf := config.TestConfig()
|
||||
|
||||
search := New(conf.Db())
|
||||
|
@ -26,7 +26,7 @@ func TestRepo_FindAlbumByUUID(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestRepo_FindAlbumThumbByUUID(t *testing.T) {
|
||||
func TestQuery_AlbumThumbByUUID(t *testing.T) {
|
||||
conf := config.TestConfig()
|
||||
|
||||
search := New(conf.Db())
|
||||
|
@ -44,7 +44,7 @@ func TestRepo_FindAlbumThumbByUUID(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestRepo_Albums(t *testing.T) {
|
||||
func TestQuery_Albums(t *testing.T) {
|
||||
conf := config.TestConfig()
|
||||
|
||||
search := New(conf.Db())
|
||||
|
|
|
@ -9,16 +9,16 @@ type CategoryLabel struct {
|
|||
Title string
|
||||
}
|
||||
|
||||
func (s *Query) CategoryLabels(limit, offset int) (results []CategoryLabel) {
|
||||
q := s.db.NewScope(nil).DB()
|
||||
func (q *Query) CategoryLabels(limit, offset int) (results []CategoryLabel) {
|
||||
s := q.db.NewScope(nil).DB()
|
||||
|
||||
q = q.Table("categories").
|
||||
s = s.Table("categories").
|
||||
Select("label_name AS name").
|
||||
Joins("JOIN labels l ON categories.category_id = l.id").
|
||||
Group("label_name").
|
||||
Limit(limit).Offset(offset)
|
||||
|
||||
if err := q.Scan(&results).Error; err != nil {
|
||||
if err := s.Scan(&results).Error; err != nil {
|
||||
log.Errorf("categories: %s", err.Error())
|
||||
return results
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"github.com/photoprism/photoprism/internal/config"
|
||||
)
|
||||
|
||||
func TestRepo_CategoryLabels(t *testing.T) {
|
||||
func TestQuery_CategoryLabels(t *testing.T) {
|
||||
conf := config.TestConfig()
|
||||
|
||||
search := New(conf.Db())
|
||||
|
|
|
@ -4,8 +4,8 @@ import "github.com/photoprism/photoprism/internal/entity"
|
|||
|
||||
// Files finds files returning maximum results defined by limit
|
||||
// and finding them from an offest defined by offset.
|
||||
func (s *Query) Files(limit int, offset int) (files []entity.File, err error) {
|
||||
if err := s.db.Where(&entity.File{}).Limit(limit).Offset(offset).Find(&files).Error; err != nil {
|
||||
func (q *Query) Files(limit int, offset int) (files []entity.File, err error) {
|
||||
if err := q.db.Where(&entity.File{}).Limit(limit).Offset(offset).Find(&files).Error; err != nil {
|
||||
return files, err
|
||||
}
|
||||
|
||||
|
@ -13,8 +13,8 @@ func (s *Query) Files(limit int, offset int) (files []entity.File, err error) {
|
|||
}
|
||||
|
||||
// FilesByUUID
|
||||
func (s *Query) FilesByUUID(u []string, limit int, offset int) (files []entity.File, err error) {
|
||||
if err := s.db.Where("(photo_uuid IN (?) AND file_primary = 1) OR file_uuid IN (?)", u, u).Preload("Photo").Limit(limit).Offset(offset).Find(&files).Error; err != nil {
|
||||
func (q *Query) FilesByUUID(u []string, limit int, offset int) (files []entity.File, err error) {
|
||||
if err := q.db.Where("(photo_uuid IN (?) AND file_primary = 1) OR file_uuid IN (?)", u, u).Preload("Photo").Limit(limit).Offset(offset).Find(&files).Error; err != nil {
|
||||
return files, err
|
||||
}
|
||||
|
||||
|
@ -22,8 +22,8 @@ func (s *Query) FilesByUUID(u []string, limit int, offset int) (files []entity.F
|
|||
}
|
||||
|
||||
// FileByPhotoUUID
|
||||
func (s *Query) FileByPhotoUUID(u string) (file entity.File, err error) {
|
||||
if err := s.db.Where("photo_uuid = ? AND file_primary = 1", u).Preload("Photo").First(&file).Error; err != nil {
|
||||
func (q *Query) FileByPhotoUUID(u string) (file entity.File, err error) {
|
||||
if err := q.db.Where("photo_uuid = ? AND file_primary = 1", u).Preload("Photo").First(&file).Error; err != nil {
|
||||
return file, err
|
||||
}
|
||||
|
||||
|
@ -31,8 +31,8 @@ func (s *Query) FileByPhotoUUID(u string) (file entity.File, err error) {
|
|||
}
|
||||
|
||||
// FileByID returns a MediaFile given a certain ID.
|
||||
func (s *Query) FileByID(id string) (file entity.File, err error) {
|
||||
if err := s.db.Where("id = ?", id).Preload("Photo").First(&file).Error; err != nil {
|
||||
func (q *Query) FileByID(id string) (file entity.File, err error) {
|
||||
if err := q.db.Where("id = ?", id).Preload("Photo").First(&file).Error; err != nil {
|
||||
return file, err
|
||||
}
|
||||
|
||||
|
@ -40,8 +40,8 @@ func (s *Query) FileByID(id string) (file entity.File, err error) {
|
|||
}
|
||||
|
||||
// FirstFileByHash finds a file with a given hash string.
|
||||
func (s *Query) FileByHash(fileHash string) (file entity.File, err error) {
|
||||
if err := s.db.Where("file_hash = ?", fileHash).Preload("Photo").First(&file).Error; err != nil {
|
||||
func (q *Query) FileByHash(fileHash string) (file entity.File, err error) {
|
||||
if err := q.db.Where("file_hash = ?", fileHash).Preload("Photo").First(&file).Error; err != nil {
|
||||
return file, err
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"github.com/photoprism/photoprism/internal/config"
|
||||
)
|
||||
|
||||
func TestRepo_FindFiles(t *testing.T) {
|
||||
func TestQuery_Files(t *testing.T) {
|
||||
conf := config.TestConfig()
|
||||
|
||||
search := New(conf.Db())
|
||||
|
@ -20,7 +20,7 @@ func TestRepo_FindFiles(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestRepo_FindFilesByUUID(t *testing.T) {
|
||||
func TestQuery_FilesByUUID(t *testing.T) {
|
||||
conf := config.TestConfig()
|
||||
|
||||
search := New(conf.Db())
|
||||
|
@ -34,7 +34,7 @@ func TestRepo_FindFilesByUUID(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestRepo_FindFileByPhotoUUID(t *testing.T) {
|
||||
func TestQuery_FileByPhotoUUID(t *testing.T) {
|
||||
conf := config.TestConfig()
|
||||
|
||||
search := New(conf.Db())
|
||||
|
@ -54,7 +54,7 @@ func TestRepo_FindFileByPhotoUUID(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestRepo_FindFileByID(t *testing.T) {
|
||||
func TestQuery_FileByID(t *testing.T) {
|
||||
conf := config.TestConfig()
|
||||
|
||||
search := New(conf.Db())
|
||||
|
@ -74,7 +74,7 @@ func TestRepo_FindFileByID(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestRepo_FindFileByHash(t *testing.T) {
|
||||
func TestQuery_FileByHash(t *testing.T) {
|
||||
conf := config.TestConfig()
|
||||
|
||||
search := New(conf.Db())
|
||||
|
|
|
@ -25,16 +25,16 @@ type GeoResult struct {
|
|||
}
|
||||
|
||||
// Geo searches for photos based on a Form and returns a PhotoResult slice.
|
||||
func (s *Query) Geo(f form.GeoSearch) (results []GeoResult, err error) {
|
||||
func (q *Query) Geo(f form.GeoSearch) (results []GeoResult, err error) {
|
||||
if err := f.ParseQueryString(); err != nil {
|
||||
return results, err
|
||||
}
|
||||
|
||||
defer log.Debug(capture.Time(time.Now(), fmt.Sprintf("search: %+v", f)))
|
||||
|
||||
q := s.db.NewScope(nil).DB()
|
||||
s := q.db.NewScope(nil).DB()
|
||||
|
||||
q = q.Table("photos").
|
||||
s = s.Table("photos").
|
||||
Select(`photos.id, photos.photo_uuid, photos.photo_lat, photos.photo_lng, photos.photo_title, photos.taken_at,
|
||||
files.file_hash, files.file_width, files.file_height`).
|
||||
Joins(`JOIN files ON files.photo_id = photos.id
|
||||
|
@ -44,43 +44,43 @@ func (s *Query) Geo(f form.GeoSearch) (results []GeoResult, err error) {
|
|||
Group("photos.id, files.id")
|
||||
|
||||
if f.Query != "" {
|
||||
q = q.Joins("LEFT JOIN photos_keywords ON photos_keywords.photo_id = photos.id").
|
||||
s = s.Joins("LEFT JOIN photos_keywords ON photos_keywords.photo_id = photos.id").
|
||||
Joins("LEFT JOIN keywords ON photos_keywords.keyword_id = keywords.id").
|
||||
Where("keywords.keyword LIKE ?", strings.ToLower(f.Query)+"%")
|
||||
}
|
||||
|
||||
if f.S2 != "" {
|
||||
s2Min, s2Max := s2.Range(f.S2, 7)
|
||||
q = q.Where("photos.location_id BETWEEN ? AND ?", s2Min, s2Max)
|
||||
s = s.Where("photos.location_id BETWEEN ? AND ?", s2Min, s2Max)
|
||||
} else if f.Olc != "" {
|
||||
s2Min, s2Max := s2.Range(pluscode.S2(f.Olc), 7)
|
||||
q = q.Where("photos.location_id BETWEEN ? AND ?", s2Min, s2Max)
|
||||
s = s.Where("photos.location_id BETWEEN ? AND ?", s2Min, s2Max)
|
||||
} else {
|
||||
// Inaccurate distance search, but probably 'good enough' for now
|
||||
if f.Lat > 0 {
|
||||
latMin := f.Lat - SearchRadius*float64(f.Dist)
|
||||
latMax := f.Lat + SearchRadius*float64(f.Dist)
|
||||
q = q.Where("photos.photo_lat BETWEEN ? AND ?", latMin, latMax)
|
||||
s = s.Where("photos.photo_lat BETWEEN ? AND ?", latMin, latMax)
|
||||
}
|
||||
|
||||
if f.Lng > 0 {
|
||||
lngMin := f.Lng - SearchRadius*float64(f.Dist)
|
||||
lngMax := f.Lng + SearchRadius*float64(f.Dist)
|
||||
q = q.Where("photos.photo_lng BETWEEN ? AND ?", lngMin, lngMax)
|
||||
s = s.Where("photos.photo_lng BETWEEN ? AND ?", lngMin, lngMax)
|
||||
}
|
||||
}
|
||||
|
||||
if !f.Before.IsZero() {
|
||||
q = q.Where("photos.taken_at <= ?", f.Before.Format("2006-01-02"))
|
||||
s = s.Where("photos.taken_at <= ?", f.Before.Format("2006-01-02"))
|
||||
}
|
||||
|
||||
if !f.After.IsZero() {
|
||||
q = q.Where("photos.taken_at >= ?", f.After.Format("2006-01-02"))
|
||||
s = s.Where("photos.taken_at >= ?", f.After.Format("2006-01-02"))
|
||||
}
|
||||
|
||||
q = q.Order("taken_at, photos.photo_uuid")
|
||||
s = s.Order("taken_at, photos.photo_uuid")
|
||||
|
||||
if result := q.Scan(&results); result.Error != nil {
|
||||
if result := s.Scan(&results); result.Error != nil {
|
||||
return results, result.Error
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
"github.com/photoprism/photoprism/internal/config"
|
||||
)
|
||||
|
||||
func TestRepo_Geo(t *testing.T) {
|
||||
func TestQuery_Geo(t *testing.T) {
|
||||
conf := config.TestConfig()
|
||||
|
||||
search := New(conf.Db())
|
||||
|
|
|
@ -29,8 +29,8 @@ type LabelResult struct {
|
|||
}
|
||||
|
||||
// LabelBySlug returns a Label based on the slug name.
|
||||
func (s *Query) LabelBySlug(labelSlug string) (label entity.Label, err error) {
|
||||
if err := s.db.Where("label_slug = ?", labelSlug).First(&label).Error; err != nil {
|
||||
func (q *Query) LabelBySlug(labelSlug string) (label entity.Label, err error) {
|
||||
if err := q.db.Where("label_slug = ?", labelSlug).First(&label).Error; err != nil {
|
||||
return label, err
|
||||
}
|
||||
|
||||
|
@ -38,8 +38,8 @@ func (s *Query) LabelBySlug(labelSlug string) (label entity.Label, err error) {
|
|||
}
|
||||
|
||||
// LabelByUUID returns a Label based on the label UUID.
|
||||
func (s *Query) LabelByUUID(labelUUID string) (label entity.Label, err error) {
|
||||
if err := s.db.Where("label_uuid = ?", labelUUID).First(&label).Error; err != nil {
|
||||
func (q *Query) LabelByUUID(labelUUID string) (label entity.Label, err error) {
|
||||
if err := q.db.Where("label_uuid = ?", labelUUID).First(&label).Error; err != nil {
|
||||
return label, err
|
||||
}
|
||||
|
||||
|
@ -47,10 +47,10 @@ func (s *Query) LabelByUUID(labelUUID string) (label entity.Label, err error) {
|
|||
}
|
||||
|
||||
// LabelThumbBySlug returns a label preview file based on the slug name.
|
||||
func (s *Query) LabelThumbBySlug(labelSlug string) (file entity.File, err error) {
|
||||
// s.db.LogMode(true)
|
||||
func (q *Query) LabelThumbBySlug(labelSlug string) (file entity.File, err error) {
|
||||
// q.db.LogMode(true)
|
||||
|
||||
if err := s.db.Where("files.file_primary AND files.deleted_at IS NULL").
|
||||
if err := q.db.Where("files.file_primary AND files.deleted_at IS NULL").
|
||||
Joins("JOIN labels ON labels.label_slug = ?", labelSlug).
|
||||
Joins("JOIN photos_labels ON photos_labels.label_id = labels.id AND photos_labels.photo_id = files.photo_id").
|
||||
Order("photos_labels.label_uncertainty ASC").
|
||||
|
@ -62,9 +62,9 @@ func (s *Query) LabelThumbBySlug(labelSlug string) (file entity.File, err error)
|
|||
}
|
||||
|
||||
// LabelThumbByUUID returns a label preview file based on the label UUID.
|
||||
func (s *Query) LabelThumbByUUID(labelUUID string) (file entity.File, err error) {
|
||||
func (q *Query) LabelThumbByUUID(labelUUID string) (file entity.File, err error) {
|
||||
// Search matching label
|
||||
err = s.db.Where("files.file_primary AND files.deleted_at IS NULL").
|
||||
err = q.db.Where("files.file_primary AND files.deleted_at IS NULL").
|
||||
Joins("JOIN labels ON labels.label_uuid = ?", labelUUID).
|
||||
Joins("JOIN photos_labels ON photos_labels.label_id = labels.id AND photos_labels.photo_id = files.photo_id").
|
||||
Order("photos_labels.label_uncertainty ASC").
|
||||
|
@ -75,7 +75,7 @@ func (s *Query) LabelThumbByUUID(labelUUID string) (file entity.File, err error)
|
|||
}
|
||||
|
||||
// If failed, search for category instead
|
||||
err = s.db.Where("files.file_primary AND files.deleted_at IS NULL").
|
||||
err = q.db.Where("files.file_primary AND files.deleted_at IS NULL").
|
||||
Joins("JOIN photos_labels ON photos_labels.photo_id = files.photo_id").
|
||||
Joins("JOIN categories c ON photos_labels.label_id = c.label_id").
|
||||
Joins("JOIN labels ON c.category_id = labels.id AND labels.label_uuid= ?", labelUUID).
|
||||
|
@ -86,26 +86,26 @@ func (s *Query) LabelThumbByUUID(labelUUID string) (file entity.File, err error)
|
|||
}
|
||||
|
||||
// Labels searches labels based on their name.
|
||||
func (s *Query) Labels(f form.LabelSearch) (results []LabelResult, err error) {
|
||||
func (q *Query) Labels(f form.LabelSearch) (results []LabelResult, err error) {
|
||||
if err := f.ParseQueryString(); err != nil {
|
||||
return results, err
|
||||
}
|
||||
|
||||
defer log.Debug(capture.Time(time.Now(), fmt.Sprintf("labels: %+v", f)))
|
||||
|
||||
q := s.db.NewScope(nil).DB()
|
||||
s := q.db.NewScope(nil).DB()
|
||||
|
||||
// q.LogMode(true)
|
||||
// s.LogMode(true)
|
||||
|
||||
q = q.Table("labels").
|
||||
s = s.Table("labels").
|
||||
Select(`labels.*`).
|
||||
Where("labels.deleted_at IS NULL").
|
||||
Group("labels.id")
|
||||
|
||||
if f.ID != "" {
|
||||
q = q.Where("labels.label_uuid = ?", f.ID)
|
||||
s = s.Where("labels.label_uuid = ?", f.ID)
|
||||
|
||||
if result := q.Scan(&results); result.Error != nil {
|
||||
if result := s.Scan(&results); result.Error != nil {
|
||||
return results, result.Error
|
||||
}
|
||||
|
||||
|
@ -120,14 +120,14 @@ func (s *Query) Labels(f form.LabelSearch) (results []LabelResult, err error) {
|
|||
slugString := slug.Make(f.Query)
|
||||
likeString := "%" + strings.ToLower(f.Query) + "%"
|
||||
|
||||
if result := s.db.First(&label, "label_slug = ?", slugString); result.Error != nil {
|
||||
if result := q.db.First(&label, "label_slug = ?", slugString); result.Error != nil {
|
||||
log.Infof("search: label \"%s\" not found", f.Query)
|
||||
|
||||
q = q.Where("LOWER(labels.label_name) LIKE ?", likeString)
|
||||
s = s.Where("LOWER(labels.label_name) LIKE ?", likeString)
|
||||
} else {
|
||||
labelIds = append(labelIds, label.ID)
|
||||
|
||||
s.db.Where("category_id = ?", label.ID).Find(&categories)
|
||||
q.db.Where("category_id = ?", label.ID).Find(&categories)
|
||||
|
||||
for _, category := range categories {
|
||||
labelIds = append(labelIds, category.LabelID)
|
||||
|
@ -135,32 +135,32 @@ func (s *Query) Labels(f form.LabelSearch) (results []LabelResult, err error) {
|
|||
|
||||
log.Infof("search: label \"%s\" includes %d categories", label.LabelName, len(labelIds))
|
||||
|
||||
q = q.Where("labels.id IN (?)", labelIds)
|
||||
s = s.Where("labels.id IN (?)", labelIds)
|
||||
}
|
||||
}
|
||||
|
||||
if f.Favorites {
|
||||
q = q.Where("labels.label_favorite = 1")
|
||||
s = s.Where("labels.label_favorite = 1")
|
||||
}
|
||||
|
||||
if !f.All {
|
||||
q = q.Where("labels.label_priority >= 0 OR labels.label_favorite = 1")
|
||||
s = s.Where("labels.label_priority >= 0 OR labels.label_favorite = 1")
|
||||
}
|
||||
|
||||
switch f.Order {
|
||||
case "slug":
|
||||
q = q.Order("labels.label_favorite DESC, label_slug ASC")
|
||||
s = s.Order("labels.label_favorite DESC, label_slug ASC")
|
||||
default:
|
||||
q = q.Order("labels.label_favorite DESC, label_slug ASC")
|
||||
s = s.Order("labels.label_favorite DESC, label_slug ASC")
|
||||
}
|
||||
|
||||
if f.Count > 0 && f.Count <= 1000 {
|
||||
q = q.Limit(f.Count).Offset(f.Offset)
|
||||
s = s.Limit(f.Count).Offset(f.Offset)
|
||||
} else {
|
||||
q = q.Limit(100).Offset(0)
|
||||
s = s.Limit(100).Offset(0)
|
||||
}
|
||||
|
||||
if result := q.Scan(&results); result.Error != nil {
|
||||
if result := s.Scan(&results); result.Error != nil {
|
||||
return results, result.Error
|
||||
}
|
||||
|
||||
|
|
|
@ -8,94 +8,94 @@ import (
|
|||
"github.com/photoprism/photoprism/internal/config"
|
||||
)
|
||||
|
||||
func TestRepo_FindLabelBySlug(t *testing.T) {
|
||||
func TestQuery_LabelBySlug(t *testing.T) {
|
||||
conf := config.TestConfig()
|
||||
|
||||
search := New(conf.Db())
|
||||
q := New(conf.Db())
|
||||
|
||||
t.Run("files found", func(t *testing.T) {
|
||||
label, err := search.LabelBySlug("flower")
|
||||
label, err := q.LabelBySlug("flower")
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "Flower", label.LabelName)
|
||||
})
|
||||
|
||||
t.Run("no files found", func(t *testing.T) {
|
||||
label, err := search.LabelBySlug("111")
|
||||
label, err := q.LabelBySlug("111")
|
||||
|
||||
assert.Error(t, err, "record not found")
|
||||
t.Log(label)
|
||||
})
|
||||
}
|
||||
|
||||
func TestRepo_FindLabelByUUID(t *testing.T) {
|
||||
func TestQuery_LabelByUUID(t *testing.T) {
|
||||
conf := config.TestConfig()
|
||||
|
||||
search := New(conf.Db())
|
||||
q := New(conf.Db())
|
||||
|
||||
t.Run("files found", func(t *testing.T) {
|
||||
label, err := search.LabelByUUID("14")
|
||||
label, err := q.LabelByUUID("14")
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "COW", label.LabelName)
|
||||
})
|
||||
|
||||
t.Run("no files found", func(t *testing.T) {
|
||||
label, err := search.LabelByUUID("111")
|
||||
label, err := q.LabelByUUID("111")
|
||||
|
||||
assert.Error(t, err, "record not found")
|
||||
t.Log(label)
|
||||
})
|
||||
}
|
||||
|
||||
func TestRepo_FindLabelThumbBySlug(t *testing.T) {
|
||||
func TestQuery_LabelThumbBySlug(t *testing.T) {
|
||||
conf := config.TestConfig()
|
||||
|
||||
search := New(conf.Db())
|
||||
q := New(conf.Db())
|
||||
|
||||
t.Run("files found", func(t *testing.T) {
|
||||
file, err := search.LabelThumbBySlug("flower")
|
||||
file, err := q.LabelThumbBySlug("flower")
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "exampleFileName.jpg", file.FileName)
|
||||
})
|
||||
|
||||
t.Run("no files found", func(t *testing.T) {
|
||||
file, err := search.LabelThumbBySlug("cow")
|
||||
file, err := q.LabelThumbBySlug("cow")
|
||||
|
||||
assert.Error(t, err, "record not found")
|
||||
t.Log(file)
|
||||
})
|
||||
}
|
||||
|
||||
func TestRepo_FindLabelThumbByUUID(t *testing.T) {
|
||||
func TestQuery_LabelThumbByUUID(t *testing.T) {
|
||||
conf := config.TestConfig()
|
||||
|
||||
search := New(conf.Db())
|
||||
q := New(conf.Db())
|
||||
|
||||
t.Run("files found", func(t *testing.T) {
|
||||
file, err := search.LabelThumbByUUID("13")
|
||||
file, err := q.LabelThumbByUUID("13")
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "exampleFileName.jpg", file.FileName)
|
||||
})
|
||||
|
||||
t.Run("no files found", func(t *testing.T) {
|
||||
file, err := search.LabelThumbByUUID("14")
|
||||
file, err := q.LabelThumbByUUID("14")
|
||||
|
||||
assert.Error(t, err, "record not found")
|
||||
t.Log(file)
|
||||
})
|
||||
}
|
||||
|
||||
func TestRepo_Labels(t *testing.T) {
|
||||
func TestQuery_Labels(t *testing.T) {
|
||||
conf := config.TestConfig()
|
||||
|
||||
search := New(conf.Db())
|
||||
q := New(conf.Db())
|
||||
|
||||
t.Run("search with query", func(t *testing.T) {
|
||||
query := form.NewLabelSearch("Query:C Count:1005 Order:slug")
|
||||
result, err := search.Labels(query)
|
||||
result, err := q.Labels(query)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 2, len(result))
|
||||
|
@ -105,7 +105,7 @@ func TestRepo_Labels(t *testing.T) {
|
|||
|
||||
t.Run("search for favorites", func(t *testing.T) {
|
||||
query := form.NewLabelSearch("Favorites:true")
|
||||
result, err := search.Labels(query)
|
||||
result, err := q.Labels(query)
|
||||
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 2, len(result))
|
||||
|
@ -115,14 +115,14 @@ func TestRepo_Labels(t *testing.T) {
|
|||
|
||||
t.Run("search with empty query", func(t *testing.T) {
|
||||
query := form.NewLabelSearch("")
|
||||
result, err := search.Labels(query)
|
||||
result, err := q.Labels(query)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 3, len(result))
|
||||
})
|
||||
|
||||
t.Run("search with invalid query string", func(t *testing.T) {
|
||||
query := form.NewLabelSearch("xxx:bla")
|
||||
result, err := search.Labels(query)
|
||||
result, err := q.Labels(query)
|
||||
assert.Error(t, err, "unknown filter")
|
||||
t.Log(result)
|
||||
})
|
||||
|
|
|
@ -8,16 +8,16 @@ type MomentsTimeResult struct {
|
|||
}
|
||||
|
||||
// GetMomentsTime counts photos per month and year
|
||||
func (s *Query) GetMomentsTime() (results []MomentsTimeResult, err error) {
|
||||
q := s.db.NewScope(nil).DB()
|
||||
func (q *Query) GetMomentsTime() (results []MomentsTimeResult, err error) {
|
||||
s := q.db.NewScope(nil).DB()
|
||||
|
||||
q = q.Table("photos").
|
||||
s = s.Table("photos").
|
||||
Where("deleted_at IS NULL").
|
||||
Select("photos.photo_year, photos.photo_month, COUNT(*) AS count").
|
||||
Group("photos.photo_year, photos.photo_month").
|
||||
Order("photos.photo_year DESC, photos.photo_month DESC")
|
||||
|
||||
if result := q.Scan(&results); result.Error != nil {
|
||||
if result := s.Scan(&results); result.Error != nil {
|
||||
return results, result.Error
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"github.com/photoprism/photoprism/internal/config"
|
||||
)
|
||||
|
||||
func TestRepo_GetMomentsTime(t *testing.T) {
|
||||
func TestQuery_GetMomentsTime(t *testing.T) {
|
||||
conf := config.TestConfig()
|
||||
|
||||
search := New(conf.Db())
|
||||
|
|
|
@ -94,18 +94,18 @@ func (m *PhotoResult) DownloadFileName() string {
|
|||
}
|
||||
|
||||
// Photos searches for photos based on a Form and returns a PhotoResult slice.
|
||||
func (s *Query) Photos(f form.PhotoSearch) (results []PhotoResult, err error) {
|
||||
func (q *Query) Photos(f form.PhotoSearch) (results []PhotoResult, err error) {
|
||||
if err := f.ParseQueryString(); err != nil {
|
||||
return results, err
|
||||
}
|
||||
|
||||
defer log.Debug(capture.Time(time.Now(), fmt.Sprintf("photos: %+v", f)))
|
||||
|
||||
q := s.db.NewScope(nil).DB()
|
||||
s := q.db.NewScope(nil).DB()
|
||||
|
||||
// q.LogMode(true)
|
||||
// s.LogMode(true)
|
||||
|
||||
q = q.Table("photos").
|
||||
s = s.Table("photos").
|
||||
Select(`photos.*,
|
||||
files.id AS file_id, files.file_uuid, files.file_primary, files.file_missing, files.file_name, files.file_hash,
|
||||
files.file_type, files.file_mime, files.file_width, files.file_height, files.file_aspect_ratio,
|
||||
|
@ -123,9 +123,9 @@ func (s *Query) Photos(f form.PhotoSearch) (results []PhotoResult, err error) {
|
|||
Group("photos.id, files.id")
|
||||
|
||||
if f.ID != "" {
|
||||
q = q.Where("photos.photo_uuid = ?", f.ID)
|
||||
s = s.Where("photos.photo_uuid = ?", f.ID)
|
||||
|
||||
if result := q.Scan(&results); result.Error != nil {
|
||||
if result := s.Scan(&results); result.Error != nil {
|
||||
return results, result.Error
|
||||
}
|
||||
|
||||
|
@ -137,27 +137,27 @@ func (s *Query) Photos(f form.PhotoSearch) (results []PhotoResult, err error) {
|
|||
var labelIds []uint
|
||||
|
||||
if f.Label != "" {
|
||||
if result := s.db.First(&label, "label_slug = ?", strings.ToLower(f.Label)); result.Error != nil {
|
||||
if result := q.db.First(&label, "label_slug = ?", strings.ToLower(f.Label)); result.Error != nil {
|
||||
log.Errorf("search: label \"%s\" not found", f.Label)
|
||||
return results, fmt.Errorf("label \"%s\" not found", f.Label)
|
||||
} else {
|
||||
labelIds = append(labelIds, label.ID)
|
||||
|
||||
s.db.Where("category_id = ?", label.ID).Find(&categories)
|
||||
q.db.Where("category_id = ?", label.ID).Find(&categories)
|
||||
|
||||
for _, category := range categories {
|
||||
labelIds = append(labelIds, category.LabelID)
|
||||
}
|
||||
|
||||
q = q.Where("photos_labels.label_id IN (?)", labelIds)
|
||||
s = s.Where("photos_labels.label_id IN (?)", labelIds)
|
||||
}
|
||||
}
|
||||
|
||||
if f.Location == true {
|
||||
q = q.Where("location_id > 0")
|
||||
s = s.Where("location_id > 0")
|
||||
|
||||
if f.Query != "" {
|
||||
q = q.Joins("LEFT JOIN photos_keywords ON photos_keywords.photo_id = photos.id").
|
||||
s = s.Joins("LEFT JOIN photos_keywords ON photos_keywords.photo_id = photos.id").
|
||||
Joins("LEFT JOIN keywords ON photos_keywords.keyword_id = keywords.id").
|
||||
Where("keywords.keyword LIKE ?", strings.ToLower(f.Query)+"%")
|
||||
}
|
||||
|
@ -170,17 +170,17 @@ func (s *Query) Photos(f form.PhotoSearch) (results []PhotoResult, err error) {
|
|||
lowerString := strings.ToLower(f.Query)
|
||||
likeString := lowerString + "%"
|
||||
|
||||
q = q.Joins("LEFT JOIN photos_keywords ON photos_keywords.photo_id = photos.id").
|
||||
s = s.Joins("LEFT JOIN photos_keywords ON photos_keywords.photo_id = photos.id").
|
||||
Joins("LEFT JOIN keywords ON photos_keywords.keyword_id = keywords.id")
|
||||
|
||||
if result := s.db.First(&label, "label_slug = ?", slugString); result.Error != nil {
|
||||
if result := q.db.First(&label, "label_slug = ?", slugString); result.Error != nil {
|
||||
log.Infof("search: label \"%s\" not found, using fuzzy search", f.Query)
|
||||
|
||||
q = q.Where("keywords.keyword LIKE ?", likeString)
|
||||
s = s.Where("keywords.keyword LIKE ?", likeString)
|
||||
} else {
|
||||
labelIds = append(labelIds, label.ID)
|
||||
|
||||
s.db.Where("category_id = ?", label.ID).Find(&categories)
|
||||
q.db.Where("category_id = ?", label.ID).Find(&categories)
|
||||
|
||||
for _, category := range categories {
|
||||
labelIds = append(labelIds, category.LabelID)
|
||||
|
@ -188,98 +188,98 @@ func (s *Query) Photos(f form.PhotoSearch) (results []PhotoResult, err error) {
|
|||
|
||||
log.Infof("search: label \"%s\" includes %d categories", label.LabelName, len(labelIds))
|
||||
|
||||
q = q.Where("photos_labels.label_id IN (?) OR keywords.keyword LIKE ?", labelIds, likeString)
|
||||
s = s.Where("photos_labels.label_id IN (?) OR keywords.keyword LIKE ?", labelIds, likeString)
|
||||
}
|
||||
}
|
||||
|
||||
if f.Archived {
|
||||
q = q.Where("photos.deleted_at IS NOT NULL")
|
||||
s = s.Where("photos.deleted_at IS NOT NULL")
|
||||
} else {
|
||||
q = q.Where("photos.deleted_at IS NULL")
|
||||
s = s.Where("photos.deleted_at IS NULL")
|
||||
}
|
||||
|
||||
if f.Error {
|
||||
q = q.Where("files.file_error <> ''")
|
||||
s = s.Where("files.file_error <> ''")
|
||||
}
|
||||
|
||||
if f.Album != "" {
|
||||
q = q.Joins("JOIN photos_albums ON photos_albums.photo_uuid = photos.photo_uuid").Where("photos_albums.album_uuid = ?", f.Album)
|
||||
s = s.Joins("JOIN photos_albums ON photos_albums.photo_uuid = photos.photo_uuid").Where("photos_albums.album_uuid = ?", f.Album)
|
||||
}
|
||||
|
||||
if f.Camera > 0 {
|
||||
q = q.Where("photos.camera_id = ?", f.Camera)
|
||||
s = s.Where("photos.camera_id = ?", f.Camera)
|
||||
}
|
||||
|
||||
if f.Lens > 0 {
|
||||
q = q.Where("photos.lens_id = ?", f.Lens)
|
||||
s = s.Where("photos.lens_id = ?", f.Lens)
|
||||
}
|
||||
|
||||
if f.Year > 0 {
|
||||
q = q.Where("photos.photo_year = ?", f.Year)
|
||||
s = s.Where("photos.photo_year = ?", f.Year)
|
||||
}
|
||||
|
||||
if f.Month > 0 {
|
||||
q = q.Where("photos.photo_month = ?", f.Month)
|
||||
s = s.Where("photos.photo_month = ?", f.Month)
|
||||
}
|
||||
|
||||
if f.Color != "" {
|
||||
q = q.Where("files.file_main_color = ?", strings.ToLower(f.Color))
|
||||
s = s.Where("files.file_main_color = ?", strings.ToLower(f.Color))
|
||||
}
|
||||
|
||||
if f.Favorites {
|
||||
q = q.Where("photos.photo_favorite = 1")
|
||||
s = s.Where("photos.photo_favorite = 1")
|
||||
}
|
||||
|
||||
if f.Public {
|
||||
q = q.Where("photos.photo_private = 0")
|
||||
s = s.Where("photos.photo_private = 0")
|
||||
}
|
||||
|
||||
if f.Safe {
|
||||
q = q.Where("photos.photo_nsfw = 0")
|
||||
s = s.Where("photos.photo_nsfw = 0")
|
||||
}
|
||||
|
||||
if f.Nsfw {
|
||||
q = q.Where("photos.photo_nsfw = 1")
|
||||
s = s.Where("photos.photo_nsfw = 1")
|
||||
}
|
||||
|
||||
if f.Story {
|
||||
q = q.Where("photos.photo_story = 1")
|
||||
s = s.Where("photos.photo_story = 1")
|
||||
}
|
||||
|
||||
if f.Country != "" {
|
||||
q = q.Where("photos.photo_country = ?", f.Country)
|
||||
s = s.Where("photos.photo_country = ?", f.Country)
|
||||
}
|
||||
|
||||
if f.Title != "" {
|
||||
q = q.Where("LOWER(photos.photo_title) LIKE ?", fmt.Sprintf("%%%s%%", strings.ToLower(f.Title)))
|
||||
s = s.Where("LOWER(photos.photo_title) LIKE ?", fmt.Sprintf("%%%s%%", strings.ToLower(f.Title)))
|
||||
}
|
||||
|
||||
if f.Hash != "" {
|
||||
q = q.Where("files.file_hash = ?", f.Hash)
|
||||
s = s.Where("files.file_hash = ?", f.Hash)
|
||||
}
|
||||
|
||||
if f.Duplicate {
|
||||
q = q.Where("files.file_duplicate = 1")
|
||||
s = s.Where("files.file_duplicate = 1")
|
||||
}
|
||||
|
||||
if f.Portrait {
|
||||
q = q.Where("files.file_portrait = 1")
|
||||
s = s.Where("files.file_portrait = 1")
|
||||
}
|
||||
|
||||
if f.Mono {
|
||||
q = q.Where("files.file_chroma = 0")
|
||||
s = s.Where("files.file_chroma = 0")
|
||||
} else if f.Chroma > 9 {
|
||||
q = q.Where("files.file_chroma > ?", f.Chroma)
|
||||
s = s.Where("files.file_chroma > ?", f.Chroma)
|
||||
} else if f.Chroma > 0 {
|
||||
q = q.Where("files.file_chroma > 0 AND files.file_chroma <= ?", f.Chroma)
|
||||
s = s.Where("files.file_chroma > 0 AND files.file_chroma <= ?", f.Chroma)
|
||||
}
|
||||
|
||||
if f.Fmin > 0 {
|
||||
q = q.Where("photos.photo_f_number >= ?", f.Fmin)
|
||||
s = s.Where("photos.photo_f_number >= ?", f.Fmin)
|
||||
}
|
||||
|
||||
if f.Fmax > 0 {
|
||||
q = q.Where("photos.photo_f_number <= ?", f.Fmax)
|
||||
s = s.Where("photos.photo_f_number <= ?", f.Fmax)
|
||||
}
|
||||
|
||||
if f.Dist == 0 {
|
||||
|
@ -292,43 +292,43 @@ func (s *Query) Photos(f form.PhotoSearch) (results []PhotoResult, err error) {
|
|||
if f.Lat > 0 {
|
||||
latMin := f.Lat - SearchRadius*float64(f.Dist)
|
||||
latMax := f.Lat + SearchRadius*float64(f.Dist)
|
||||
q = q.Where("photos.photo_lat BETWEEN ? AND ?", latMin, latMax)
|
||||
s = s.Where("photos.photo_lat BETWEEN ? AND ?", latMin, latMax)
|
||||
}
|
||||
|
||||
if f.Lng > 0 {
|
||||
lngMin := f.Lng - SearchRadius*float64(f.Dist)
|
||||
lngMax := f.Lng + SearchRadius*float64(f.Dist)
|
||||
q = q.Where("photos.photo_lng BETWEEN ? AND ?", lngMin, lngMax)
|
||||
s = s.Where("photos.photo_lng BETWEEN ? AND ?", lngMin, lngMax)
|
||||
}
|
||||
|
||||
if !f.Before.IsZero() {
|
||||
q = q.Where("photos.taken_at <= ?", f.Before.Format("2006-01-02"))
|
||||
s = s.Where("photos.taken_at <= ?", f.Before.Format("2006-01-02"))
|
||||
}
|
||||
|
||||
if !f.After.IsZero() {
|
||||
q = q.Where("photos.taken_at >= ?", f.After.Format("2006-01-02"))
|
||||
s = s.Where("photos.taken_at >= ?", f.After.Format("2006-01-02"))
|
||||
}
|
||||
|
||||
switch f.Order {
|
||||
case "relevance":
|
||||
q = q.Order("photo_story DESC, photo_favorite DESC, taken_at DESC")
|
||||
s = s.Order("photo_story DESC, photo_favorite DESC, taken_at DESC")
|
||||
case "newest":
|
||||
q = q.Order("taken_at DESC, photos.photo_uuid")
|
||||
s = s.Order("taken_at DESC, photos.photo_uuid")
|
||||
case "oldest":
|
||||
q = q.Order("taken_at, photos.photo_uuid")
|
||||
s = s.Order("taken_at, photos.photo_uuid")
|
||||
case "imported":
|
||||
q = q.Order("photos.id DESC")
|
||||
s = s.Order("photos.id DESC")
|
||||
default:
|
||||
q = q.Order("taken_at DESC, photos.photo_uuid")
|
||||
s = s.Order("taken_at DESC, photos.photo_uuid")
|
||||
}
|
||||
|
||||
if f.Count > 0 && f.Count <= 1000 {
|
||||
q = q.Limit(f.Count).Offset(f.Offset)
|
||||
s = s.Limit(f.Count).Offset(f.Offset)
|
||||
} else {
|
||||
q = q.Limit(100).Offset(0)
|
||||
s = s.Limit(100).Offset(0)
|
||||
}
|
||||
|
||||
if result := q.Scan(&results); result.Error != nil {
|
||||
if result := s.Scan(&results); result.Error != nil {
|
||||
return results, result.Error
|
||||
}
|
||||
|
||||
|
@ -336,8 +336,8 @@ func (s *Query) Photos(f form.PhotoSearch) (results []PhotoResult, err error) {
|
|||
}
|
||||
|
||||
// PhotoByID returns a Photo based on the ID.
|
||||
func (s *Query) PhotoByID(photoID uint64) (photo entity.Photo, err error) {
|
||||
if err := s.db.Where("id = ?", photoID).Preload("Description").First(&photo).Error; err != nil {
|
||||
func (q *Query) PhotoByID(photoID uint64) (photo entity.Photo, err error) {
|
||||
if err := q.db.Where("id = ?", photoID).Preload("Description").First(&photo).Error; err != nil {
|
||||
return photo, err
|
||||
}
|
||||
|
||||
|
@ -345,8 +345,8 @@ func (s *Query) PhotoByID(photoID uint64) (photo entity.Photo, err error) {
|
|||
}
|
||||
|
||||
// PhotoByUUID returns a Photo based on the UUID.
|
||||
func (s *Query) PhotoByUUID(photoUUID string) (photo entity.Photo, err error) {
|
||||
if err := s.db.Where("photo_uuid = ?", photoUUID).Preload("Description").First(&photo).Error; err != nil {
|
||||
func (q *Query) PhotoByUUID(photoUUID string) (photo entity.Photo, err error) {
|
||||
if err := q.db.Where("photo_uuid = ?", photoUUID).Preload("Description").First(&photo).Error; err != nil {
|
||||
return photo, err
|
||||
}
|
||||
|
||||
|
@ -354,8 +354,8 @@ func (s *Query) PhotoByUUID(photoUUID string) (photo entity.Photo, err error) {
|
|||
}
|
||||
|
||||
// PreloadPhotoByUUID returns a Photo based on the UUID with all dependencies preloaded.
|
||||
func (s *Query) PreloadPhotoByUUID(photoUUID string) (photo entity.Photo, err error) {
|
||||
if err := s.db.Where("photo_uuid = ?", photoUUID).
|
||||
func (q *Query) PreloadPhotoByUUID(photoUUID string) (photo entity.Photo, err error) {
|
||||
if err := q.db.Where("photo_uuid = ?", photoUUID).
|
||||
Preload("Labels", func(db *gorm.DB) *gorm.DB {
|
||||
return db.Order("photos_labels.label_uncertainty ASC, photos_labels.label_id DESC")
|
||||
}).
|
||||
|
@ -367,7 +367,7 @@ func (s *Query) PreloadPhotoByUUID(photoUUID string) (photo entity.Photo, err er
|
|||
return photo, err
|
||||
}
|
||||
|
||||
photo.PreloadMany(s.db)
|
||||
photo.PreloadMany(q.db)
|
||||
|
||||
return photo, nil
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"github.com/photoprism/photoprism/internal/form"
|
||||
)
|
||||
|
||||
/*func TestRepo_Photos(t *testing.T) {
|
||||
/*func TestQuery_Photos(t *testing.T) {
|
||||
conf := config.TestConfig()
|
||||
|
||||
search := New(conf.OriginalsPath(), conf.Db())
|
||||
|
@ -28,7 +28,7 @@ import (
|
|||
})
|
||||
}*/
|
||||
|
||||
func TestRepo_FindPhotoByID(t *testing.T) {
|
||||
func TestQuery_PhotoByID(t *testing.T) {
|
||||
conf := config.TestConfig()
|
||||
|
||||
search := New(conf.Db())
|
||||
|
@ -46,7 +46,7 @@ func TestRepo_FindPhotoByID(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestRepo_FindPhotoByUUID(t *testing.T) {
|
||||
func TestQuery_PhotoByUUID(t *testing.T) {
|
||||
conf := config.TestConfig()
|
||||
|
||||
search := New(conf.Db())
|
||||
|
@ -64,7 +64,7 @@ func TestRepo_FindPhotoByUUID(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestRepo_PreloadPhotoByUUID(t *testing.T) {
|
||||
func TestQuery_PreloadPhotoByUUID(t *testing.T) {
|
||||
conf := config.TestConfig()
|
||||
|
||||
search := New(conf.Db())
|
||||
|
@ -81,7 +81,8 @@ func TestRepo_PreloadPhotoByUUID(t *testing.T) {
|
|||
t.Log(result)
|
||||
})
|
||||
}
|
||||
func TestSearch_Photos_Query(t *testing.T) {
|
||||
|
||||
func TestSearch_Photos(t *testing.T) {
|
||||
conf := config.TestConfig()
|
||||
|
||||
conf.CreateDirectories()
|
||||
|
|
|
@ -8,23 +8,23 @@ import (
|
|||
)
|
||||
|
||||
// PhotoSelection returns all selected photos.
|
||||
func (s *Query) PhotoSelection(f form.Selection) (results []entity.Photo, err error) {
|
||||
func (q *Query) PhotoSelection(f form.Selection) (results []entity.Photo, err error) {
|
||||
if f.Empty() {
|
||||
return results, errors.New("no photos selected")
|
||||
}
|
||||
|
||||
q := s.db.NewScope(nil).DB()
|
||||
s := q.db.NewScope(nil).DB()
|
||||
|
||||
q = q.Table("photos").
|
||||
s = s.Table("photos").
|
||||
Select("photos.*").
|
||||
Joins("LEFT JOIN photos_labels ON photos_labels.photo_id = photos.id").
|
||||
Joins("LEFT JOIN labels ON photos_labels.label_id = labels.id AND labels.deleted_at IS NULL").
|
||||
Where("photos.deleted_at IS NULL").
|
||||
Group("photos.id")
|
||||
|
||||
q = q.Where("photos.photo_uuid IN (?) OR labels.label_uuid IN (?)", f.Photos, f.Labels)
|
||||
s = s.Where("photos.photo_uuid IN (?) OR labels.label_uuid IN (?)", f.Photos, f.Labels)
|
||||
|
||||
if result := q.Scan(&results); result.Error != nil {
|
||||
if result := s.Scan(&results); result.Error != nil {
|
||||
return results, result.Error
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue