Files
photoview/api/graphql/models/actions/search_actions.go
Kostiantyn 5fc8feb75e Refactoring part 2.3: Long func refactoring in graphql/models (#1075)
* Split long functions and optimize code

* 2 more small files

---------

Co-authored-by: Konstantin Koval
2024-10-08 21:10:34 +03:00

77 lines
2.0 KiB
Go

package actions
import (
"strings"
"github.com/photoview/photoview/api/database/drivers"
"github.com/photoview/photoview/api/graphql/models"
"github.com/pkg/errors"
"gorm.io/gorm"
"gorm.io/gorm/clause"
)
func Search(db *gorm.DB, query string, userID int, limitMedia *int, limitAlbums *int) (*models.SearchResult, error) {
limitMediaInternal := 10
limitAlbumsInternal := 10
if limitMedia != nil {
limitMediaInternal = *limitMedia
}
if limitAlbums != nil {
limitAlbumsInternal = *limitAlbums
}
wildQuery := "%" + strings.ToLower(query) + "%"
var media []*models.Media
userSubquery := db.Table("user_albums").Where("user_id = ?", userID)
if drivers.POSTGRES.MatchDatabase(db) {
userSubquery = userSubquery.Where("album_id = \"Album\".id")
} else {
userSubquery = userSubquery.Where("album_id = Album.id")
}
err := db.Joins("Album").
Where("EXISTS (?)", userSubquery).
Where("LOWER(media.title) LIKE ? OR LOWER(media.path) LIKE ?", wildQuery, wildQuery).
Clauses(clause.OrderBy{
Expression: clause.Expr{
SQL: "(CASE WHEN LOWER(media.title) LIKE ? THEN 2 WHEN LOWER(media.path) LIKE ? THEN 1 END) DESC",
Vars: []interface{}{wildQuery, wildQuery},
WithoutParentheses: true},
}).
Limit(limitMediaInternal).Find(&media).Error
if err != nil {
return nil, errors.Wrapf(err, "searching media")
}
var albums []*models.Album
err = db.
Where("EXISTS (?)", db.Table("user_albums").Where("user_id = ?", userID).Where("album_id = albums.id")).
Where("albums.title LIKE ? OR albums.path LIKE ?", wildQuery, wildQuery).
Clauses(clause.OrderBy{
Expression: clause.Expr{
SQL: "(CASE WHEN albums.title LIKE ? THEN 2 WHEN albums.path LIKE ? THEN 1 END) DESC",
Vars: []interface{}{wildQuery, wildQuery},
WithoutParentheses: true},
}).
Limit(limitAlbumsInternal).
Find(&albums).Error
if err != nil {
return nil, errors.Wrapf(err, "searching albums")
}
result := models.SearchResult{
Query: query,
Media: media,
Albums: albums,
}
return &result, nil
}