mirror of
https://github.com/navidrome/navidrome.git
synced 2025-04-14 19:20:37 +03:00
162 lines
4.4 KiB
Go
162 lines
4.4 KiB
Go
package persistence
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
|
|
. "github.com/Masterminds/squirrel"
|
|
"github.com/astaxie/beego/orm"
|
|
"github.com/deluan/navidrome/model"
|
|
"github.com/deluan/rest"
|
|
"github.com/kennygrant/sanitize"
|
|
)
|
|
|
|
type mediaFileRepository struct {
|
|
sqlRepository
|
|
}
|
|
|
|
func NewMediaFileRepository(ctx context.Context, o orm.Ormer) *mediaFileRepository {
|
|
r := &mediaFileRepository{}
|
|
r.ctx = ctx
|
|
r.ormer = o
|
|
r.tableName = "media_file"
|
|
return r
|
|
}
|
|
|
|
func (r mediaFileRepository) CountAll(options ...model.QueryOptions) (int64, error) {
|
|
return r.count(Select(), options...)
|
|
}
|
|
|
|
func (r mediaFileRepository) Exists(id string) (bool, error) {
|
|
return r.exists(Select().Where(Eq{"id": id}))
|
|
}
|
|
|
|
func (r mediaFileRepository) Put(m *model.MediaFile) error {
|
|
values, _ := toSqlArgs(*m)
|
|
update := Update(r.tableName).Where(Eq{"id": m.ID}).SetMap(values)
|
|
count, err := r.executeSQL(update)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if count > 0 {
|
|
return nil
|
|
}
|
|
insert := Insert(r.tableName).SetMap(values)
|
|
_, err = r.executeSQL(insert)
|
|
return err
|
|
}
|
|
|
|
func (r mediaFileRepository) selectMediaFile(options ...model.QueryOptions) SelectBuilder {
|
|
return r.newSelectWithAnnotation(model.MediaItemType, "media_file.id", options...).Columns("media_file.*")
|
|
}
|
|
|
|
func (r mediaFileRepository) Get(id string) (*model.MediaFile, error) {
|
|
sel := r.selectMediaFile().Where(Eq{"id": id})
|
|
var res model.MediaFile
|
|
err := r.queryOne(sel, &res)
|
|
return &res, err
|
|
}
|
|
|
|
func (r mediaFileRepository) GetAll(options ...model.QueryOptions) (model.MediaFiles, error) {
|
|
sq := r.selectMediaFile(options...)
|
|
var res model.MediaFiles
|
|
err := r.queryAll(sq, &res)
|
|
return res, err
|
|
}
|
|
|
|
func (r mediaFileRepository) FindByAlbum(albumId string) (model.MediaFiles, error) {
|
|
sel := r.selectMediaFile().Where(Eq{"album_id": albumId})
|
|
var res model.MediaFiles
|
|
err := r.queryAll(sel, &res)
|
|
return res, err
|
|
}
|
|
|
|
func (r mediaFileRepository) FindByPath(path string) (model.MediaFiles, error) {
|
|
sel := r.selectMediaFile().Where(Like{"path": path + "%"})
|
|
var res model.MediaFiles
|
|
err := r.queryAll(sel, &res)
|
|
return res, err
|
|
}
|
|
|
|
func (r mediaFileRepository) GetStarred(options ...model.QueryOptions) (model.MediaFiles, error) {
|
|
sq := r.selectMediaFile(options...).Where("starred = true")
|
|
var starred model.MediaFiles
|
|
err := r.queryAll(sq, &starred)
|
|
return starred, err
|
|
}
|
|
|
|
// TODO Keep order when paginating
|
|
func (r mediaFileRepository) GetRandom(options ...model.QueryOptions) (model.MediaFiles, error) {
|
|
sq := r.selectMediaFile(options...)
|
|
switch r.ormer.Driver().Type() {
|
|
case orm.DRMySQL:
|
|
sq = sq.OrderBy("RAND()")
|
|
default:
|
|
sq = sq.OrderBy("RANDOM()")
|
|
}
|
|
sql, args, err := r.toSql(sq)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var results model.MediaFiles
|
|
_, err = r.ormer.Raw(sql, args...).QueryRows(&results)
|
|
return results, err
|
|
}
|
|
|
|
func (r mediaFileRepository) Delete(id string) error {
|
|
return r.delete(Eq{"id": id})
|
|
}
|
|
|
|
func (r mediaFileRepository) DeleteByPath(path string) error {
|
|
del := Delete(r.tableName).Where(Like{"path": path + "%"})
|
|
_, err := r.executeSQL(del)
|
|
return err
|
|
}
|
|
|
|
func (r mediaFileRepository) Search(q string, offset int, size int) (model.MediaFiles, error) {
|
|
q = strings.TrimSpace(sanitize.Accents(strings.ToLower(strings.TrimSuffix(q, "*"))))
|
|
if len(q) <= 2 {
|
|
return model.MediaFiles{}, nil
|
|
}
|
|
sq := Select("*").From(r.tableName)
|
|
sq = sq.Limit(uint64(size)).Offset(uint64(offset)).OrderBy("title")
|
|
sq = sq.Join("search").Where("search.id = " + r.tableName + ".id")
|
|
parts := strings.Split(q, " ")
|
|
for _, part := range parts {
|
|
sq = sq.Where(Or{
|
|
Like{"full_text": part + "%"},
|
|
Like{"full_text": "%" + part + "%"},
|
|
})
|
|
}
|
|
sql, args, err := r.toSql(sq)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var results model.MediaFiles
|
|
_, err = r.ormer.Raw(sql, args...).QueryRows(results)
|
|
return results, err
|
|
}
|
|
|
|
func (r mediaFileRepository) Count(options ...rest.QueryOptions) (int64, error) {
|
|
return r.CountAll(r.parseRestOptions(options...))
|
|
}
|
|
|
|
func (r mediaFileRepository) Read(id string) (interface{}, error) {
|
|
return r.Get(id)
|
|
}
|
|
|
|
func (r mediaFileRepository) ReadAll(options ...rest.QueryOptions) (interface{}, error) {
|
|
return r.GetAll(r.parseRestOptions(options...))
|
|
}
|
|
|
|
func (r mediaFileRepository) EntityName() string {
|
|
return "mediafile"
|
|
}
|
|
|
|
func (r mediaFileRepository) NewInstance() interface{} {
|
|
return model.MediaFile{}
|
|
}
|
|
|
|
var _ model.MediaFileRepository = (*mediaFileRepository)(nil)
|
|
var _ model.ResourceRepository = (*mediaFileRepository)(nil)
|