Skip to content

Commit 4f941c6

Browse files
committed
PYCBC-1683: Fix search range queries to follow RFC
Motivation ========== The `DateRangeQuery`, `NumericRangeQuery` and `TermRangeQuery` search queries do not abide by the RFC and are incorrectly encoding the search JSON for some parameters. The search queries should be updated so that users can successfully use these range query types. Modification ============ * Deprecate `TermRangeQuery` properties that do not follow RFC (`start`, `end`, `start_inclusive` and `end_inclusive`) * Add properties missing from the RFC: `min`, `max`, `inclusive_min` and `inclusive_max`. * Deprecate `DateRangeQuery` properties that do not follow RFC (`start_inclusive` and `end_inclusive`) and add properties missing from the RFC (`inclusive_start` and `inclusive_end`) * Deprecate `NumericRangeQuery` properties that do not follow RFC (`min_inclusive` and `max_inclusive`) and add properties missing from the RFC (`inclusive_min` and `inclusive_max`) * Update various type definitions * Update search_param tests to confirm correct encoded JSON Results ======= All results pass. Change-Id: Ie2631a54e0762a5173ad03cc25802f6ff070f84d Reviewed-on: https://review.couchbase.org/c/couchbase-python-client/+/226327 Tested-by: Build Bot <build@couchbase.com> Reviewed-by: Dimitris Christodoulou <dimitris.christodoulou@couchbase.com>
1 parent d0250f5 commit 4f941c6

2 files changed

Lines changed: 223 additions & 36 deletions

File tree

couchbase/logic/search_queries.py

Lines changed: 134 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
from couchbase.exceptions import InvalidArgumentException, NoChildrenException
2424
from couchbase.logic.search import MatchOperator, _QueryBuilder
25+
from couchbase.logic.supportability import Supportability
2526

2627
# Query Types
2728

