Skip to content

Commit e09d42a

Browse files
authored
Merge pull request #11 from cloudblue/fix_rql_values
fix casting of boolean for comp operators
2 parents edc7069 + a40cb1b commit e09d42a

3 files changed

Lines changed: 35 additions & 29 deletions

File tree

cnct/rql/base.py

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
from datetime import date, datetime
2-
from decimal import Decimal
3-
4-
from cnct.rql.utils import parse_kwargs
1+
from cnct.rql.utils import parse_kwargs, to_rql_value
52

63

74
COMP = ('eq', 'ne', 'lt', 'le', 'gt', 'ge')
@@ -225,31 +222,15 @@ def empty(self, value):
225222

226223
def _bin(self, op, value):
227224
self._field = '.'.join(self._path)
228-
actual_value = None
229-
if isinstance(value, str):
230-
actual_value = value
231-
elif isinstance(value, bool):
232-
actual_value = 'true' if value else 'false'
233-
elif isinstance(value, (int, float, Decimal)):
234-
actual_value = str(value)
235-
elif isinstance(value, (date, datetime)):
236-
actual_value = value.isoformat()
237-
else:
238-
raise TypeError(f"the `{op}` operator doesn't support the {type(value)} type.")
239-
240-
self.expr = f'{op}({self._field},{actual_value})'
225+
value = to_rql_value(op, value)
226+
self.expr = f'{op}({self._field},{value})'
241227
return self
242228

243229
def _list(self, op, value):
244230
self._field = '.'.join(self._path)
245-
actual_value = None
246-
if isinstance(value, (list, tuple)):
247-
actual_value = ','.join(value)
248-
if actual_value:
249-
self.expr = f'{op}({self._field},({actual_value}))'
250-
return self
251-
252-
raise TypeError(f"the `{op}` operator doesn't support the {type(value)} type.")
231+
value = to_rql_value(op, value)
232+
self.expr = f'{op}({self._field},({value}))'
233+
return self
253234

254235
def _bool(self, expr, value):
255236
self._field = '.'.join(self._path)

cnct/rql/utils.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
from datetime import date, datetime
2+
from decimal import Decimal
3+
4+
15
COMP = ('eq', 'ne', 'lt', 'le', 'gt', 'ge')
26
SEARCH = ('like', 'ilike')
37
LIST = ('in', 'out')
@@ -14,20 +18,23 @@ def parse_kwargs(query_dict):
1418
if len(tokens) == 1:
1519
# field=value
1620
field = tokens[0]
21+
value = to_rql_value('eq', value)
1722
query.append(f'eq({field},{value})')
1823
continue
1924
op = tokens[-1]
2025
if op not in KEYWORDS:
2126
# field__nested=value
2227
field = '.'.join(tokens)
28+
value = to_rql_value('eq', value)
2329
query.append(f'eq({field},{value})')
2430
continue
2531
field = '.'.join(tokens[:-1])
2632
if op in COMP or op in SEARCH:
33+
value = to_rql_value(op, value)
2734
query.append(f'{op}({field},{value})')
2835
continue
2936
if op in LIST:
30-
value = ','.join(value)
37+
value = to_rql_value(op, value)
3138
query.append(f'{op}({field},({value}))')
3239
continue
3340

@@ -36,3 +43,18 @@ def parse_kwargs(query_dict):
3643
query.append(f'{cmpop}({field},{expr})')
3744

3845
return query
46+
47+
48+
def to_rql_value(op, value):
49+
if op not in LIST:
50+
if isinstance(value, str):
51+
return value
52+
if isinstance(value, bool):
53+
return 'true' if value else 'false'
54+
if isinstance(value, (int, float, Decimal)):
55+
return str(value)
56+
if isinstance(value, (date, datetime)):
57+
return value.isoformat()
58+
if op in LIST and isinstance(value, (list, tuple)):
59+
return ','.join(value)
60+
raise TypeError(f"the `{op}` operator doesn't support the {type(value)} type.")

tests/rql/test_base.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,19 @@ def test_create_single_kwarg():
2222

2323

2424
def test_create_multiple_kwargs():
25-
q = RQLQuery(id='ID', status__in=('a', 'b'))
25+
q = RQLQuery(id='ID', status__in=('a', 'b'), ok=True)
2626
assert q.op == RQLQuery.AND
27-
assert str(q) == 'and(eq(id,ID),in(status,(a,b)))'
28-
assert len(q.children) == 2
27+
assert str(q) == 'and(eq(id,ID),in(status,(a,b)),eq(ok,true))'
28+
assert len(q.children) == 3
2929
assert q.children[0].op == RQLQuery.EXPR
3030
assert q.children[0].children == []
3131
assert str(q.children[0]) == 'eq(id,ID)'
3232
assert q.children[1].op == RQLQuery.EXPR
3333
assert q.children[1].children == []
3434
assert str(q.children[1]) == 'in(status,(a,b))'
35+
assert q.children[2].op == RQLQuery.EXPR
36+
assert q.children[2].children == []
37+
assert str(q.children[2]) == 'eq(ok,true)'
3538

3639

3740
def test_len():

0 commit comments

Comments
 (0)