NullSort instead of None

A more descriptive placeholder for "don't sort".
This commit is contained in:
Adrian Sampson 2014-09-13 20:36:39 -07:00
parent 369533d46f
commit 2b921b19fd
4 changed files with 41 additions and 15 deletions

View file

@ -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:

View file

@ -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

View file

@ -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

View file

@ -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+'])