|
29 | 29 | node_attr_dict_factory, |
30 | 30 | node_dict_factory, |
31 | 31 | ) |
32 | | -from .function import get_node_id |
| 32 | +from .function import get_node_id, mirror_to_nxcg |
33 | 33 | from .reportviews import ArangoEdgeView, ArangoNodeView |
34 | 34 |
|
35 | 35 | networkx_api = nxadb.utils.decorators.networkx_class(nx.Graph) # type: ignore |
@@ -195,12 +195,14 @@ def __init__( |
195 | 195 | symmetrize_edges: bool = False, |
196 | 196 | use_arango_views: bool = False, |
197 | 197 | overwrite_graph: bool = False, |
| 198 | + mirror_crud_to_nxcg: bool = False, |
198 | 199 | *args: Any, |
199 | 200 | **kwargs: Any, |
200 | 201 | ): |
201 | 202 | self.__db = None |
202 | 203 | self.__use_arango_views = use_arango_views |
203 | 204 | self.__graph_exists_in_db = False |
| 205 | + self.__mirror_crud_to_nxcg = mirror_crud_to_nxcg |
204 | 206 |
|
205 | 207 | self.__set_db(db) |
206 | 208 | if all([self.__db, name]): |
@@ -261,11 +263,19 @@ def __init__( |
261 | 263 | self.subgraph = self.subgraph_override |
262 | 264 | self.clear = self.clear_override |
263 | 265 | self.clear_edges = self.clear_edges_override |
264 | | - self.add_node = self.add_node_override |
265 | | - self.add_nodes_from = self.add_nodes_from_override |
266 | 266 | self.number_of_edges = self.number_of_edges_override |
267 | 267 | self.nbunch_iter = self.nbunch_iter_override |
268 | 268 |
|
| 269 | + self.add_node = self.add_node_override |
| 270 | + self.add_nodes_from = self.add_nodes_from_override |
| 271 | + self.remove_node = self.remove_node_override |
| 272 | + self.remove_nodes_from = self.remove_nodes_from_override |
| 273 | + self.add_edge = self.add_edge_override |
| 274 | + self.add_edges_from = self.add_edges_from_override |
| 275 | + self.remove_edge = self.remove_edge_override |
| 276 | + self.remove_edges_from = self.remove_edges_from_override |
| 277 | + self.update = self.update_override |
| 278 | + |
269 | 279 | # If incoming_graph_data wasn't loaded by the NetworkX Adapter, |
270 | 280 | # then we can rely on the CRUD operations of the modified dictionaries |
271 | 281 | # to load the data into the graph. However, if the graph is directed |
@@ -541,6 +551,10 @@ def is_smart(self) -> bool: |
541 | 551 | def smart_field(self) -> str | None: |
542 | 552 | return self.__smart_field |
543 | 553 |
|
| 554 | + @property |
| 555 | + def mirror_crud_to_nxcg(self) -> bool: |
| 556 | + return self.__mirror_crud_to_nxcg |
| 557 | + |
544 | 558 | ########### |
545 | 559 | # Setters # |
546 | 560 | ########### |
@@ -691,81 +705,6 @@ def clear_edges_override(self): |
691 | 705 | nbr_dict.clear() |
692 | 706 | nx._clear_cache(self) |
693 | 707 |
|
694 | | - def add_node_override(self, node_for_adding, **attr): |
695 | | - if node_for_adding is None: |
696 | | - raise ValueError("None cannot be a node") |
697 | | - |
698 | | - if node_for_adding not in self._node: |
699 | | - self._adj[node_for_adding] = self.adjlist_inner_dict_factory() |
700 | | - |
701 | | - ###################### |
702 | | - # NOTE: monkey patch # |
703 | | - ###################### |
704 | | - |
705 | | - # Old: |
706 | | - # attr_dict = self._node[node_for_adding] = self.node_attr_dict_factory() |
707 | | - # attr_dict.update(attr) |
708 | | - |
709 | | - # New: |
710 | | - node_attr_dict = self.node_attr_dict_factory() |
711 | | - node_attr_dict.data = attr |
712 | | - self._node[node_for_adding] = node_attr_dict |
713 | | - |
714 | | - # Reason: |
715 | | - # We can optimize the process of adding a node by creating avoiding |
716 | | - # the creation of a new dictionary and updating it with the attributes. |
717 | | - # Instead, we can create a new node_attr_dict object and set the attributes |
718 | | - # directly. This only makes 1 network call to the database instead of 2. |
719 | | - |
720 | | - ########################### |
721 | | - |
722 | | - else: |
723 | | - self._node[node_for_adding].update(attr) |
724 | | - |
725 | | - nx._clear_cache(self) |
726 | | - |
727 | | - def add_nodes_from_override(self, nodes_for_adding, **attr): |
728 | | - for n in nodes_for_adding: |
729 | | - try: |
730 | | - newnode = n not in self._node |
731 | | - newdict = attr |
732 | | - except TypeError: |
733 | | - n, ndict = n |
734 | | - newnode = n not in self._node |
735 | | - newdict = attr.copy() |
736 | | - newdict.update(ndict) |
737 | | - if newnode: |
738 | | - if n is None: |
739 | | - raise ValueError("None cannot be a node") |
740 | | - self._adj[n] = self.adjlist_inner_dict_factory() |
741 | | - |
742 | | - ###################### |
743 | | - # NOTE: monkey patch # |
744 | | - ###################### |
745 | | - |
746 | | - # Old: |
747 | | - # self._node[n] = self.node_attr_dict_factory() |
748 | | - # |
749 | | - # self._node[n].update(newdict) |
750 | | - |
751 | | - # New: |
752 | | - node_attr_dict = self.node_attr_dict_factory() |
753 | | - node_attr_dict.data = newdict |
754 | | - self._node[n] = node_attr_dict |
755 | | - |
756 | | - else: |
757 | | - self._node[n].update(newdict) |
758 | | - |
759 | | - # Reason: |
760 | | - # We can optimize the process of adding a node by creating avoiding |
761 | | - # the creation of a new dictionary and updating it with the attributes. |
762 | | - # Instead, we create a new node_attr_dict object and set the attributes |
763 | | - # directly. This only makes 1 network call to the database instead of 2. |
764 | | - |
765 | | - ########################### |
766 | | - |
767 | | - nx._clear_cache(self) |
768 | | - |
769 | 708 | def number_of_edges_override(self, u=None, v=None): |
770 | 709 | if u is not None: |
771 | 710 | return super().number_of_edges(u, v) |
@@ -847,3 +786,108 @@ def bunch_iter(nlist, adj): |
847 | 786 |
|
848 | 787 | bunch = bunch_iter(nbunch, self._adj) |
849 | 788 | return bunch |
| 789 | + |
| 790 | + @mirror_to_nxcg |
| 791 | + def add_node_override(self, node_for_adding, **attr): |
| 792 | + if node_for_adding is None: |
| 793 | + raise ValueError("None cannot be a node") |
| 794 | + |
| 795 | + if node_for_adding not in self._node: |
| 796 | + self._adj[node_for_adding] = self.adjlist_inner_dict_factory() |
| 797 | + |
| 798 | + ###################### |
| 799 | + # NOTE: monkey patch # |
| 800 | + ###################### |
| 801 | + |
| 802 | + # Old: |
| 803 | + # attr_dict = self._node[node_for_adding] = self.node_attr_dict_factory() |
| 804 | + # attr_dict.update(attr) |
| 805 | + |
| 806 | + # New: |
| 807 | + node_attr_dict = self.node_attr_dict_factory() |
| 808 | + node_attr_dict.data = attr |
| 809 | + self._node[node_for_adding] = node_attr_dict |
| 810 | + |
| 811 | + # Reason: |
| 812 | + # We can optimize the process of adding a node by creating avoiding |
| 813 | + # the creation of a new dictionary and updating it with the attributes. |
| 814 | + # Instead, we can create a new node_attr_dict object and set the attributes |
| 815 | + # directly. This only makes 1 network call to the database instead of 2. |
| 816 | + |
| 817 | + ########################### |
| 818 | + |
| 819 | + else: |
| 820 | + self._node[node_for_adding].update(attr) |
| 821 | + |
| 822 | + nx._clear_cache(self) |
| 823 | + |
| 824 | + @mirror_to_nxcg |
| 825 | + def add_nodes_from_override(self, nodes_for_adding, **attr): |
| 826 | + for n in nodes_for_adding: |
| 827 | + try: |
| 828 | + newnode = n not in self._node |
| 829 | + newdict = attr |
| 830 | + except TypeError: |
| 831 | + n, ndict = n |
| 832 | + newnode = n not in self._node |
| 833 | + newdict = attr.copy() |
| 834 | + newdict.update(ndict) |
| 835 | + if newnode: |
| 836 | + if n is None: |
| 837 | + raise ValueError("None cannot be a node") |
| 838 | + self._adj[n] = self.adjlist_inner_dict_factory() |
| 839 | + |
| 840 | + ###################### |
| 841 | + # NOTE: monkey patch # |
| 842 | + ###################### |
| 843 | + |
| 844 | + # Old: |
| 845 | + # self._node[n] = self.node_attr_dict_factory() |
| 846 | + # |
| 847 | + # self._node[n].update(newdict) |
| 848 | + |
| 849 | + # New: |
| 850 | + node_attr_dict = self.node_attr_dict_factory() |
| 851 | + node_attr_dict.data = newdict |
| 852 | + self._node[n] = node_attr_dict |
| 853 | + |
| 854 | + else: |
| 855 | + self._node[n].update(newdict) |
| 856 | + |
| 857 | + # Reason: |
| 858 | + # We can optimize the process of adding a node by creating avoiding |
| 859 | + # the creation of a new dictionary and updating it with the attributes. |
| 860 | + # Instead, we create a new node_attr_dict object and set the attributes |
| 861 | + # directly. This only makes 1 network call to the database instead of 2. |
| 862 | + |
| 863 | + ########################### |
| 864 | + |
| 865 | + nx._clear_cache(self) |
| 866 | + |
| 867 | + @mirror_to_nxcg |
| 868 | + def remove_node_override(self, n): |
| 869 | + super().remove_node(n) |
| 870 | + |
| 871 | + @mirror_to_nxcg |
| 872 | + def remove_nodes_from_override(self, nodes): |
| 873 | + super().remove_nodes_from(nodes) |
| 874 | + |
| 875 | + @mirror_to_nxcg |
| 876 | + def add_edge_override(self, u, v, **attr): |
| 877 | + super().add_edge(u, v, **attr) |
| 878 | + |
| 879 | + @mirror_to_nxcg |
| 880 | + def add_edges_from_override(self, ebunch_to_add, **attr): |
| 881 | + super().add_edges_from(ebunch_to_add, **attr) |
| 882 | + |
| 883 | + @mirror_to_nxcg |
| 884 | + def remove_edge_override(self, u, v): |
| 885 | + super().remove_edge(u, v) |
| 886 | + |
| 887 | + @mirror_to_nxcg |
| 888 | + def remove_edges_from_override(self, ebunch): |
| 889 | + super().remove_edges_from(ebunch) |
| 890 | + |
| 891 | + @mirror_to_nxcg |
| 892 | + def update_override(self, *args, **kwargs): |
| 893 | + super().update(*args, **kwargs) |
0 commit comments