@@ -40,6 +40,7 @@ class InvalidQueryError(ParsingError):
40
40
41
41
The query should be a unicode string or a list, which will be space-joined.
42
42
"""
43
+
43
44
def __init__ (self , query , explanation ):
44
45
if isinstance (query , list ):
45
46
query = " " .join (query )
@@ -53,6 +54,7 @@ class InvalidQueryArgumentValueError(ParsingError):
53
54
It exists to be caught in upper stack levels so a meaningful (i.e. with the
54
55
query) InvalidQueryError can be raised.
55
56
"""
57
+
56
58
def __init__ (self , what , expected , detail = None ):
57
59
message = u"'{0}' is not {1}" .format (what , expected )
58
60
if detail :
@@ -63,6 +65,7 @@ def __init__(self, what, expected, detail=None):
63
65
class Query (object ):
64
66
"""An abstract class representing a query into the item database.
65
67
"""
68
+
66
69
def clause (self ):
67
70
"""Generate an SQLite expression implementing the query.
68
71
@@ -95,6 +98,7 @@ class FieldQuery(Query):
95
98
string. Subclasses may also provide `col_clause` to implement the
96
99
same matching functionality in SQLite.
97
100
"""
101
+
98
102
def __init__ (self , field , pattern , fast = True ):
99
103
self .field = field
100
104
self .pattern = pattern
@@ -126,14 +130,15 @@ def __repr__(self):
126
130
127
131
def __eq__ (self , other ):
128
132
return super (FieldQuery , self ).__eq__ (other ) and \
129
- self .field == other .field and self .pattern == other .pattern
133
+ self .field == other .field and self .pattern == other .pattern
130
134
131
135
def __hash__ (self ):
132
136
return hash ((self .field , hash (self .pattern )))
133
137
134
138
135
139
class MatchQuery (FieldQuery ):
136
140
"""A query that looks for exact matches in an item field."""
141
+
137
142
def col_clause (self ):
138
143
return self .field + " = ?" , [self .pattern ]
139
144
@@ -143,7 +148,6 @@ def value_match(cls, pattern, value):
143
148
144
149
145
150
class NoneQuery (FieldQuery ):
146
-
147
151
def __init__ (self , field , fast = True ):
148
152
super (NoneQuery , self ).__init__ (field , None , fast )
149
153
@@ -165,6 +169,7 @@ class StringFieldQuery(FieldQuery):
165
169
"""A FieldQuery that converts values to strings before matching
166
170
them.
167
171
"""
172
+
168
173
@classmethod
169
174
def value_match (cls , pattern , value ):
170
175
"""Determine whether the value matches the pattern. The value
@@ -182,11 +187,12 @@ def string_match(cls, pattern, value):
182
187
183
188
class SubstringQuery (StringFieldQuery ):
184
189
"""A query that matches a substring in a specific item field."""
190
+
185
191
def col_clause (self ):
186
192
pattern = (self .pattern
187
- .replace ('\\ ' , '\\ \\ ' )
188
- .replace ('%' , '\\ %' )
189
- .replace ('_' , '\\ _' ))
193
+ .replace ('\\ ' , '\\ \\ ' )
194
+ .replace ('%' , '\\ %' )
195
+ .replace ('_' , '\\ _' ))
190
196
search = '%' + pattern + '%'
191
197
clause = self .field + " like ? escape '\\ '"
192
198
subvals = [search ]
@@ -204,6 +210,7 @@ class RegexpQuery(StringFieldQuery):
204
210
Raises InvalidQueryError when the pattern is not a valid regular
205
211
expression.
206
212
"""
213
+
207
214
def __init__ (self , field , pattern , fast = True ):
208
215
super (RegexpQuery , self ).__init__ (field , pattern , fast )
209
216
pattern = self ._normalize (pattern )
@@ -231,6 +238,7 @@ class BooleanQuery(MatchQuery):
231
238
"""Matches a boolean field. Pattern should either be a boolean or a
232
239
string reflecting a boolean.
233
240
"""
241
+
234
242
def __init__ (self , field , pattern , fast = True ):
235
243
super (BooleanQuery , self ).__init__ (field , pattern , fast )
236
244
if isinstance (pattern , six .string_types ):
@@ -244,6 +252,7 @@ class BytesQuery(MatchQuery):
244
252
`unicode` equivalently in Python 2. Always use this query instead of
245
253
`MatchQuery` when matching on BLOB values.
246
254
"""
255
+
247
256
def __init__ (self , field , pattern ):
248
257
super (BytesQuery , self ).__init__ (field , pattern )
249
258
@@ -270,6 +279,7 @@ class NumericQuery(FieldQuery):
270
279
Raises InvalidQueryError when the pattern does not represent an int or
271
280
a float.
272
281
"""
282
+
273
283
def _convert (self , s ):
274
284
"""Convert a string to a numeric type (float or int).
275
285
@@ -337,6 +347,7 @@ class CollectionQuery(Query):
337
347
"""An abstract query class that aggregates other queries. Can be
338
348
indexed like a list to access the sub-queries.
339
349
"""
350
+
340
351
def __init__ (self , subqueries = ()):
341
352
self .subqueries = subqueries
342
353
@@ -375,7 +386,7 @@ def __repr__(self):
375
386
376
387
def __eq__ (self , other ):
377
388
return super (CollectionQuery , self ).__eq__ (other ) and \
378
- self .subqueries == other .subqueries
389
+ self .subqueries == other .subqueries
379
390
380
391
def __hash__ (self ):
381
392
"""Since subqueries are mutable, this object should not be hashable.
@@ -389,6 +400,7 @@ class AnyFieldQuery(CollectionQuery):
389
400
any field. The individual field query class is provided to the
390
401
constructor.
391
402
"""
403
+
392
404
def __init__ (self , pattern , fields , cls ):
393
405
self .pattern = pattern
394
406
self .fields = fields
@@ -414,7 +426,7 @@ def __repr__(self):
414
426
415
427
def __eq__ (self , other ):
416
428
return super (AnyFieldQuery , self ).__eq__ (other ) and \
417
- self .query_class == other .query_class
429
+ self .query_class == other .query_class
418
430
419
431
def __hash__ (self ):
420
432
return hash ((self .pattern , tuple (self .fields ), self .query_class ))
@@ -424,6 +436,7 @@ class MutableCollectionQuery(CollectionQuery):
424
436
"""A collection query whose subqueries may be modified after the
425
437
query is initialized.
426
438
"""
439
+
427
440
def __setitem__ (self , key , value ):
428
441
self .subqueries [key ] = value
429
442
@@ -433,6 +446,7 @@ def __delitem__(self, key):
433
446
434
447
class AndQuery (MutableCollectionQuery ):
435
448
"""A conjunction of a list of other queries."""
449
+
436
450
def clause (self ):
437
451
return self .clause_with_joiner ('and' )
438
452
@@ -442,6 +456,7 @@ def match(self, item):
442
456
443
457
class OrQuery (MutableCollectionQuery ):
444
458
"""A conjunction of a list of other queries."""
459
+
445
460
def clause (self ):
446
461
return self .clause_with_joiner ('or' )
447
462
@@ -453,6 +468,7 @@ class NotQuery(Query):
453
468
"""A query that matches the negation of its `subquery`, as a shorcut for
454
469
performing `not(subquery)` without using regular expressions.
455
470
"""
471
+
456
472
def __init__ (self , subquery ):
457
473
self .subquery = subquery
458
474
@@ -473,14 +489,15 @@ def __repr__(self):
473
489
474
490
def __eq__ (self , other ):
475
491
return super (NotQuery , self ).__eq__ (other ) and \
476
- self .subquery == other .subquery
492
+ self .subquery == other .subquery
477
493
478
494
def __hash__ (self ):
479
495
return hash (('not' , hash (self .subquery )))
480
496
481
497
482
498
class TrueQuery (Query ):
483
499
"""A query that always matches."""
500
+
484
501
def clause (self ):
485
502
return '1' , ()
486
503
@@ -490,6 +507,7 @@ def match(self, item):
490
507
491
508
class FalseQuery (Query ):
492
509
"""A query that never matches."""
510
+
493
511
def clause (self ):
494
512
return '0' , ()
495
513
@@ -533,7 +551,6 @@ class Period(object):
533
551
instants of time during January 2014.
534
552
"""
535
553
536
-
537
554
precisions = ('year' , 'month' , 'day' , 'hour' , 'minute' , 'second' )
538
555
date_formats = (
539
556
('%Y' ,), # year
@@ -545,7 +562,6 @@ class Period(object):
545
562
)
546
563
relative = {'y' : 365 , 'm' : 30 , 'w' : 7 , 'd' : 1 }
547
564
548
-
549
565
def __init__ (self , date , precision ):
550
566
"""Create a period with the given date (a `datetime` object) and
551
567
precision (a string, one of "year", "month", "day", "hour", "minute",
@@ -599,7 +615,8 @@ def find_date_and_format(string):
599
615
timespan = match_dq .group ('timespan' )
600
616
multiplier = - 1 if sign == '-' else 1
601
617
days = cls .relative [timespan ]
602
- date = datetime .now () + multiplier * timedelta (days = int (quantity ) * days )
618
+ date = datetime .now () + multiplier * timedelta (
619
+ days = int (quantity ) * days )
603
620
string = date .strftime (cls .date_formats [5 ][0 ])
604
621
605
622
date , ordinal = find_date_and_format (string )
@@ -838,13 +855,14 @@ def __hash__(self):
838
855
839
856
def __eq__ (self , other ):
840
857
return super (MultipleSort , self ).__eq__ (other ) and \
841
- self .sorts == other .sorts
858
+ self .sorts == other .sorts
842
859
843
860
844
861
class FieldSort (Sort ):
845
862
"""An abstract sort criterion that orders by a specific field (of
846
863
any kind).
847
864
"""
865
+
848
866
def __init__ (self , field , ascending = True , case_insensitive = True ):
849
867
self .field = field
850
868
self .ascending = ascending
@@ -875,13 +893,14 @@ def __hash__(self):
875
893
876
894
def __eq__ (self , other ):
877
895
return super (FieldSort , self ).__eq__ (other ) and \
878
- self .field == other .field and \
879
- self .ascending == other .ascending
896
+ self .field == other .field and \
897
+ self .ascending == other .ascending
880
898
881
899
882
900
class FixedFieldSort (FieldSort ):
883
901
"""Sort object to sort on a fixed field.
884
902
"""
903
+
885
904
def order_clause (self ):
886
905
order = "ASC" if self .ascending else "DESC"
887
906
if self .case_insensitive :
@@ -898,12 +917,14 @@ class SlowFieldSort(FieldSort):
898
917
"""A sort criterion by some model field other than a fixed field:
899
918
i.e., a computed or flexible field.
900
919
"""
920
+
901
921
def is_slow (self ):
902
922
return True
903
923
904
924
905
925
class NullSort (Sort ):
906
926
"""No sorting. Leave results unsorted."""
927
+
907
928
def sort (self , items ):
908
929
return items
909
930
0 commit comments