5
5
from abc import abstractmethod , ABC
6
6
from datetime import timedelta , datetime
7
7
from enum import Enum
8
- from typing import Dict , List , Tuple , Callable , Union , Optional , Generic , Type
8
+ from typing import Dict , List , Tuple , Callable , Union , Optional , Generic , Type , Any , TYPE_CHECKING
9
9
10
10
import inflect
11
11
25
25
26
26
_T = TypeVar ("_T" )
27
27
28
+ if TYPE_CHECKING :
29
+ from ravendb .documents .session .document_session_operations .in_memory_document_session_operations import (
30
+ InMemoryDocumentSessionOperations ,
31
+ )
32
+
28
33
29
34
class DocumentConventions (object ):
30
35
@classmethod
@@ -63,7 +68,8 @@ def __init__(self):
63
68
64
69
# Utilities
65
70
self .document_id_generator : Optional [Callable [[str , object ], str ]] = None
66
- self ._find_identity_property = lambda q : q .__name__ == "key"
71
+ self ._find_identity_property_name : Callable [[Type [Any ]], str ] = lambda type_ : "Id"
72
+ self ._id_property_name_cache : Dict [Type , str ] = {}
67
73
self ._find_python_class : Optional [Callable [[str , Dict ], str ]] = None
68
74
self ._find_collection_name : Callable [[Type ], str ] = self .default_get_collection_name
69
75
self ._find_collection_name_for_dict : Callable [[str ], str ] = self .default_get_collection_name_for_dict
@@ -106,7 +112,7 @@ def find_collection_name(self) -> Callable[[type], str]:
106
112
107
113
@find_collection_name .setter
108
114
def find_collection_name (self , value ) -> None :
109
- self .__assert_not_frozen ()
115
+ self ._assert_not_frozen ()
110
116
self ._find_collection_name = value
111
117
112
118
@property
@@ -122,7 +128,7 @@ def __default(key: str, doc: Dict) -> Optional[str]:
122
128
123
129
@find_python_class .setter
124
130
def find_python_class (self , value : Callable [[str , Dict ], str ]):
125
- self .__assert_not_frozen ()
131
+ self ._assert_not_frozen ()
126
132
self ._find_python_class = value
127
133
128
134
def get_python_class (self , key : str , document : Dict ) -> str :
@@ -134,7 +140,7 @@ def transform_class_collection_name_to_document_id_prefix(self) -> Callable[[str
134
140
135
141
@transform_class_collection_name_to_document_id_prefix .setter
136
142
def transform_class_collection_name_to_document_id_prefix (self , value : Callable [[str ], str ]) -> None :
137
- self .__assert_not_frozen ()
143
+ self ._assert_not_frozen ()
138
144
self ._transform_class_collection_name_to_document_id_prefix = value
139
145
140
146
@property
@@ -167,7 +173,7 @@ def find_python_class_name(self) -> Callable[[type], str]:
167
173
168
174
@find_python_class_name .setter
169
175
def find_python_class_name (self , value ) -> None :
170
- self .__assert_not_frozen ()
176
+ self ._assert_not_frozen ()
171
177
self ._find_python_class_name = value
172
178
173
179
@property
@@ -176,7 +182,7 @@ def should_ignore_entity_changes(self) -> ShouldIgnoreEntityChanges:
176
182
177
183
@should_ignore_entity_changes .setter
178
184
def should_ignore_entity_changes (self , value : ShouldIgnoreEntityChanges ) -> None :
179
- self .__assert_not_frozen ()
185
+ self ._assert_not_frozen ()
180
186
self ._should_ignore_entity_changes = value
181
187
182
188
@property
@@ -185,7 +191,7 @@ def load_balancer_context_seed(self) -> int:
185
191
186
192
@load_balancer_context_seed .setter
187
193
def load_balancer_context_seed (self , value : int ):
188
- self .__assert_not_frozen ()
194
+ self ._assert_not_frozen ()
189
195
self ._load_balancer_context_seed = value
190
196
191
197
@property
@@ -194,7 +200,7 @@ def load_balance_behavior(self):
194
200
195
201
@load_balance_behavior .setter
196
202
def load_balance_behavior (self , value : LoadBalanceBehavior ):
197
- self .__assert_not_frozen ()
203
+ self ._assert_not_frozen ()
198
204
self ._load_balance_behavior = value
199
205
200
206
@property
@@ -203,7 +209,7 @@ def read_balance_behavior(self) -> ReadBalanceBehavior:
203
209
204
210
@read_balance_behavior .setter
205
211
def read_balance_behavior (self , value : ReadBalanceBehavior ):
206
- self .__assert_not_frozen ()
212
+ self ._assert_not_frozen ()
207
213
self ._read_balance_behavior = value
208
214
209
215
@property
@@ -216,9 +222,17 @@ def disable_atomic_document_writes_in_cluster_wide_transaction(self) -> bool:
216
222
217
223
@disable_atomic_document_writes_in_cluster_wide_transaction .setter
218
224
def disable_atomic_document_writes_in_cluster_wide_transaction (self , value : bool ):
219
- self .__assert_not_frozen ()
225
+ self ._assert_not_frozen ()
220
226
self ._disable_atomic_document_writes_in_cluster_wide_transaction = value
221
227
228
+ @property
229
+ def find_identity_property_name (self ) -> Callable [[Type [Any ]], str ]:
230
+ return self ._find_identity_property_name
231
+
232
+ @find_identity_property_name .setter
233
+ def find_identity_property_name (self , find_identity_property_name_function : Callable [[Type [Any ]], str ]):
234
+ self ._find_identity_property_name = find_identity_property_name_function
235
+
222
236
@staticmethod
223
237
def json_default (o ):
224
238
if o is None :
@@ -325,7 +339,7 @@ def default_get_collection_name_for_dict(key: str) -> str:
325
339
return result
326
340
327
341
@staticmethod
328
- def try_get_type_from_metadata (metadata ) :
342
+ def try_get_type_from_metadata (metadata : Dict [ str , Any ]) -> Optional [ str ] :
329
343
if "Raven-Python-Type" in metadata :
330
344
return metadata ["Raven-Python-Type" ]
331
345
return None
@@ -355,7 +369,7 @@ def range_field_name(field_name, type_name):
355
369
356
370
return field_name
357
371
358
- def __assert_not_frozen (self ) -> None :
372
+ def _assert_not_frozen (self ) -> None :
359
373
if self ._frozen :
360
374
raise RuntimeError (
361
375
"Conventions has been frozen after documentStore.initialize()" " and no changes can be applied to them"
@@ -370,7 +384,7 @@ def clone(self) -> DocumentConventions:
370
384
cloned ._save_enums_as_integers = self ._save_enums_as_integers
371
385
cloned .identity_parts_separator = self .identity_parts_separator
372
386
cloned .disable_topology_updates = self .disable_topology_updates
373
- cloned ._find_identity_property = self ._find_identity_property
387
+ cloned ._find_identity_property_name = self ._find_identity_property_name
374
388
375
389
cloned .document_id_generator = self .document_id_generator
376
390
@@ -384,6 +398,19 @@ def clone(self) -> DocumentConventions:
384
398
cloned ._read_balance_behavior = self ._read_balance_behavior
385
399
cloned ._load_balance_behavior = self ._load_balance_behavior
386
400
self ._max_http_cache_size = self ._max_http_cache_size
401
+ return cloned
402
+
403
+ def get_identity_property_name (self , object_type : Type [Any ]) -> Optional [str ]:
404
+ # Check the cache first
405
+ if object_type in self ._id_property_name_cache :
406
+ return self ._id_property_name_cache [object_type ]
407
+
408
+ id_property_name = self .find_identity_property_name (object_type )
409
+
410
+ # Cache the result
411
+ self ._id_property_name_cache [object_type ] = id_property_name
412
+
413
+ return id_property_name
387
414
388
415
def update_from (self , configuration : ClientConfiguration ):
389
416
if configuration .disabled and self ._original_configuration is None :
@@ -479,7 +506,7 @@ def update_from(self, configuration: ClientConfiguration):
479
506
480
507
@staticmethod
481
508
def default_transform_collection_name_to_document_id_prefix (collection_name : str ) -> str :
482
- upper_count = len (list (filter (str .isupper , collection_name )))
509
+ upper_count = len (list (filter (str .isupper , [ char for char in collection_name ] )))
483
510
if upper_count <= 1 :
484
511
return collection_name .lower ()
485
512
0 commit comments