Skip to content

Commit b1da9f7

Browse files
committed
RDBC-685 Around 25+ tests, include counters on query
1 parent c130c08 commit b1da9f7

File tree

6 files changed

+171
-145
lines changed

6 files changed

+171
-145
lines changed

ravendb/documents/session/loaders/include.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def _include_compare_exchange_value(self, path: str) -> None:
4343

4444
def _include_counter_with_alias(self, path: str, *names: str) -> None:
4545
self._with_alias()
46-
self._include_counters(path, *names)
46+
self._include_counters(path, list(names) if isinstance(names, tuple) else [names])
4747

4848
def _include_documents(self, path: str):
4949
if not self._documents_to_include:
@@ -113,12 +113,13 @@ def include_documents(self, path: str) -> IncludeBuilderBase:
113113
self._include_documents(path)
114114
return self
115115

116-
def include_counter(self, *names: str) -> IncludeBuilderBase:
117-
self._include_counters("", [names] if isinstance(names, str) else names)
116+
def include_counter(self, name: str) -> IncludeBuilderBase:
117+
self._include_counters("", [name])
118118
return self
119119

120-
def include_counters(self, names: List[str]) -> IncludeBuilderBase:
121-
self.include_counter(*names)
120+
def include_counters(self, *names: str) -> IncludeBuilderBase:
121+
for name in names:
122+
self.include_counter(name)
122123
return self
123124

124125
def include_all_counters(self) -> IncludeBuilderBase:
@@ -141,8 +142,12 @@ def include_compare_exchange_value(self, path: str) -> IncludeBuilderBase:
141142

142143

143144
class QueryIncludeBuilder(IncludeBuilderBase):
145+
def include_counter(self, name:str, path: Optional[str] = ""):
146+
self._include_counter_with_alias(path, name)
147+
return self
148+
144149
def include_counters(self, *names: str, path: Optional[str] = ""):
145-
self._include_counter_with_alias(path, *names)
150+
self._include_counter_with_alias(path, *names if isinstance(names, tuple) else names)
146151
return self
147152

148153
def include_all_counters(self, path: Optional[str] = ""):

ravendb/documents/session/operations/query.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,10 @@ def __complete_internal(
130130
query_result.results, query_result.includes, query_result.included_paths
131131
)
132132

133-
# todo: counters and timeseries
134133
if query_result.counter_includes is not None:
135-
raise NotImplementedError()
134+
self.__session.register_counters(query_result.counter_includes, query_result.included_counter_names)
136135

136+
# todo: timeseries
137137
if query_result.time_series_includes is not None:
138138
raise NotImplementedError()
139139

ravendb/documents/session/query.py

