Skip to content

Commit dde678d

Browse files
author
Robert Segal
committed
Fix any and all with multiple nested conditions for a collection
1 parent 68c9e07 commit dde678d

File tree

2 files changed

+43
-12
lines changed

2 files changed

+43
-12
lines changed

mpt_api_client/rql/query_builder.py

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -257,28 +257,33 @@ def __getattr__(self, name: str) -> Self:
257257
def __str__(self) -> str:
258258
return self._to_string(self)
259259

260-
def any(self) -> Self:
260+
def any(self, collection_name: str) -> Self:
261261
"""Any nested objects have to match the filter condition.
262262
263263
Returns:
264264
RQLQuery: RQLQuery with new condition
265265
266266
Examples:
267-
RQLQuery(saleDetails__orderQty__gt=11).any()
268-
will result: any(saleDetails,orderQty=11)
267+
RQLQuery(orderQty__gt=11).any("saleDetails")
268+
will result (single): any(saleDetails,orderQty=11)
269+
(RQLQuery(orderQty__gt=11) & RQLQuery(price__lt=100)).any("saleDetails")
270+
will result (multiple): any(and(saleDetails,gt(orderQty,11),lt(price,100)))
269271
"""
270-
return self.new(op=self.OP_ANY, children=[self])
272+
return self._nest(self.OP_ANY, collection_name)
271273

272-
def all(self) -> Self:
274+
def all(self, collection_name: str) -> Self:
273275
"""All nested objects have to match the filter condition.
274276
275277
Returns:
276278
RQLQuery: RQLQuery with new condition
277279
278-
Example:
279-
RQLQuery(saleDetails__orderQty__gt=1).all()
280+
Examples:
281+
RQLQuery(orderQty__gt=1).all("saleDetails")
282+
will result (single): all(saleDetails,gt(orderQty,1))
283+
(RQLQuery(orderQty__gt=11) & RQLQuery(price__lt=100)).all("saleDetails")
284+
will result (multiple): all(and(saleDetails,gt(orderQty,11),lt(price,100)))
280285
"""
281-
return self.new(op=self.OP_ALL, children=[self])
286+
return self._nest(self.OP_ALL, collection_name)
282287

283288
def n(self, name: str) -> Self: # noqa: WPS111
284289
"""Set the current field for this `RQLQuery` object.
@@ -522,3 +527,9 @@ def _append(self, query: "RQLQuery") -> "RQLQuery" | Self:
522527

523528
self.children.append(query)
524529
return self
530+
531+
def _nest(self, op: str, collection_name: str) -> Self:
532+
name = collection_name.replace("__", ".")
533+
collection = self._to_string(self) if self.children else self.expr or ""
534+
expr = f"{op}({name},{collection})"
535+
return self.new(expr=expr)

tests/unit/rql/query_builder/test_rql_all_any.py

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,36 @@
22

33

44
def test_all():
5-
query = RQLQuery(saleDetails__orderQty__gt=1).all()
5+
query = RQLQuery(orderQty__gt=1).all("saleDetails")
66

77
result = str(query)
88

9-
assert result == "all(gt(saleDetails.orderQty,1))"
9+
assert result == "all(saleDetails,gt(orderQty,1))"
1010

1111

1212
def test_any():
13-
query = RQLQuery(saleDetails__orderQty__gt=1).any()
13+
query = RQLQuery(orderQty__gt=1).any("saleDetails")
1414

1515
result = str(query)
1616

17-
assert result == "any(gt(saleDetails.orderQty,1))"
17+
assert result == "any(saleDetails,gt(orderQty,1))"
18+
19+
20+
def test_all_multiple_conditions():
21+
order_qty_query = RQLQuery(orderQty__gt=1)
22+
price_query = RQLQuery(price__lt=100)
23+
query = (order_qty_query & price_query).all("saleDetails")
24+
25+
result = str(query)
26+
27+
assert result == "all(saleDetails,and(gt(orderQty,1),lt(price,100)))"
28+
29+
30+
def test_any_multiple_conditions():
31+
order_qty_query = RQLQuery(orderQty__gt=1)
32+
price_query = RQLQuery(price__lt=100)
33+
query = (order_qty_query & price_query).any("saleDetails")
34+
35+
result = str(query)
36+
37+
assert result == "any(saleDetails,and(gt(orderQty,1),lt(price,100)))"

0 commit comments

Comments
 (0)