Skip to content

Commit

Permalink
Fix ByPath queries should not match partial filenames
Browse files Browse the repository at this point in the history
  • Loading branch information
deluan committed Oct 6, 2020
1 parent 23fe8cd commit 21f7c19
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 10 deletions.
31 changes: 21 additions & 10 deletions persistence/mediafile_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"os"
"path/filepath"
"strings"
"unicode/utf8"

. "github.com/Masterminds/squirrel"
Expand Down Expand Up @@ -94,9 +95,23 @@ func (r mediaFileRepository) FindByPath(path string) (*model.MediaFile, error) {
return &res[0], nil
}

func cleanPath(path string) string {
path = filepath.Clean(path)
if !strings.HasSuffix(path, string(os.PathSeparator)) {
path = path + string(os.PathSeparator)
}
return path
}

func pathStartsWith(path string) Eq {
substr := fmt.Sprintf("substr(path, 1, %d)", utf8.RuneCountInString(path))
return Eq{substr: path}
}

// FindAllByPath only return mediafiles that are direct children of requested path
func (r mediaFileRepository) FindAllByPath(path string) (model.MediaFiles, error) {
// Query by path based on https://stackoverflow.com/a/13911906/653632
path = cleanPath(path)
pathLen := utf8.RuneCountInString(path)
sel0 := r.selectMediaFile().Columns(fmt.Sprintf("substr(path, %d) AS item", pathLen+2)).
Where(pathStartsWith(path))
Expand All @@ -108,24 +123,20 @@ func (r mediaFileRepository) FindAllByPath(path string) (model.MediaFiles, error
return res, err
}

func pathStartsWith(path string) Eq {
cleanPath := filepath.Clean(path)
substr := fmt.Sprintf("substr(path, 1, %d)", utf8.RuneCountInString(cleanPath))
return Eq{substr: cleanPath}
}

// FindPathsRecursively returns a list of all subfolders of basePath, recursively
func (r mediaFileRepository) FindPathsRecursively(basePath string) ([]string, error) {
path := cleanPath(basePath)
// Query based on https://stackoverflow.com/a/38330814/653632
sel := r.newSelect().Columns(fmt.Sprintf("distinct rtrim(path, replace(path, '%s', ''))", string(os.PathSeparator))).
Where(pathStartsWith(basePath))
Where(pathStartsWith(path))
var res []string
err := r.queryAll(sel, &res)
return res, err
}

func (r mediaFileRepository) deleteNotInPath(basePath string) error {
sel := Delete(r.tableName).Where(NotEq(pathStartsWith(basePath)))
path := cleanPath(basePath)
sel := Delete(r.tableName).Where(NotEq(pathStartsWith(path)))
c, err := r.executeSQL(sel)
if err == nil {
if c > 0 {
Expand Down Expand Up @@ -156,8 +167,8 @@ func (r mediaFileRepository) Delete(id string) error {
}

// DeleteByPath delete from the DB all mediafiles that are direct children of path
func (r mediaFileRepository) DeleteByPath(path string) (int64, error) {
path = filepath.Clean(path)
func (r mediaFileRepository) DeleteByPath(basePath string) (int64, error) {
path := cleanPath(basePath)
pathLen := utf8.RuneCountInString(path)
del := Delete(r.tableName).
Where(And{pathStartsWith(path),
Expand Down
13 changes: 13 additions & 0 deletions persistence/mediafile_repository_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,19 @@ var _ = Describe("MediaRepository", func() {
Expect(mr.FindAllByPath(P("/Legi茫o Urbana"))).To(HaveLen(0))
})

It("only deletes tracks that match exact path", func() {
id1 := "6021"
Expect(mr.Put(&model.MediaFile{ID: id1, Path: P("/music/overlap/Ella Fitzgerald/" + id1 + ".mp3")})).To(BeNil())
id2 := "6022"
Expect(mr.Put(&model.MediaFile{ID: id2, Path: P("/music/overlap/Ella Fitzgerald/" + id2 + ".mp3")})).To(BeNil())
id3 := "6023"
Expect(mr.Put(&model.MediaFile{ID: id3, Path: P("/music/overlap/Ella Fitzgerald & Louis Armstrong - They Can't Take That Away From Me.mp3")})).To(BeNil())

Expect(mr.FindAllByPath(P("/music/overlap/Ella Fitzgerald"))).To(HaveLen(2))
Expect(mr.DeleteByPath(P("/music/overlap/Ella Fitzgerald"))).To(Equal(int64(2)))
Expect(mr.FindAllByPath(P("/music/overlap"))).To(HaveLen(1))
})

Context("Annotations", func() {
It("increments play count when the tracks does not have annotations", func() {
id := "incplay.firsttime"
Expand Down

0 comments on commit 21f7c19

Please sign in to comment.