@@ -355,7 +356,7 @@ def bool(self, value # type: bool
355356

356357
@_QueryBuilder._with_fields(fields=['field'])
357358
class GeoDistanceQuery(SearchQuery):
358-
def __init__(self, distance, # type: Union[int, float]
359+
def __init__(self, distance, # type: str
359360
location, # type: Tuple[float, float]
360361
**kwargs # type: Dict[str, Any]
361362
) -> None:
@@ -467,7 +468,8 @@ class NumericRangeQuery(SearchQuery):
467468
At least one of `min` or `max` must be specified.
468469
"""
469470

470-
def __init__(self, min=None, # type: Optional[float]
471+
def __init__(self,
472+
min=None, # type: Optional[float]
471473
max=None, # type: Optional[float]
472474
**kwargs # type: Dict[str, Any]
473475
) -> None:
@@ -486,7 +488,8 @@ def min(self) -> Optional[float]:
486488
return self._json_.get('min', None)
487489

488490
@min.setter
489-
def min(self, value # type: float
491+
def min(self,
492+
value # type: float
490493
) -> None:
491494
self.set_prop('min', value)
492495

@@ -495,16 +498,29 @@ def min_inclusive(self) -> Optional[bool]:
495498
return self._json_.get('min_inclusive', None)
496499

497500
@min_inclusive.setter
498-
def min_inclusive(self, value # type: bool
501+
def min_inclusive(self,
502+
value # type: bool
499503
) -> None:
500-
self.set_prop('min_inclusive', value)
504+
Supportability.class_property_deprecated('min_inclusive', 'inclusive_min')
505+
self.set_prop('inclusive_min', value)
506+
507+
@property
508+
def inclusive_min(self) -> Optional[bool]:
509+
return self._json_.get('inclusive_min', None)
510+
511+
@inclusive_min.setter
512+
def inclusive_min(self,
513+
value # type: bool
514+
) -> None:
515+
self.set_prop('inclusive_min', value)
501516

502517
@property
503518
def max(self) -> Optional[float]:
504519
return self._json_.get('max', None)
505520

506521
@max.setter
507-
def max(self, value # type: float
522+
def max(self,
523+
value # type: float
508524
) -> None:
509525
self.set_prop('max', value)
510526

@@ -513,9 +529,21 @@ def max_inclusive(self) -> Optional[bool]:
513529
return self._json_.get('max_inclusive', None)
514530

515531
@max_inclusive.setter
516-
def max_inclusive(self, value # type: bool
532+
def max_inclusive(self,
533+
value # type: bool
517534
) -> None:
518-
self.set_prop('max_inclusive', value)
535+
Supportability.class_property_deprecated('max_inclusive', 'inclusive_max')
536+
self.set_prop('inclusive_max', value)
537+
538+
@property
539+
def inclusive_max(self) -> Optional[bool]:
540+
return self._json_.get('inclusive_max', None)
541+
542+
@inclusive_max.setter
543+
def inclusive_max(self,
544+
value # type: bool
545+
) -> None:
546+
self.set_prop('inclusive_max', value)
519547

520548
# min = _genprop(
521549
# float, 'min', doc='Lower bound of range. See :attr:`min_inclusive`')
@@ -570,7 +598,8 @@ def start(self) -> Optional[str]:
570598
return self._json_.get('start', None)
571599

572600
@start.setter
573-
def start(self, value # type: str
601+
def start(self,
602+
value # type: str
574603
) -> None:
575604
self.set_prop('start', value)
576605

@@ -579,16 +608,29 @@ def start_inclusive(self) -> Optional[bool]:
579608
return self._json_.get('start_inclusive', None)
580609

581610
@start_inclusive.setter
582-
def start_inclusive(self, value # type: bool
611+
def start_inclusive(self,
612+
value # type: bool
613+
) -> None:
614+
Supportability.class_property_deprecated('start_inclusive', 'inclusive_start')
615+
self.set_prop('inclusive_start', value)
616+
617+
@property
618+
def inclusive_start(self) -> Optional[bool]:
619+
return self._json_.get('inclusive_start', None)
620+
621+
@inclusive_start.setter
622+
def inclusive_start(self,
623+
value # type: bool
583624
) -> None:
584-
self.set_prop('start_inclusive', value)
625+
self.set_prop('inclusive_start', value)
585626

586627
@property
587628
def end(self) -> Optional[str]:
588629
return self._json_.get('end', None)
589630

590631
@end.setter
591-
def end(self, value # type: str
632+
def end(self,
633+
value # type: str
592634
) -> None:
593635
self.set_prop('end', value)
594636

@@ -597,16 +639,29 @@ def end_inclusive(self) -> Optional[bool]:
597639
return self._json_.get('end_inclusive', None)
598640

599641
@end_inclusive.setter
600-
def end_inclusive(self, value # type: bool
642+
def end_inclusive(self,
643+
value # type: bool
644+
) -> None:
645+
Supportability.class_property_deprecated('end_inclusive', 'inclusive_end')
646+
self.set_prop('inclusive_end', value)
647+
648+
@property
649+
def inclusive_end(self) -> Optional[bool]:
650+
return self._json_.get('inclusive_end', None)
651+
652+
@inclusive_end.setter
653+
def inclusive_end(self,
654+
value # type: bool
601655
) -> None:
602-
self.set_prop('end_inclusive', value)
656+
self.set_prop('inclusive_end', value)
603657

604658
@property
605659
def datetime_parser(self) -> Optional[str]:
606660
return self._json_.get('datetime_parser', None)
607661

608662
@datetime_parser.setter
609-
def datetime_parser(self, value # type: str
663+
def datetime_parser(self,
664+
value # type: str
610665
) -> None:
611666
self.set_prop('datetime_parser', value)
612667

@@ -638,18 +693,31 @@ class TermRangeQuery(SearchQuery):
638693
lexical range.
639694
"""
640695

641-
_MINMAX = 'start', 'end'
696+
_MINMAX = 'min', 'max'
642697

643-
def __init__(self, start=None, # type: Optional[str]
698+
def __init__(self,
699+
start=None, # type: Optional[str]
644700
end=None, # type: Optional[str]
701+
min=None, # type: Optional[str]
702+
max=None, # type: Optional[str]
645703
**kwargs # type: Dict[str, Any]
646704
) -> None:
647705
"""
648-
:param str start: See :attr:`start`
649-
:param str end: See :attr:`end`
706+
Args:
707+
start (str): **DEPRECATED** Use min.
708+
end (str): **DEPRECATED** Use max.
709+
min (str): The lower end of the range.
710+
max (str): The higher end of the range.
650711
"""
651712
super().__init__()
652-
_QueryBuilder._validate_range_query(self, start, end, **kwargs)
713+
if start is not None and min is None:
714+
Supportability.class_property_deprecated('start', 'min')
715+
min = start
716+
if end is not None and max is None:
717+
Supportability.class_property_deprecated('end', 'max')
718+
max = end
719+
720+
_QueryBuilder._validate_range_query(self, min, max, **kwargs)
653721

654722
@property
655723
def start(self) -> Optional[str]:
@@ -658,7 +726,17 @@ def start(self) -> Optional[str]:
658726
@start.setter
659727
def start(self, value # type: str
660728
) -> None:
661-
self.set_prop('start', value)
729+
Supportability.class_property_deprecated('start', 'min')
730+
self.set_prop('min', value)
731+
732+
@property
733+
def min(self) -> Optional[str]:
734+
return self._json_.get('min', None)
735+
736+
@min.setter
737+
def min(self, value # type: str
738+
) -> None:
739+
self.set_prop('min', value)
662740

663741
@property
664742
def start_inclusive(self) -> Optional[bool]:
@@ -667,7 +745,17 @@ def start_inclusive(self) -> Optional[bool]:
667745
@start_inclusive.setter
668746
def start_inclusive(self, value # type: bool
669747
) -> None:
670-
self.set_prop('start_inclusive', value)
748+
Supportability.class_property_deprecated('start_inclusive', 'inclusive_min')
749+
self.set_prop('inclusive_min', value)
750+
751+
@property
752+
def inclusive_min(self) -> Optional[bool]:
753+
return self._json_.get('start_inclusive', None)
754+
755+
@inclusive_min.setter
756+
def inclusive_min(self, value # type: bool
757+
) -> None:
758+
self.set_prop('inclusive_min', value)
671759

672760
@property
673761
def end(self) -> Optional[str]:
@@ -676,7 +764,17 @@ def end(self) -> Optional[str]:
676764
@end.setter
677765
def end(self, value # type: str
678766
) -> None:
679-
self.set_prop('end', value)
767+
Supportability.class_property_deprecated('end', 'max')
768+
self.set_prop('max', value)
769+
770+
@property
771+
def max(self) -> Optional[str]:
772+
return self._json_.get('max', None)
773+
774+
@max.setter
775+
def max(self, value # type: str
776+
) -> None:
777+
self.set_prop('max', value)
680778

681779
@property
682780
def end_inclusive(self) -> Optional[bool]:
@@ -685,7 +783,17 @@ def end_inclusive(self) -> Optional[bool]:
685783
@end_inclusive.setter
686784
def end_inclusive(self, value # type: bool
687785
) -> None:
688-
self.set_prop('end_inclusive', value)
786+
Supportability.class_property_deprecated('end_inclusive', 'inclusive_max')
787+
self.set_prop('inclusive_max', value)
788+
789+
@property
790+
def inclusive_max(self) -> Optional[bool]:
791+
return self._json_.get('inclusive_max', None)
792+
793+
@inclusive_max.setter
794+
def inclusive_max(self, value # type: bool
795+
) -> None:
796+
self.set_prop('inclusive_max', value)
689797

690798
# def __init__(self, start=None, end=None, **kwargs):
691799
# super(TermRangeQuery, self).__init__(start=start, end=end, **kwargs)
@@ -799,7 +907,7 @@ def __init__(self, must=None, should=None, must_not=None):
799907
self.must_not = must_not
800908

801909
@property
802-
def must(self) -> DisjunctionQuery:
910+
def must(self) -> ConjunctionQuery:
803911
return self._subqueries.get('must')
804912

805913
@must.setter
@@ -808,7 +916,7 @@ def must(self, value # type: CompoundQueryType
808916
self._set_query('must', value, ConjunctionQuery)
809917

810918
@property
811-
def must_not(self) -> ConjunctionQuery:
919+
def must_not(self) -> DisjunctionQuery:
812920
return self._subqueries.get('must_not')
813921

814922
@must_not.setter

0 commit comments

Comments
 (0)