mirror of
https://github.com/beetbox/beets.git
synced 2026-01-30 12:02:41 +01:00
Prototype support for named (pseudo-field) queries
As discussed here: https://github.com/beetbox/beets/pull/3145#pullrequestreview-204523870 This would replace the need for #3149.
This commit is contained in:
parent
3633c1e27f
commit
d8e167637e
3 changed files with 43 additions and 18 deletions
|
|
@ -143,6 +143,11 @@ class Model(object):
|
|||
are subclasses of `Sort`.
|
||||
"""
|
||||
|
||||
_queries = {}
|
||||
"""Named queries that use a field-like `name:value` syntax but which
|
||||
do not relate to any specific field.
|
||||
"""
|
||||
|
||||
_always_dirty = False
|
||||
"""By default, fields only become "dirty" when their value actually
|
||||
changes. Enabling this flag marks fields as dirty even when the new
|
||||
|
|
|
|||
|
|
@ -119,12 +119,13 @@ def construct_query_part(model_cls, prefixes, query_part):
|
|||
if not query_part:
|
||||
return query.TrueQuery()
|
||||
|
||||
# Use `model_cls` to build up a map from field names to `Query`
|
||||
# classes.
|
||||
# Use `model_cls` to build up a map from field (or query) names to
|
||||
# `Query` classes.
|
||||
query_classes = {}
|
||||
for k, t in itertools.chain(model_cls._fields.items(),
|
||||
model_cls._types.items()):
|
||||
query_classes[k] = t.query
|
||||
query_classes.update(model_cls._queries) # Non-field queries.
|
||||
|
||||
# Parse the string.
|
||||
key, pattern, query_class, negate = \
|
||||
|
|
@ -137,26 +138,27 @@ def construct_query_part(model_cls, prefixes, query_part):
|
|||
# The query type matches a specific field, but none was
|
||||
# specified. So we use a version of the query that matches
|
||||
# any field.
|
||||
q = query.AnyFieldQuery(pattern, model_cls._search_fields,
|
||||
query_class)
|
||||
if negate:
|
||||
return query.NotQuery(q)
|
||||
else:
|
||||
return q
|
||||
out_query = query.AnyFieldQuery(pattern, model_cls._search_fields,
|
||||
query_class)
|
||||
else:
|
||||
# Non-field query type.
|
||||
if negate:
|
||||
return query.NotQuery(query_class(pattern))
|
||||
else:
|
||||
return query_class(pattern)
|
||||
out_query = query_class(pattern)
|
||||
|
||||
# Otherwise, this must be a `FieldQuery`. Use the field name to
|
||||
# construct the query object.
|
||||
key = key.lower()
|
||||
q = query_class(key.lower(), pattern, key in model_cls._fields)
|
||||
# Field queries get constructed according to the name of the field
|
||||
# they are querying.
|
||||
elif issubclass(query_class, query.FieldQuery):
|
||||
key = key.lower()
|
||||
out_query = query_class(key.lower(), pattern, key in model_cls._fields)
|
||||
|
||||
# Non-field (named) query.
|
||||
else:
|
||||
out_query = query_class(pattern)
|
||||
|
||||
# Apply negation.
|
||||
if negate:
|
||||
return query.NotQuery(q)
|
||||
return q
|
||||
return query.NotQuery(out_query)
|
||||
else:
|
||||
return out_query
|
||||
|
||||
|
||||
def query_from_strings(query_cls, model_cls, prefixes, query_parts):
|
||||
|
|
|
|||
|
|
@ -36,6 +36,17 @@ class TestSort(dbcore.query.FieldSort):
|
|||
pass
|
||||
|
||||
|
||||
class TestQuery(dbcore.query.Query):
|
||||
def __init__(self, pattern):
|
||||
self.pattern = pattern
|
||||
|
||||
def clause(self):
|
||||
return None, ()
|
||||
|
||||
def match(self):
|
||||
return True
|
||||
|
||||
|
||||
class TestModel1(dbcore.Model):
|
||||
_table = 'test'
|
||||
_flex_table = 'testflex'
|
||||
|
|
@ -49,6 +60,9 @@ class TestModel1(dbcore.Model):
|
|||
_sorts = {
|
||||
'some_sort': TestSort,
|
||||
}
|
||||
_queries = {
|
||||
'some_query': TestQuery,
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def _getters(cls):
|
||||
|
|
@ -519,6 +533,10 @@ class QueryFromStringsTest(unittest.TestCase):
|
|||
q = self.qfs([''])
|
||||
self.assertIsInstance(q.subqueries[0], dbcore.query.TrueQuery)
|
||||
|
||||
def test_parse_named_query(self):
|
||||
q = self.qfs(['some_query:foo'])
|
||||
self.assertIsInstance(q.subqueries[0], TestQuery)
|
||||
|
||||
|
||||
class SortFromStringsTest(unittest.TestCase):
|
||||
def sfs(self, strings):
|
||||
|
|
|
|||
Loading…
Reference in a new issue