Skip to content

Commit 33a83ce

Browse files
committed
RDBC-1023: add session.advanced.what_changed_for(entity) and get_tracked_entities()
C# Advanced.WhatChangedFor(entity) returns DocumentsChanges[] for a single entity. Python had no equivalent. Added _what_changed_for() to InMemoryDocumentSessionOperations and exposed it via Advanced.what_changed_for(). Matches C# behaviour: returns [DocumentDeleted] immediately when the entity has been deleted in the same session, before running the JSON diff. C# Advanced.GetTrackedEntities() returns a dict of all entities currently tracked by the session (stored and deleted). Added _get_tracked_entities() to InMemoryDocumentSessionOperations and exposed it via Advanced.get_tracked_entities(). Each entry maps document ID to a dict with keys: id, entity, is_deleted. Matches C# behaviour: entries deleted by string ID (present in _known_missing_ids but absent from _deleted_entities) appear with is_deleted=True. Regression tests: test_session_advanced_api.py verifies that what_changed_for() returns per-entity changes and correctly reports DocumentDeleted when the entity is deleted before the call; get_tracked_entities() includes newly stored entities with is_deleted=False and entries deleted by string id with is_deleted=True.
1 parent 58297b7 commit 33a83ce

7 files changed

Lines changed: 322 additions & 283 deletions

File tree

ravendb/documents/session/document_info.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,5 @@ def get_new_document_info(cls, document: Dict) -> DocumentInfo:
4444
if not change_vector or not isinstance(change_vector, str):
4545
raise ValueError(f"Document {key} must have a Change Vector")
4646

47+
# Shallow-copy metadata so mutations on this DocumentInfo don't alias the original document dict
4748
return cls(key=key, document=document, metadata=dict(metadata), entity=None, change_vector=change_vector)

ravendb/documents/session/document_session.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -803,6 +803,12 @@ def graph_query(self, object_type: type, query: str): # -> GraphDocumentQuery:
803803
def what_changed(self) -> Dict[str, List[DocumentsChanges]]:
804804
return self._session._what_changed()
805805

806+
def what_changed_for(self, entity: object) -> List[DocumentsChanges]:
807+
return self._session._what_changed_for(entity)
808+
809+
def get_tracked_entities(self) -> Dict[str, dict]:
810+
return self._session._get_tracked_entities()
811+
806812
def exists(self, key: str) -> bool:
807813
if key is None:
808814
raise ValueError("Key cannot be None")

ravendb/documents/session/document_session_operations/in_memory_document_session_operations.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,6 +1183,51 @@ def _what_changed(self) -> Dict[str, List[DocumentsChanges]]:
11831183

11841184
return changes
11851185

1186+
def _what_changed_for(self, entity: object) -> List[DocumentsChanges]:
1187+
if (doc_info := self._documents_by_entity.get(entity)) is None:
1188+
return []
1189+
if entity in self._deleted_entities:
1190+
return [
1191+
DocumentsChanges(
1192+
field_old_value="",
1193+
field_new_value="",
1194+
change=DocumentsChanges.ChangeType.DOCUMENT_DELETED,
1195+
)
1196+
]
1197+
_update_metadata_modifications(doc_info.metadata_instance, doc_info.metadata)
1198+
new_obj = self.entity_to_json.convert_entity_to_json(entity, doc_info)
1199+
changes: Dict[str, List[DocumentsChanges]] = {}
1200+
if not self._entity_changed(new_obj, doc_info, changes):
1201+
return []
1202+
return [
1203+
DocumentsChanges(
1204+
field_old_value=d["old_value"],
1205+
field_new_value=d["new_value"],
1206+
change=d["change"],
1207+
field_name=d["field_name"],
1208+
field_path=d["field_path"],
1209+
)
1210+
for d in changes.get(doc_info.key, [])
1211+
]
1212+
1213+
def _get_tracked_entities(self) -> Dict[str, dict]:
1214+
result = {}
1215+
for entity_result in self._documents_by_entity:
1216+
doc_info = entity_result.value
1217+
result[doc_info.key] = {
1218+
"id": doc_info.key,
1219+
"entity": entity_result.key,
1220+
"is_deleted": self.is_deleted(doc_info.key),
1221+
}
1222+
for key in self._known_missing_ids:
1223+
if key not in result:
1224+
result[key] = {
1225+
"id": key,
1226+
"entity": None,
1227+
"is_deleted": True,
1228+
}
1229+
return result
1230+
11861231
def __get_all_entities_changes(self, changes: Dict[str, List[DocumentsChanges]]) -> None:
11871232
for key, value in self._documents_by_id.items():
11881233
_update_metadata_modifications(value.metadata_instance, value.metadata)

ravendb/json/json_operation.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,10 @@ def compare_json_array(field_path: str, key: str, old_collection, new_collection
193193
DocumentsChanges.ChangeType.ARRAY_VALUE_CHANGED,
194194
)
195195
elif isinstance(new_collection_item, (int, float, bool, str)):
196-
if type(old_collection_item) != type(new_collection_item) or old_collection_item != new_collection_item:
196+
if (
197+
type(old_collection_item) is not type(new_collection_item)
198+
or old_collection_item != new_collection_item
199+
):
197200
if changes is not None:
198201
JsonOperation.new_change(
199202
JsonOperation.add_index_field_path(field_path, position),

0 commit comments

Comments
 (0)