From 2b921b19fd5a23bc2e86060c2c12137d63dfe1db Mon Sep 17 00:00:00 2001 From: Adrian Sampson Date: Sat, 13 Sep 2014 20:36:39 -0700 Subject: [PATCH] NullSort instead of None A more descriptive placeholder for "don't sort". --- beets/dbcore/db.py | 1 - beets/dbcore/query.py | 27 +++++++++++++++++++++++---- beets/dbcore/queryparse.py | 26 +++++++++++++++++--------- test/test_dbcore.py | 2 +- 4 files changed, 41 insertions(+), 15 deletions(-) diff --git a/beets/dbcore/db.py b/beets/dbcore/db.py index c15f02422..5eba083f3 100644 --- a/beets/dbcore/db.py +++ b/beets/dbcore/db.py @@ -752,7 +752,6 @@ class Database(object): `sort_order` is either a SQLite ORDER BY clause for sorting or a Sort object. """ - sql, subvals, query, sort = build_sql(model_cls, query, sort_order) with self.transaction() as tx: diff --git a/beets/dbcore/query.py b/beets/dbcore/query.py index 9c53cf6ed..7779d4598 100644 --- a/beets/dbcore/query.py +++ b/beets/dbcore/query.py @@ -531,7 +531,7 @@ class Sort(object): def sort(self, items): """Sort the list of objects and return a list. """ - return sorted(items, key=lambda x: x) + return sorted(items) def is_slow(self): """Indicate whether this query is *slow*, meaning that it cannot @@ -544,8 +544,8 @@ class MultipleSort(Sort): """Sort that encapsulates multiple sub-sorts. """ - def __init__(self): - self.sorts = [] + def __init__(self, sorts=None): + self.sorts = sorts or [] def add_sort(self, sort): self.sorts.append(sort) @@ -612,6 +612,9 @@ class MultipleSort(Sort): items = sort.sort(items) return items + def __repr__(self): + return u'MultipleSort({0})'.format(repr(self.sorts)) + class FieldSort(Sort): """An abstract sort criterion that orders by a specific field (of @@ -628,6 +631,13 @@ class FieldSort(Sort): return sorted(objs, key=attrgetter(self.field), reverse=not self.ascending) + def __repr__(self): + return u'<{0}: {1}{2}>'.format( + type(self).__name__, + self.field, + '+' if self.ascending else '-', + ) + class FixedFieldSort(FieldSort): """Sort object to sort on a fixed field. @@ -653,7 +663,7 @@ class SmartArtistSort(Sort): field = 'artist' return ('(CASE {0}_sort WHEN NULL THEN {0} ' 'WHEN "" THEN {0} ' - 'ELSE {0}_sort END) {2} ').format(field, order) + 'ELSE {0}_sort END) {1} ').format(field, order) class SlowFieldSort(FieldSort): @@ -664,6 +674,15 @@ class SlowFieldSort(FieldSort): return True +class NullSort(Sort): + """No sorting. Leave results unsorted.""" + def sort(items): + return items + + def __nonzero__(self): + return False + + def build_sql(model_cls, query, sort): """ Generate a sql statement (and the values that must be injected into it) from a query, sort and a model class. Query and sort objects are returned diff --git a/beets/dbcore/queryparse.py b/beets/dbcore/queryparse.py index cf8a75ffe..8a50e04d5 100644 --- a/beets/dbcore/queryparse.py +++ b/beets/dbcore/queryparse.py @@ -124,11 +124,18 @@ def query_from_strings(query_cls, model_cls, prefixes, query_parts): def construct_sort_part(model_cls, part): - """ Creates a Sort object from a single criteria. Returns a `Sort` instance. + """Create a `Sort` from a single string criterion. + + `model_cls` is the `Model` being queried. `part` is a single string + ending in ``+`` or ``-`` indicating the sort. """ - sort = None + assert part, "part must be a field name and + or -" field = part[:-1] - is_ascending = (part[-1] == '+') + assert field, "field is missing" + direction = part[-1] + assert direction in ('+', '-'), "part must end with + or -" + is_ascending = direction == '+' + if field in model_cls._fields: sort = query.FixedFieldSort(field, is_ascending) elif field == 'smartartist': @@ -141,11 +148,12 @@ def construct_sort_part(model_cls, part): def sort_from_strings(model_cls, sort_parts): - """Creates a Sort object from a list of sort criteria strings. + """Create a `Sort` from a list of sort criteria (strings). """ if not sort_parts: - return None - sort = query.MultipleSort() - for part in sort_parts: - sort.add_sort(construct_sort_part(model_cls, part)) - return sort + return query.NullSort() + else: + sort = query.MultipleSort() + for part in sort_parts: + sort.add_sort(construct_sort_part(model_cls, part)) + return sort diff --git a/test/test_dbcore.py b/test/test_dbcore.py index 9167acfa5..68a4b61ef 100644 --- a/test/test_dbcore.py +++ b/test/test_dbcore.py @@ -434,7 +434,7 @@ class SortFromStringsTest(unittest.TestCase): def test_zero_parts(self): s = self.sfs([]) - self.assertIsNone(s) + self.assertIsInstance(s, dbcore.query.NullSort) def test_one_parts(self): s = self.sfs(['field+'])