new path queries only match prefixes

This commit is contained in:
Adrian Sampson 2011-06-14 23:19:18 -07:00
parent efa704f61e
commit 6ca995f4e7
2 changed files with 48 additions and 1 deletions

View file

@ -427,6 +427,8 @@ class CollectionQuery(Query):
subqueries.append(SubstringQuery(key.lower(), pattern))
elif key.lower() == 'singleton':
subqueries.append(SingletonQuery(util.str2bool(pattern)))
elif key.lower() == 'path':
subqueries.append(PathQuery(pattern))
if not subqueries: # no terms in query
subqueries = [TrueQuery()]
return cls(subqueries)
@ -485,6 +487,20 @@ class TrueQuery(Query):
def match(self, item):
return True
class PathQuery(Query):
"""A query that matches all items under a given path."""
def __init__(self, path):
self.file_path = normpath(path) # As a file.
self.dir_path = os.path.join(path, '') # As a directory (prefix).
def match(self, item):
return (item.path == self.file_path) or \
item.path.startswith(self.dir_path)
def clause(self):
dir_pat = self.dir_path + '%'
return '(path = ?) || (path LIKE ?)', (self.file_path, dir_pat)
class ResultIterator(object):
"""An iterator into an item query result set."""

View file

@ -14,7 +14,6 @@
"""Various tests for querying the library database.
"""
import unittest
import os
@ -226,6 +225,38 @@ class MemoryGetTest(unittest.TestCase, AssertsMixin):
names = [a.album for a in results]
self.assertEqual(names, ['the album'])
class PathQueryTest(unittest.TestCase, AssertsMixin):
def setUp(self):
self.lib = beets.library.Library(':memory:')
path_item = _common.item()
path_item.path = '/a/b/c.mp3'
path_item.title = 'path item'
self.lib.add(path_item)
def test_path_exact_match(self):
q = 'path:/a/b/c.mp3'
results = self.lib.items(q)
self.assert_matched(results, 'path item')
self.assert_done(results)
def test_parent_directory_no_slash(self):
q = 'path:/a'
results = self.lib.items(q)
self.assert_matched(results, 'path item')
self.assert_done(results)
def test_parent_directory_with_slash(self):
q = 'path:/a/'
results = self.lib.items(q)
self.assert_matched(results, 'path item')
self.assert_done(results)
def test_no_match(self):
q = 'path:/xyzzy/'
results = self.lib.items(q)
self.assert_done(results)
class BrowseTest(unittest.TestCase, AssertsMixin):
def setUp(self):
self.lib = beets.library.Library(