|
8 | 8 | import os
|
9 | 9 | import time
|
10 | 10 | import uuid
|
11 |
| -from typing import Union, Callable, TYPE_CHECKING, Optional, Dict, List, Type, TypeVar, Tuple, Generic, Set |
| 11 | +from typing import ( |
| 12 | + Union, |
| 13 | + Callable, |
| 14 | + TYPE_CHECKING, |
| 15 | + Optional, |
| 16 | + Dict, |
| 17 | + List, |
| 18 | + Type, |
| 19 | + TypeVar, |
| 20 | + Iterator, |
| 21 | + Iterable, |
| 22 | + Tuple, |
| 23 | + Generic, |
| 24 | + Set, |
| 25 | +) |
12 | 26 |
|
13 | 27 | from ravendb.documents.session.document_session_revisions import DocumentSessionRevisions
|
14 | 28 | from ravendb.primitives import constants
|
|
22 | 36 | GetMultipleTimeSeriesOperation,
|
23 | 37 | TimeSeriesConfiguration,
|
24 | 38 | )
|
| 39 | +from ravendb.documents.commands.stream import StreamResult |
25 | 40 | from ravendb.documents.session.conditional_load import ConditionalLoadResult
|
| 41 | +from ravendb.documents.session.operations.stream import StreamOperation |
| 42 | +from ravendb.documents.session.stream_statistics import StreamQueryStatistics |
| 43 | +from ravendb.documents.session.tokens.query_tokens.definitions import FieldsToFetchToken |
26 | 44 | from ravendb.documents.session.time_series import (
|
27 | 45 | TimeSeriesEntry,
|
28 | 46 | TypedTimeSeriesEntry,
|
|
58 | 76 | from ravendb.documents.session.loaders.loaders import LoaderWithInclude, MultiLoaderWithInclude
|
59 | 77 | from ravendb.documents.session.operations.lazy import LazyLoadOperation, LazySessionOperations
|
60 | 78 | from ravendb.documents.session.operations.operations import MultiGetOperation, LoadStartingWithOperation
|
| 79 | +from ravendb.documents.session.operations.query import QueryOperation |
61 | 80 | from ravendb.documents.session.misc import (
|
62 | 81 | SessionOptions,
|
63 | 82 | ResponseTimeInformation,
|
|
67 | 86 | SessionInfo,
|
68 | 87 | TransactionMode,
|
69 | 88 | )
|
70 |
| -from ravendb.documents.session.query import DocumentQuery, RawDocumentQuery |
| 89 | +from ravendb.documents.session.query import DocumentQuery, RawDocumentQuery, AbstractDocumentQuery |
71 | 90 | from ravendb.json.metadata_as_dictionary import MetadataAsDictionary
|
72 | 91 | from ravendb.documents.session.operations.load_operation import LoadOperation
|
73 | 92 | from ravendb.tools.time_series import TSRangeHelper
|
@@ -1030,23 +1049,117 @@ def add_or_increment(self, key: str, entity: object, path_to_object: str, val_to
|
1030 | 1049 | patch_command_data.create_if_missing = new_instance
|
1031 | 1050 | self.defer(patch_command_data)
|
1032 | 1051 |
|
1033 |
| - def stream( |
1034 |
| - self, |
1035 |
| - query_or_raw_query, # : Union[RawDocumentQuery, DocumentQuery], |
1036 |
| - stream_query_stats, # : Optional[StreamQueryStatistics] = None, |
1037 |
| - ) -> iter: |
1038 |
| - pass |
| 1052 | + def stream(self, query_or_raw_query: AbstractDocumentQuery[_T]) -> Iterator[StreamResult[_T]]: |
| 1053 | + stream_operation = StreamOperation(self._session) |
| 1054 | + command = stream_operation.create_request(query_or_raw_query.index_query) |
| 1055 | + |
| 1056 | + self.request_executor.execute_command(command, self.session_info) |
| 1057 | + |
| 1058 | + result = stream_operation.set_result(command.result) |
| 1059 | + |
| 1060 | + return self._yield_result(query_or_raw_query, result) |
| 1061 | + |
| 1062 | + def stream_with_statistics( |
| 1063 | + self, query_or_raw_query: AbstractDocumentQuery[_T], stats_callback: Callable[[StreamQueryStatistics], None] |
| 1064 | + ) -> Iterator[StreamResult[_T]]: |
| 1065 | + stats = StreamQueryStatistics() |
| 1066 | + stream_operation = StreamOperation(self._session, stats) |
| 1067 | + command = stream_operation.create_request(query_or_raw_query.index_query) |
| 1068 | + |
| 1069 | + self.request_executor.execute_command(command, self.session_info) |
| 1070 | + |
| 1071 | + result = stream_operation.set_result(command.result) |
| 1072 | + |
| 1073 | + stats_callback(stats) |
| 1074 | + |
| 1075 | + return self._yield_result(query_or_raw_query, result) |
1039 | 1076 |
|
1040 | 1077 | def stream_starting_with(
|
1041 | 1078 | self,
|
1042 |
| - object_type: type, |
1043 | 1079 | starts_with: str,
|
1044 |
| - matches: str = None, |
| 1080 | + matches: Optional[str] = None, |
1045 | 1081 | start: int = 0,
|
1046 |
| - page_size: int = 25, |
1047 |
| - starting_after: str = None, |
1048 |
| - ) -> iter: |
1049 |
| - pass |
| 1082 | + page_size: int = constants.int_max, |
| 1083 | + start_after: Optional[str] = None, |
| 1084 | + object_type: Optional[Type[_T]] = None, |
| 1085 | + ) -> Iterable[StreamResult[_T]]: |
| 1086 | + stream_operation = StreamOperation(self._session) |
| 1087 | + |
| 1088 | + command = stream_operation.create_request_for_starts_with( |
| 1089 | + starts_with, matches, start, page_size, None, start_after |
| 1090 | + ) |
| 1091 | + self.request_executor.execute_command(command, self.session_info) |
| 1092 | + |
| 1093 | + result = stream_operation.set_result(command.result) |
| 1094 | + return DocumentSession._Advanced._StreamIterator(self, result, None, False, None, object_type) |
| 1095 | + |
| 1096 | + class _StreamIterator(Iterator): |
| 1097 | + def __init__( |
| 1098 | + self, |
| 1099 | + session_advanced_reference: DocumentSession._Advanced, |
| 1100 | + inner_iterator: Iterator[Dict], |
| 1101 | + fields_to_fetch_token: Optional[FieldsToFetchToken], |
| 1102 | + is_project_into: bool, |
| 1103 | + on_next_item: Optional[Callable[[Dict], None]] = None, |
| 1104 | + object_type: Optional[Type[_T]] = None, |
| 1105 | + ): |
| 1106 | + self._session_advanced_reference = session_advanced_reference |
| 1107 | + self._inner_iterator = inner_iterator |
| 1108 | + self._fields_to_fetch_token = fields_to_fetch_token |
| 1109 | + self._is_project_into = is_project_into |
| 1110 | + self._on_next_item = on_next_item |
| 1111 | + self._object_type = object_type |
| 1112 | + |
| 1113 | + def __iter__(self): |
| 1114 | + return self |
| 1115 | + |
| 1116 | + def __next__(self): |
| 1117 | + next_value = self._inner_iterator.__next__() |
| 1118 | + try: |
| 1119 | + if self._on_next_item is not None: |
| 1120 | + self._on_next_item(next_value) |
| 1121 | + return DocumentSession._Advanced._create_stream_result( |
| 1122 | + self._session_advanced_reference, |
| 1123 | + next_value, |
| 1124 | + self._fields_to_fetch_token, |
| 1125 | + self._is_project_into, |
| 1126 | + self._object_type, |
| 1127 | + ) |
| 1128 | + except Exception as e: |
| 1129 | + raise RuntimeError(f"Unable to parse stream result: {e.args[0]}", e) |
| 1130 | + |
| 1131 | + def __exit__(self, exc_type, exc_val, exc_tb): |
| 1132 | + pass |
| 1133 | + |
| 1134 | + def _create_stream_result( |
| 1135 | + self, |
| 1136 | + json_dict: Dict, |
| 1137 | + fields_to_fetch: FieldsToFetchToken, |
| 1138 | + is_project_into: bool, |
| 1139 | + object_type: Optional[Type[_T]], |
| 1140 | + ) -> StreamResult[_T]: |
| 1141 | + metadata = json_dict.get(constants.Documents.Metadata.KEY) |
| 1142 | + change_vector = metadata.get(constants.Documents.Metadata.CHANGE_VECTOR) |
| 1143 | + |
| 1144 | + # MapReduce indexes return reduce results tht don't have @id property |
| 1145 | + key = metadata.get(constants.Documents.Metadata.ID, None) |
| 1146 | + |
| 1147 | + entity = QueryOperation.deserialize( |
| 1148 | + object_type, key, json_dict, metadata, fields_to_fetch, True, self._session, is_project_into |
| 1149 | + ) |
| 1150 | + |
| 1151 | + stream_result = StreamResult(key, change_vector, MetadataAsDictionary(metadata), entity) |
| 1152 | + return stream_result |
| 1153 | + |
| 1154 | + def _yield_result(self, query: AbstractDocumentQuery, enumerator: Iterator[Dict]) -> Iterator[StreamResult[_T]]: |
| 1155 | + return DocumentSession._Advanced._StreamIterator( |
| 1156 | + self, |
| 1157 | + enumerator, |
| 1158 | + query._fields_to_fetch_token, |
| 1159 | + query.is_project_into, |
| 1160 | + query.invoke_after_stream_executed, |
| 1161 | + object_type=query.query_class, |
| 1162 | + ) |
1050 | 1163 |
|
1051 | 1164 | def stream_into(self): # query: Union[DocumentQuery, RawDocumentQuery], output: iter):
|
1052 | 1165 | pass
|
|
0 commit comments