navidrome/persistence/sql_restful.go

85 lines
2.0 KiB
Go

package persistence
import (
"fmt"
"strings"
. "github.com/Masterminds/squirrel"
"github.com/deluan/rest"
"github.com/navidrome/navidrome/model"
)
type filterFunc = func(field string, value interface{}) Sqlizer
type sqlRestful struct {
filterMappings map[string]filterFunc
}
func (r sqlRestful) parseRestFilters(options rest.QueryOptions) Sqlizer {
if len(options.Filters) == 0 {
return nil
}
filters := And{}
for f, v := range options.Filters {
if v == "" {
continue
}
if ff, ok := r.filterMappings[f]; ok {
filters = append(filters, ff(f, v))
} else if strings.HasSuffix(strings.ToLower(f), "id") {
filters = append(filters, eqFilter(f, v))
} else {
filters = append(filters, startsWithFilter(f, v))
}
}
return filters
}
func (r sqlRestful) parseRestOptions(options ...rest.QueryOptions) model.QueryOptions {
qo := model.QueryOptions{}
if len(options) > 0 {
qo.Sort = options[0].Sort
qo.Order = strings.ToLower(options[0].Order)
qo.Max = options[0].Max
qo.Offset = options[0].Offset
qo.Filters = r.parseRestFilters(options[0])
}
return qo
}
func eqFilter(field string, value interface{}) Sqlizer {
return Eq{field: value}
}
func startsWithFilter(field string, value interface{}) Sqlizer {
return Like{field: fmt.Sprintf("%s%%", value)}
}
func containsFilter(field string, value interface{}) Sqlizer {
return Like{field: fmt.Sprintf("%%%s%%", value)}
}
func booleanFilter(field string, value interface{}) Sqlizer {
v := strings.ToLower(value.(string))
return Eq{field: strings.ToLower(v) == "true"}
}
func fullTextFilter(field string, value interface{}) Sqlizer {
return fullTextExpr(value.(string))
}
func substringFilter(field string, value interface{}) Sqlizer {
parts := strings.Split(value.(string), " ")
filters := And{}
for _, part := range parts {
filters = append(filters, Like{field: "%" + part + "%"})
}
return filters
}
func idFilter(tableName string) func(string, interface{}) Sqlizer {
return func(field string, value interface{}) Sqlizer {
return Eq{tableName + ".id": value}
}
}