refactor: extracted restful helpers into their own composable struct

This commit is contained in:
Deluan 2020-03-21 20:00:46 -04:00
parent 91a743623a
commit 20075ae68d
8 changed files with 72 additions and 54 deletions

View File

@ -13,6 +13,7 @@ import (
type albumRepository struct {
sqlRepository
sqlRestful
}
func NewAlbumRepository(ctx context.Context, o orm.Ormer) model.AlbumRepository {

View File

@ -16,6 +16,7 @@ import (
type artistRepository struct {
sqlRepository
sqlRestful
indexGroups utils.IndexGroups
}

View File

@ -14,6 +14,7 @@ import (
type mediaFileRepository struct {
sqlRepository
sqlRestful
}
func NewMediaFileRepository(ctx context.Context, o orm.Ormer) *mediaFileRepository {

View File

@ -11,6 +11,7 @@ import (
type playerRepository struct {
sqlRepository
sqlRestful
}
func NewPlayerRepository(ctx context.Context, o orm.Ormer) model.PlayerRepository {

View File

@ -11,19 +11,14 @@ import (
"github.com/astaxie/beego/orm"
"github.com/deluan/navidrome/log"
"github.com/deluan/navidrome/model"
"github.com/deluan/rest"
"github.com/google/uuid"
"github.com/kennygrant/sanitize"
)
type filterFunc = func(field string, value interface{}) Sqlizer
type sqlRepository struct {
ctx context.Context
tableName string
ormer orm.Ormer
sortMappings map[string]string
filterMappings map[string]filterFunc
ctx context.Context
tableName string
ormer orm.Ormer
sortMappings map[string]string
}
const invalidUserId = "-1"
@ -219,48 +214,3 @@ func (r sqlRepository) logSQL(sql string, args []interface{}, err error, rowsAff
log.Trace(r.ctx, "SQL: `"+sql+"`", "args", `[`+strings.Join(fmtArgs, ",")+`]`, "rowsAffected", rowsAffected, "elapsedTime", elapsed)
}
}
func (r sqlRepository) 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
if len(options[0].Filters) > 0 {
filters := And{}
for f, v := range options[0].Filters {
if ff, ok := r.filterMappings[f]; ok {
filters = append(filters, ff(f, v))
} else {
filters = append(filters, startsWithFilter(f, v))
}
}
qo.Filters = filters
}
}
return qo
}
func startsWithFilter(field string, value interface{}) Like {
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 {
q := value.(string)
q = strings.TrimSpace(sanitize.Accents(strings.ToLower(strings.TrimSuffix(q, "*"))))
parts := strings.Split(q, " ")
filters := And{}
for _, part := range parts {
filters = append(filters, Or{
Like{"full_text": part + "%"},
Like{"full_text": "%" + part + "%"},
})
}
return filters
}

View File

@ -0,0 +1,62 @@
package persistence
import (
"fmt"
"strings"
. "github.com/Masterminds/squirrel"
"github.com/deluan/navidrome/model"
"github.com/deluan/rest"
"github.com/kennygrant/sanitize"
)
type filterFunc = func(field string, value interface{}) Sqlizer
type sqlRestful struct {
filterMappings map[string]filterFunc
}
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
if len(options[0].Filters) > 0 {
filters := And{}
for f, v := range options[0].Filters {
if ff, ok := r.filterMappings[f]; ok {
filters = append(filters, ff(f, v))
} else {
filters = append(filters, startsWithFilter(f, v))
}
}
qo.Filters = filters
}
}
return qo
}
func startsWithFilter(field string, value interface{}) Like {
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 {
q := value.(string)
q = strings.TrimSpace(sanitize.Accents(strings.ToLower(strings.TrimSuffix(q, "*"))))
parts := strings.Split(q, " ")
filters := And{}
for _, part := range parts {
filters = append(filters, Or{
Like{"full_text": part + "%"},
Like{"full_text": "%" + part + "%"},
})
}
return filters
}

View File

@ -11,6 +11,7 @@ import (
type transcodingRepository struct {
sqlRepository
sqlRestful
}
func NewTranscodingRepository(ctx context.Context, o orm.Ormer) model.TranscodingRepository {

View File

@ -14,6 +14,7 @@ import (
type userRepository struct {
sqlRepository
sqlRestful
}
func NewUserRepository(ctx context.Context, o orm.Ormer) model.UserRepository {