Lines changed: 59 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
DistinctToken,
8383
ShapeToken,
8484
SuggestToken,
85+
CounterIncludesToken,
8586
)
8687
from ravendb.documents.session.utils.document_query import DocumentQueryHelper
8788
from ravendb.documents.session.utils.includes_util import IncludesUtil
@@ -101,11 +102,11 @@ def __init__(
101102
self,
102103
object_type: Type[_T],
103104
session: "InMemoryDocumentSessionOperations",
104-
index_name: Union[None, str],
105-
collection_name: Union[None, str],
105+
index_name: Optional[str],
106+
collection_name: Optional[str],
106107
is_group_by: bool,
107-
declare_tokens: Union[None, List[DeclareToken]],
108-
load_tokens: Union[None, List[LoadToken]],
108+
declare_tokens: Optional[List[DeclareToken]],
109+
load_tokens: Optional[List[LoadToken]],
109110
from_alias: Optional[str] = None,
110111
is_project_into: Optional[bool] = False,
111112
):
@@ -121,30 +122,31 @@ def __init__(
121122
self.__conventions = DocumentConventions() if session is None else session.conventions
122123
self.is_project_into = is_project_into if is_project_into is not None else False
123124

124-
self._is_intersect: Union[None, bool] = None
125-
self.__is_in_more_like_this: Union[None, bool] = None
126-
self._includes_alias: Union[None, str] = None
127-
self._negate: Union[None, bool] = None
128-
self._query_raw: Union[None, str] = None
125+
self._is_intersect: Optional[bool] = None
126+
self.__is_in_more_like_this: Optional[bool] = None
127+
self._includes_alias: Optional[str] = None
128+
self._negate: Optional[bool] = None
129+
self._query_raw: Optional[str] = None
129130
self._query_parameters: Dict[str, object] = {}
130131
self.__alias_to_group_by_field_name: Dict[str, str] = {}
131132

132133
self._document_includes: Set[str] = set()
133-
self._page_size: Union[None, int] = None
134-
self._start: Union[None, int] = None
134+
self._page_size: Optional[int] = None
135+
self._start: Optional[int] = None
135136
self.__current_clause_depth: int = 0
136137

137138
self._select_tokens: List[QueryToken] = []
138-
self._fields_to_fetch_token: Union[None, FieldsToFetchToken] = None
139+
self._fields_to_fetch_token: Optional[FieldsToFetchToken] = None
139140
self._where_tokens: List[QueryToken] = []
140141
self._group_by_tokens: List[QueryToken] = []
141142
self._order_by_tokens: List[QueryToken] = []
142143
self._with_tokens: List[QueryToken] = []
143144
self._compare_exchange_includes_tokens: List[CompareExchangeValueIncludesToken] = []
144145
self._highlighting_tokens: List[HighlightingToken] = []
145146
self._query_highlightings: QueryHighlightings = QueryHighlightings()
146-
self._explanation_token: Union[None, ExplanationToken] = None
147-
self._explanations: Union[None, Explanations] = None
147+
self._explanation_token: Optional[ExplanationToken] = None
148+
self._explanations: Optional[Explanations] = None
149+
self._counter_includes_tokens: Optional[List[CounterIncludesToken]] = None
148150

149151
self._before_query_executed_callback: List[Callable[[IndexQuery], None]] = []
150152
self._after_query_executed_callback: List[Callable[[QueryResult], None]] = [
@@ -153,16 +155,16 @@ def __init__(
153155
self._after_stream_executed_callback: List[Callable[[Dict], None]] = []
154156

155157
self._query_stats = QueryStatistics()
156-
self._disable_entities_tracking: Union[None, bool] = None
157-
self._disable_caching: Union[None, bool] = None
158-
self._projection_behavior: Union[None, ProjectionBehavior] = None
158+
self._disable_entities_tracking: Optional[bool] = None
159+
self._disable_caching: Optional[bool] = None
160+
self._projection_behavior: Optional[ProjectionBehavior] = None
159161
self.parameter_prefix = "p"
160-
self._query_timings: Union[None, QueryTimings] = None
162+
self._query_timings: Optional[QueryTimings] = None
161163
self._default_operator = QueryOperator.AND
162-
self._the_wait_for_non_stale_results: Union[None, bool] = None
163-
self._timeout: Union[None, datetime.timedelta] = None
164+
self._the_wait_for_non_stale_results: Optional[bool] = None
165+
self._timeout: Optional[datetime.timedelta] = None
164166

165-
self._query_operation: Union[None, QueryOperation] = None
167+
self._query_operation: Optional[QueryOperation] = None
166168

167169
@property
168170
def conventions(self) -> DocumentConventions:
@@ -211,7 +213,7 @@ def _using_default_operator(self, operator: QueryOperator) -> None:
211213

212214
self._default_operator = operator
213215

214-
def _wait_for_non_stale_results(self, wait_timeout: Union[None, datetime.timedelta]) -> None:
216+
def _wait_for_non_stale_results(self, wait_timeout: Optional[datetime.timedelta]) -> None:
215217
# Graph queries may set this property multiple times
216218
if self._the_wait_for_non_stale_results:
217219
if self._timeout is None or (wait_timeout is not None and self._timeout.seconds < wait_timeout.seconds):
@@ -367,7 +369,7 @@ def _include(self, path_or_include_builder: Union[str, IncludeBuilderBase]) -> N
367369
self._document_includes.update(includes._documents_to_include)
368370

369371
# todo: counters and time series includes
370-
# self._include_counters(includes.alias, includes.counters_to_include_by_source_path)
372+
self._include_counters(includes._alias, includes._counters_to_include_by_source_path)
371373
# if includes.time_series_to_include_by_source_alias is not None:
372374
# self._include_time_series(includes.alias, includes.time_series_to_include_by_source_alias)
373375
if includes._compare_exchange_values_to_include is not None:
@@ -461,7 +463,7 @@ def __if_value_is_method(self, op: WhereOperator, where_params: WhereParams, tok
461463
for arg in mc.args:
462464
args.append(self.__add_query_parameter(arg))
463465

464-
token: Union[None, WhereToken] = None
466+
token: Optional[WhereToken] = None
465467
object_type = type(mc)
466468
if object_type == CmpXchg:
467469
token = WhereToken.create(
@@ -918,7 +920,7 @@ def __build_include(self, query_text: List[str]) -> None:
918920
and self._explanation_token is None
919921
and self._query_timings is None
920922
and not self._compare_exchange_includes_tokens
921-
# todo: and self._counter_includes_tokens is None
923+
and self._counter_includes_tokens is None
922924
# todo: and self._time_series_includes_tokens is None
923925
):
924926
return
@@ -939,7 +941,7 @@ def __build_include(self, query_text: List[str]) -> None:
939941
query_text.append(include)
940942

941943
# todo: counters & time series
942-
# first = self.__write_include_tokens(self._counter_includes_tokens, first, query_text)
944+
first = self.__write_include_tokens(self._counter_includes_tokens, first, query_text)
943945
# first = self.__write_include_tokens(self._time_series_includes_tokens, first, query_text)
944946
first = self.__write_include_tokens(self._compare_exchange_includes_tokens, first, query_text)
945947
first = self.__write_include_tokens(self._highlighting_tokens, first, query_text)
@@ -1167,7 +1169,7 @@ def __transform_collection(self, field_name: str, values: List) -> List:
11671169
result.append(self.__transform_value(nested_where_params))
11681170
return result
11691171

1170-
def __negate_if_needed(self, tokens: List[QueryToken], field_name: Union[None, str]) -> None:
1172+
def __negate_if_needed(self, tokens: List[QueryToken], field_name: Optional[str]) -> None:
11711173
if not self._negate:
11721174
return
11731175

@@ -1260,12 +1262,15 @@ def add_alias_to_includes_tokens(self, from_alias: str) -> str:
12601262
from_alias = self._includes_alias
12611263
self.add_from_alias_to_where_tokens(from_alias)
12621264

1263-
# todo: counter and time series tokens
1265+
if self._counter_includes_tokens is not None:
1266+
for counter_includes_token in self._counter_includes_tokens:
1267+
counter_includes_token.add_alias_to_path(from_alias)
1268+
# todo: time series tokens
12641269

12651270
return from_alias
12661271

12671272
@staticmethod
1268-
def _get_source_alias_if_exists(object_type: type, query_data: QueryData, fields: List[str]) -> Union[None, str]:
1273+
def _get_source_alias_if_exists(object_type: type, query_data: QueryData, fields: List[str]) -> Optional[str]:
12691274
if len(fields) != 1 or fields[0] is None:
12701275
return None
12711276
try:
@@ -1556,7 +1561,7 @@ def __execute_actual_query(self) -> None:
15561561
def __iter__(self) -> Iterator[_T]:
15571562
return self.__execute_query_operation(None).__iter__()
15581563

1559-
def __execute_query_operation(self, take: Union[None, int]) -> List[_T]:
1564+
def __execute_query_operation(self, take: Optional[int]) -> List[_T]:
15601565
self.__execute_query_operation_internal(take)
15611566

15621567
return self._query_operation.complete(self._object_type)
@@ -1603,7 +1608,7 @@ def count_lazily(self) -> Lazy[int]:
16031608
self._the_session: "DocumentSession"
16041609
return self._the_session.add_lazy_count_operation(self.lazy_query_operation)
16051610

1606-
def _suggest_using(self, suggestion: Union[None, SuggestionBase]) -> None:
1611+
def _suggest_using(self, suggestion: Optional[SuggestionBase]) -> None:
16071612
if suggestion is None:
16081613
raise ValueError("suggestion cannot be None")
16091614

@@ -1664,9 +1669,25 @@ def _include_explanations(
16641669
self._explanations = Explanations()
16651670
explanations_callback(self._explanations)
16661671

1667-
# todo: counters
1668-
def _include_counters(self, alias: str, counter_to_include_by_doc_id: Dict[str, Tuple[bool, Set[str]]]) -> None:
1669-
raise NotImplementedError()
1672+
def _include_counters(
1673+
self, alias: str, counter_to_include_by_doc_id: Optional[Dict[str, Tuple[bool, Set[str]]]]
1674+
) -> None:
1675+
if not counter_to_include_by_doc_id:
1676+
return
1677+
1678+
self._counter_includes_tokens = []
1679+
self._includes_alias = alias
1680+
1681+
for key, value in counter_to_include_by_doc_id.items():
1682+
if value[0]:
1683+
self._counter_includes_tokens.append(CounterIncludesToken.all(key))
1684+
continue
1685+
1686+
if not value[1]:
1687+
continue
1688+
1689+
for name in value[1]:
1690+
self._counter_includes_tokens.append(CounterIncludesToken.create(key, name))
16701691

16711692
# todo: time series
16721693
# def _include_time_series(self, alias:str, time_series_to_include:Dict[str,Set[AbstractTimeSeriesRange]]) -> None:
@@ -2041,7 +2062,7 @@ def create_document_query_internal(
20412062
query._the_wait_for_non_stale_results = self._the_wait_for_non_stale_results
20422063
query._negate = self._negate
20432064
query._document_includes = self._document_includes
2044-
# todo: self._counter_includes_tokens = self._counter_includes_tokens
2065+
query._counter_includes_tokens = self._counter_includes_tokens
20452066
# todo: self._time_series_includes_tokens = self._time_series_includes_tokens
20462067
query._compare_exchange_includes_tokens = self._compare_exchange_includes_tokens
20472068
query._root_types = {self._object_type}
@@ -2346,9 +2367,9 @@ def __init__(self):
23462367
self.nested_path = False
23472368
self.allow_wildcards = False
23482369

2349-
self.field_name: Union[None, str] = None
2350-
self.value: Union[None, object] = None
2351-
self.exact: Union[None, bool] = None
2370+
self.field_name: Optional[str] = None
2371+
self.value: Optional[object] = None
2372+
self.exact: Optional[bool] = None
23522373

23532374

23542375
class QueryStatistics:

0 commit comments

Comments
 (0)