2021-09-02 16:12:31 +02:00
|
|
|
package query
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/jinzhu/gorm"
|
|
|
|
"github.com/photoprism/photoprism/internal/entity"
|
|
|
|
"github.com/photoprism/photoprism/internal/form"
|
|
|
|
"github.com/photoprism/photoprism/pkg/capture"
|
|
|
|
)
|
|
|
|
|
|
|
|
// SubjectResult represents a subject search result.
|
|
|
|
type SubjectResult struct {
|
2021-09-17 14:26:12 +02:00
|
|
|
SubjUID string `json:"UID"`
|
|
|
|
SubjType string `json:"Type"`
|
|
|
|
SubjSlug string `json:"Slug"`
|
|
|
|
SubjName string `json:"Name"`
|
|
|
|
SubjAlias string `json:"Alias"`
|
|
|
|
SubjFavorite bool `json:"Favorite"`
|
|
|
|
SubjPrivate bool `json:"Private"`
|
|
|
|
SubjExcluded bool `json:"Excluded"`
|
2021-09-17 16:13:47 +02:00
|
|
|
FileCount int `json:"FileCount"`
|
2021-09-17 14:26:12 +02:00
|
|
|
Thumb string `json:"Thumb"`
|
2021-09-02 16:12:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// SubjectResults represents subject search results.
|
|
|
|
type SubjectResults []SubjectResult
|
|
|
|
|
|
|
|
// SubjectSearch searches subjects and returns them.
|
|
|
|
func SubjectSearch(f form.SubjectSearch) (results SubjectResults, err error) {
|
|
|
|
if err := f.ParseQueryString(); err != nil {
|
|
|
|
return results, err
|
|
|
|
}
|
|
|
|
|
|
|
|
defer log.Debug(capture.Time(time.Now(), fmt.Sprintf("subjects: search %s", form.Serialize(f, true))))
|
|
|
|
|
|
|
|
// Base query.
|
|
|
|
s := UnscopedDb().Table(entity.Subject{}.TableName()).
|
2021-09-17 14:26:12 +02:00
|
|
|
Select("subj_uid, subj_slug, subj_name, subj_alias, subj_type, thumb, subj_favorite, subj_private, subj_excluded, file_count")
|
2021-09-02 16:12:31 +02:00
|
|
|
|
|
|
|
// Limit result count.
|
|
|
|
if f.Count > 0 && f.Count <= MaxResults {
|
|
|
|
s = s.Limit(f.Count).Offset(f.Offset)
|
|
|
|
} else {
|
|
|
|
s = s.Limit(MaxResults).Offset(f.Offset)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set sort order.
|
|
|
|
switch f.Order {
|
2021-09-17 14:26:12 +02:00
|
|
|
case "name":
|
|
|
|
s = s.Order("subj_name")
|
2021-09-02 16:12:31 +02:00
|
|
|
case "count":
|
|
|
|
s = s.Order("file_count DESC")
|
2021-09-17 14:26:12 +02:00
|
|
|
case "added":
|
|
|
|
s = s.Order("created_at DESC")
|
|
|
|
case "relevance":
|
|
|
|
s = s.Order("subj_favorite DESC, subj_name")
|
2021-09-02 16:12:31 +02:00
|
|
|
default:
|
2021-09-17 14:26:12 +02:00
|
|
|
s = s.Order("subj_favorite DESC, subj_name")
|
2021-09-02 16:12:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if f.ID != "" {
|
2021-09-17 14:26:12 +02:00
|
|
|
s = s.Where("subj_uid IN (?)", strings.Split(f.ID, Or))
|
2021-09-02 16:12:31 +02:00
|
|
|
|
|
|
|
if result := s.Scan(&results); result.Error != nil {
|
|
|
|
return results, result.Error
|
|
|
|
}
|
|
|
|
|
|
|
|
return results, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
if f.Query != "" {
|
2021-09-17 14:26:12 +02:00
|
|
|
for _, where := range LikeAnyWord("subj_name", f.Query) {
|
2021-09-02 16:12:31 +02:00
|
|
|
s = s.Where("(?)", gorm.Expr(where))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if f.Type != "" {
|
2021-09-17 14:26:12 +02:00
|
|
|
s = s.Where("subj_type IN (?)", strings.Split(f.Type, Or))
|
2021-09-02 16:12:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if f.Favorite {
|
2021-09-17 14:26:12 +02:00
|
|
|
s = s.Where("subj_favorite = 1")
|
2021-09-02 16:12:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if f.Private {
|
2021-09-17 14:26:12 +02:00
|
|
|
s = s.Where("subj_private = 1")
|
2021-09-02 16:12:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if f.Excluded {
|
2021-09-17 14:26:12 +02:00
|
|
|
s = s.Where("subj_excluded = 1")
|
2021-09-02 16:12:31 +02:00
|
|
|
}
|
|
|
|
|
2021-09-17 14:26:12 +02:00
|
|
|
// Omit deleted rows.
|
2021-09-02 16:12:31 +02:00
|
|
|
s = s.Where("deleted_at IS NULL")
|
|
|
|
|
|
|
|
if result := s.Scan(&results); result.Error != nil {
|
|
|
|
return results, result.Error
|
|
|
|
}
|
|
|
|
|
|
|
|
return results, nil
|
|
|
|
}
|