exonware-xwnode 0.0.1.13__py3-none-any.whl → 0.0.1.15__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (213) hide show
  1. exonware/__init__.py +1 -1
  2. exonware/xwnode/__init__.py +1 -1
  3. exonware/xwnode/base.py +1 -1
  4. exonware/xwnode/common/__init__.py +20 -0
  5. exonware/xwnode/common/management/__init__.py +26 -0
  6. exonware/xwnode/{strategies → common/management}/manager.py +2 -2
  7. exonware/xwnode/common/monitoring/__init__.py +26 -0
  8. exonware/xwnode/{strategies → common/monitoring}/metrics.py +2 -2
  9. exonware/xwnode/{strategies → common/monitoring}/pattern_detector.py +2 -2
  10. exonware/xwnode/{strategies → common/monitoring}/performance_monitor.py +2 -2
  11. exonware/xwnode/common/patterns/__init__.py +26 -0
  12. exonware/xwnode/{strategies → common/patterns}/advisor.py +1 -1
  13. exonware/xwnode/{strategies → common/patterns}/flyweight.py +4 -4
  14. exonware/xwnode/{strategies → common/patterns}/registry.py +109 -112
  15. exonware/xwnode/common/utils/__init__.py +26 -0
  16. exonware/xwnode/{strategies/edges → edges/strategies}/__init__.py +1 -1
  17. exonware/xwnode/{strategies/edges → edges/strategies}/base.py +3 -3
  18. exonware/xwnode/facade.py +4 -3
  19. exonware/xwnode/{strategies/nodes → nodes/strategies}/__init__.py +1 -1
  20. exonware/xwnode/{strategies/nodes → nodes/strategies}/adjacency_list.py +7 -2
  21. exonware/xwnode/{strategies/nodes → nodes/strategies}/aho_corasick.py +6 -1
  22. exonware/xwnode/{strategies/nodes → nodes/strategies}/array_list.py +6 -1
  23. exonware/xwnode/{strategies/nodes → nodes/strategies}/base.py +24 -4
  24. exonware/xwnode/nodes/strategies/contracts.py +116 -0
  25. exonware/xwnode/{strategies/nodes → nodes/strategies}/deque.py +7 -2
  26. exonware/xwnode/{strategies/nodes → nodes/strategies}/hash_map.py +4 -0
  27. exonware/xwnode/{strategies/nodes → nodes/strategies}/heap.py +6 -1
  28. exonware/xwnode/{strategies/nodes → nodes/strategies}/linked_list.py +6 -1
  29. exonware/xwnode/{strategies/nodes → nodes/strategies}/node_aho_corasick.py +6 -1
  30. exonware/xwnode/{strategies/nodes → nodes/strategies}/node_array_list.py +4 -0
  31. exonware/xwnode/{strategies/nodes → nodes/strategies}/node_avl_tree.py +6 -1
  32. exonware/xwnode/{strategies/nodes → nodes/strategies}/node_b_plus_tree.py +6 -1
  33. exonware/xwnode/{strategies/nodes → nodes/strategies}/node_bitmap.py +6 -1
  34. exonware/xwnode/{strategies/nodes → nodes/strategies}/node_bitset_dynamic.py +6 -1
  35. exonware/xwnode/{strategies/nodes → nodes/strategies}/node_bloom_filter.py +4 -0
  36. exonware/xwnode/{strategies/nodes → nodes/strategies}/node_btree.py +6 -1
  37. exonware/xwnode/{strategies/nodes → nodes/strategies}/node_count_min_sketch.py +4 -0
  38. exonware/xwnode/{strategies/nodes → nodes/strategies}/node_cow_tree.py +6 -1
  39. exonware/xwnode/{strategies/nodes → nodes/strategies}/node_fenwick_tree.py +6 -1
  40. exonware/xwnode/{strategies/nodes → nodes/strategies}/node_hash_map.py +4 -0
  41. exonware/xwnode/{strategies/nodes → nodes/strategies}/node_heap.py +6 -1
  42. exonware/xwnode/{strategies/nodes → nodes/strategies}/node_hyperloglog.py +4 -0
  43. exonware/xwnode/{strategies/nodes → nodes/strategies}/node_linked_list.py +4 -0
  44. exonware/xwnode/{strategies/nodes → nodes/strategies}/node_lsm_tree.py +6 -1
  45. exonware/xwnode/{strategies/nodes → nodes/strategies}/node_ordered_map.py +6 -1
  46. exonware/xwnode/{strategies/nodes → nodes/strategies}/node_ordered_map_balanced.py +6 -1
  47. exonware/xwnode/{strategies/nodes → nodes/strategies}/node_patricia.py +6 -1
  48. exonware/xwnode/{strategies/nodes → nodes/strategies}/node_persistent_tree.py +6 -1
  49. exonware/xwnode/{strategies/nodes → nodes/strategies}/node_radix_trie.py +6 -1
  50. exonware/xwnode/{strategies/nodes → nodes/strategies}/node_red_black_tree.py +6 -1
  51. exonware/xwnode/{strategies/nodes → nodes/strategies}/node_roaring_bitmap.py +6 -1
  52. exonware/xwnode/{strategies/nodes → nodes/strategies}/node_segment_tree.py +6 -1
  53. exonware/xwnode/{strategies/nodes → nodes/strategies}/node_set_hash.py +4 -0
  54. exonware/xwnode/{strategies/nodes → nodes/strategies}/node_set_tree.py +6 -1
  55. exonware/xwnode/{strategies/nodes → nodes/strategies}/node_skip_list.py +6 -1
  56. exonware/xwnode/{strategies/nodes → nodes/strategies}/node_splay_tree.py +6 -1
  57. exonware/xwnode/{strategies/nodes → nodes/strategies}/node_suffix_array.py +6 -1
  58. exonware/xwnode/{strategies/nodes → nodes/strategies}/node_treap.py +6 -1
  59. exonware/xwnode/{strategies/nodes → nodes/strategies}/node_tree_graph_hybrid.py +4 -0
  60. exonware/xwnode/{strategies/nodes → nodes/strategies}/node_trie.py +6 -1
  61. exonware/xwnode/{strategies/nodes → nodes/strategies}/node_union_find.py +6 -1
  62. exonware/xwnode/{strategies/nodes → nodes/strategies}/node_xdata_optimized.py +4 -0
  63. exonware/xwnode/{strategies/nodes → nodes/strategies}/priority_queue.py +7 -2
  64. exonware/xwnode/{strategies/nodes → nodes/strategies}/queue.py +7 -2
  65. exonware/xwnode/{strategies/nodes → nodes/strategies}/sparse_matrix.py +7 -2
  66. exonware/xwnode/{strategies/nodes → nodes/strategies}/stack.py +7 -2
  67. exonware/xwnode/{strategies/nodes → nodes/strategies}/trie.py +6 -1
  68. exonware/xwnode/{strategies/nodes → nodes/strategies}/union_find.py +6 -1
  69. exonware/xwnode/queries/executors/__init__.py +47 -0
  70. exonware/xwnode/queries/executors/advanced/__init__.py +37 -0
  71. exonware/xwnode/queries/executors/advanced/aggregate_executor.py +50 -0
  72. exonware/xwnode/queries/executors/advanced/ask_executor.py +50 -0
  73. exonware/xwnode/queries/executors/advanced/construct_executor.py +50 -0
  74. exonware/xwnode/queries/executors/advanced/describe_executor.py +50 -0
  75. exonware/xwnode/queries/executors/advanced/for_loop_executor.py +50 -0
  76. exonware/xwnode/queries/executors/advanced/foreach_executor.py +50 -0
  77. exonware/xwnode/queries/executors/advanced/join_executor.py +50 -0
  78. exonware/xwnode/queries/executors/advanced/let_executor.py +50 -0
  79. exonware/xwnode/queries/executors/advanced/mutation_executor.py +50 -0
  80. exonware/xwnode/queries/executors/advanced/options_executor.py +50 -0
  81. exonware/xwnode/queries/executors/advanced/pipe_executor.py +50 -0
  82. exonware/xwnode/queries/executors/advanced/subscribe_executor.py +50 -0
  83. exonware/xwnode/queries/executors/advanced/subscription_executor.py +50 -0
  84. exonware/xwnode/queries/executors/advanced/union_executor.py +50 -0
  85. exonware/xwnode/queries/executors/advanced/window_executor.py +51 -0
  86. exonware/xwnode/queries/executors/advanced/with_cte_executor.py +50 -0
  87. exonware/xwnode/queries/executors/aggregation/__init__.py +21 -0
  88. exonware/xwnode/queries/executors/aggregation/avg_executor.py +50 -0
  89. exonware/xwnode/queries/executors/aggregation/count_executor.py +38 -0
  90. exonware/xwnode/queries/executors/aggregation/distinct_executor.py +50 -0
  91. exonware/xwnode/queries/executors/aggregation/group_executor.py +50 -0
  92. exonware/xwnode/queries/executors/aggregation/having_executor.py +50 -0
  93. exonware/xwnode/queries/executors/aggregation/max_executor.py +50 -0
  94. exonware/xwnode/queries/executors/aggregation/min_executor.py +50 -0
  95. exonware/xwnode/queries/executors/aggregation/sum_executor.py +50 -0
  96. exonware/xwnode/queries/executors/aggregation/summarize_executor.py +50 -0
  97. exonware/xwnode/queries/executors/array/__init__.py +9 -0
  98. exonware/xwnode/queries/executors/array/indexing_executor.py +51 -0
  99. exonware/xwnode/queries/executors/array/slicing_executor.py +51 -0
  100. exonware/xwnode/queries/executors/base.py +257 -0
  101. exonware/xwnode/queries/executors/capability_checker.py +204 -0
  102. exonware/xwnode/queries/executors/contracts.py +166 -0
  103. exonware/xwnode/queries/executors/core/__init__.py +17 -0
  104. exonware/xwnode/queries/executors/core/create_executor.py +96 -0
  105. exonware/xwnode/queries/executors/core/delete_executor.py +99 -0
  106. exonware/xwnode/queries/executors/core/drop_executor.py +100 -0
  107. exonware/xwnode/queries/executors/core/insert_executor.py +39 -0
  108. exonware/xwnode/queries/executors/core/select_executor.py +152 -0
  109. exonware/xwnode/queries/executors/core/update_executor.py +102 -0
  110. exonware/xwnode/queries/executors/data/__init__.py +13 -0
  111. exonware/xwnode/queries/executors/data/alter_executor.py +50 -0
  112. exonware/xwnode/queries/executors/data/load_executor.py +50 -0
  113. exonware/xwnode/queries/executors/data/merge_executor.py +50 -0
  114. exonware/xwnode/queries/executors/data/store_executor.py +50 -0
  115. exonware/xwnode/queries/executors/engine.py +221 -0
  116. exonware/xwnode/queries/executors/errors.py +68 -0
  117. exonware/xwnode/queries/executors/filtering/__init__.py +25 -0
  118. exonware/xwnode/queries/executors/filtering/between_executor.py +80 -0
  119. exonware/xwnode/queries/executors/filtering/filter_executor.py +79 -0
  120. exonware/xwnode/queries/executors/filtering/has_executor.py +70 -0
  121. exonware/xwnode/queries/executors/filtering/in_executor.py +70 -0
  122. exonware/xwnode/queries/executors/filtering/like_executor.py +76 -0
  123. exonware/xwnode/queries/executors/filtering/optional_executor.py +76 -0
  124. exonware/xwnode/queries/executors/filtering/range_executor.py +80 -0
  125. exonware/xwnode/queries/executors/filtering/term_executor.py +77 -0
  126. exonware/xwnode/queries/executors/filtering/values_executor.py +71 -0
  127. exonware/xwnode/queries/executors/filtering/where_executor.py +44 -0
  128. exonware/xwnode/queries/executors/graph/__init__.py +15 -0
  129. exonware/xwnode/queries/executors/graph/in_traverse_executor.py +51 -0
  130. exonware/xwnode/queries/executors/graph/match_executor.py +51 -0
  131. exonware/xwnode/queries/executors/graph/out_executor.py +51 -0
  132. exonware/xwnode/queries/executors/graph/path_executor.py +51 -0
  133. exonware/xwnode/queries/executors/graph/return_executor.py +51 -0
  134. exonware/xwnode/queries/executors/ordering/__init__.py +9 -0
  135. exonware/xwnode/queries/executors/ordering/by_executor.py +50 -0
  136. exonware/xwnode/queries/executors/ordering/order_executor.py +51 -0
  137. exonware/xwnode/queries/executors/projection/__init__.py +9 -0
  138. exonware/xwnode/queries/executors/projection/extend_executor.py +50 -0
  139. exonware/xwnode/queries/executors/projection/project_executor.py +50 -0
  140. exonware/xwnode/queries/executors/registry.py +173 -0
  141. exonware/xwnode/queries/executors/types.py +93 -0
  142. exonware/xwnode/queries/parsers/__init__.py +26 -0
  143. exonware/xwnode/queries/parsers/base.py +86 -0
  144. exonware/xwnode/queries/parsers/contracts.py +46 -0
  145. exonware/xwnode/queries/parsers/errors.py +53 -0
  146. exonware/xwnode/queries/parsers/sql_param_extractor.py +318 -0
  147. exonware/xwnode/{strategies/queries → queries/strategies}/__init__.py +1 -1
  148. exonware/xwnode/{strategies/queries → queries/strategies}/base.py +1 -1
  149. exonware/xwnode/{strategies/queries → queries/strategies}/cql.py +1 -1
  150. exonware/xwnode/{strategies/queries → queries/strategies}/cypher.py +1 -1
  151. exonware/xwnode/{strategies/queries → queries/strategies}/datalog.py +1 -1
  152. exonware/xwnode/{strategies/queries → queries/strategies}/elastic_dsl.py +1 -1
  153. exonware/xwnode/{strategies/queries → queries/strategies}/eql.py +1 -1
  154. exonware/xwnode/{strategies/queries → queries/strategies}/flux.py +1 -1
  155. exonware/xwnode/{strategies/queries → queries/strategies}/gql.py +1 -1
  156. exonware/xwnode/{strategies/queries → queries/strategies}/graphql.py +1 -1
  157. exonware/xwnode/{strategies/queries → queries/strategies}/gremlin.py +1 -1
  158. exonware/xwnode/{strategies/queries → queries/strategies}/hiveql.py +1 -1
  159. exonware/xwnode/{strategies/queries → queries/strategies}/hql.py +1 -1
  160. exonware/xwnode/{strategies/queries → queries/strategies}/jmespath.py +1 -1
  161. exonware/xwnode/{strategies/queries → queries/strategies}/jq.py +1 -1
  162. exonware/xwnode/{strategies/queries → queries/strategies}/json_query.py +1 -1
  163. exonware/xwnode/{strategies/queries → queries/strategies}/jsoniq.py +1 -1
  164. exonware/xwnode/{strategies/queries → queries/strategies}/kql.py +1 -1
  165. exonware/xwnode/{strategies/queries → queries/strategies}/linq.py +1 -1
  166. exonware/xwnode/{strategies/queries → queries/strategies}/logql.py +1 -1
  167. exonware/xwnode/{strategies/queries → queries/strategies}/mql.py +1 -1
  168. exonware/xwnode/{strategies/queries → queries/strategies}/n1ql.py +1 -1
  169. exonware/xwnode/{strategies/queries → queries/strategies}/partiql.py +1 -1
  170. exonware/xwnode/{strategies/queries → queries/strategies}/pig.py +1 -1
  171. exonware/xwnode/{strategies/queries → queries/strategies}/promql.py +1 -1
  172. exonware/xwnode/{strategies/queries → queries/strategies}/sparql.py +1 -1
  173. exonware/xwnode/{strategies/queries → queries/strategies}/sql.py +1 -1
  174. exonware/xwnode/{strategies/queries → queries/strategies}/xml_query.py +1 -1
  175. exonware/xwnode/{strategies/queries → queries/strategies}/xpath.py +1 -1
  176. exonware/xwnode/{strategies/queries → queries/strategies}/xquery.py +1 -1
  177. exonware/xwnode/{strategies/queries → queries/strategies}/xwnode_executor.py +1 -1
  178. exonware/xwnode/{strategies/queries → queries/strategies}/xwquery.py +43 -11
  179. exonware/xwnode/strategies/__init__.py +8 -8
  180. exonware/xwnode/version.py +3 -3
  181. {exonware_xwnode-0.0.1.13.dist-info → exonware_xwnode-0.0.1.15.dist-info}/METADATA +2 -3
  182. exonware_xwnode-0.0.1.15.dist-info/RECORD +214 -0
  183. exonware/xwnode/strategies/impls/__init__.py +0 -13
  184. exonware/xwnode/strategies/nodes/_base_node.py +0 -307
  185. exonware_xwnode-0.0.1.13.dist-info/RECORD +0 -132
  186. /exonware/xwnode/{strategies → common/management}/migration.py +0 -0
  187. /exonware/xwnode/{strategies → common/utils}/simple.py +0 -0
  188. /exonware/xwnode/{strategies → common/utils}/utils.py +0 -0
  189. /exonware/xwnode/{strategies/impls → edges/strategies}/_base_edge.py +0 -0
  190. /exonware/xwnode/{strategies/edges → edges/strategies}/adj_list.py +0 -0
  191. /exonware/xwnode/{strategies/edges → edges/strategies}/adj_matrix.py +0 -0
  192. /exonware/xwnode/{strategies/impls → edges/strategies}/edge_adj_list.py +0 -0
  193. /exonware/xwnode/{strategies/impls → edges/strategies}/edge_adj_matrix.py +0 -0
  194. /exonware/xwnode/{strategies/impls → edges/strategies}/edge_bidir_wrapper.py +0 -0
  195. /exonware/xwnode/{strategies/impls → edges/strategies}/edge_block_adj_matrix.py +0 -0
  196. /exonware/xwnode/{strategies/impls → edges/strategies}/edge_coo.py +0 -0
  197. /exonware/xwnode/{strategies/impls → edges/strategies}/edge_csc.py +0 -0
  198. /exonware/xwnode/{strategies/impls → edges/strategies}/edge_csr.py +0 -0
  199. /exonware/xwnode/{strategies/impls → edges/strategies}/edge_dynamic_adj_list.py +0 -0
  200. /exonware/xwnode/{strategies/impls → edges/strategies}/edge_flow_network.py +0 -0
  201. /exonware/xwnode/{strategies/impls → edges/strategies}/edge_hyperedge_set.py +0 -0
  202. /exonware/xwnode/{strategies/impls → edges/strategies}/edge_neural_graph.py +0 -0
  203. /exonware/xwnode/{strategies/impls → edges/strategies}/edge_octree.py +0 -0
  204. /exonware/xwnode/{strategies/impls → edges/strategies}/edge_property_store.py +0 -0
  205. /exonware/xwnode/{strategies/impls → edges/strategies}/edge_quadtree.py +0 -0
  206. /exonware/xwnode/{strategies/impls → edges/strategies}/edge_rtree.py +0 -0
  207. /exonware/xwnode/{strategies/impls → edges/strategies}/edge_temporal_edgeset.py +0 -0
  208. /exonware/xwnode/{strategies/impls → edges/strategies}/edge_tree_graph_basic.py +0 -0
  209. /exonware/xwnode/{strategies/impls → edges/strategies}/edge_weighted_graph.py +0 -0
  210. /exonware/xwnode/{strategies/impls → nodes/strategies}/_base_node.py +0 -0
  211. /exonware/xwnode/{strategies/nodes → nodes/strategies}/node_cuckoo_hash.py +0 -0
  212. {exonware_xwnode-0.0.1.13.dist-info → exonware_xwnode-0.0.1.15.dist-info}/WHEEL +0 -0
  213. {exonware_xwnode-0.0.1.13.dist-info → exonware_xwnode-0.0.1.15.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,257 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ #exonware/xwnode/src/exonware/xwnode/queries/executors/base.py
4
+
5
+ Operation Executor Base Classes
6
+
7
+ This module provides base classes for operation executors with capability checking.
8
+
9
+ Company: eXonware.com
10
+ Author: Eng. Muhammad AlShehri
11
+ Email: connect@exonware.com
12
+ Version: 0.0.1.15
13
+ Generation Date: 08-Oct-2025
14
+ """
15
+
16
+ import time
17
+ from abc import ABC, abstractmethod
18
+ from typing import Any, Dict, List, Optional
19
+
20
+ from .contracts import (
21
+ IOperationExecutor,
22
+ Action,
23
+ ExecutionContext,
24
+ ExecutionResult,
25
+ NodeType
26
+ )
27
+ from .types import OperationCapability
28
+ from .errors import UnsupportedOperationError # Reuse from root via errors.py
29
+ from ...errors import XWNodeValueError
30
+
31
+
32
+ class AOperationExecutor(IOperationExecutor):
33
+ """
34
+ Abstract base class for operation executors.
35
+
36
+ Provides common functionality including:
37
+ - Capability checking
38
+ - Performance monitoring
39
+ - Error handling
40
+ - Validation
41
+ """
42
+
43
+ # Operation name (must be set by subclasses)
44
+ OPERATION_NAME: str = "UNKNOWN"
45
+
46
+ # Supported node types (empty = all types)
47
+ SUPPORTED_NODE_TYPES: List[NodeType] = []
48
+
49
+ # Required capabilities
50
+ REQUIRED_CAPABILITIES: OperationCapability = OperationCapability.NONE
51
+
52
+ def __init__(self):
53
+ """Initialize operation executor."""
54
+ self._execution_count = 0
55
+ self._total_time = 0.0
56
+ self._error_count = 0
57
+
58
+ def execute(self, action: Action, context: ExecutionContext) -> ExecutionResult:
59
+ """
60
+ Execute operation with monitoring and error handling.
61
+
62
+ This method implements the Template Method pattern:
63
+ 1. Validate
64
+ 2. Check capability
65
+ 3. Execute (delegated to subclass)
66
+ 4. Monitor performance
67
+ """
68
+ start_time = time.time()
69
+
70
+ try:
71
+ # Validate action
72
+ if not self.validate(action, context):
73
+ raise XWNodeValueError(f"Invalid action: {action.type}")
74
+
75
+ # Check capability
76
+ self.validate_capability_or_raise(context)
77
+
78
+ # Execute (delegated to subclass)
79
+ result = self._do_execute(action, context)
80
+
81
+ # Update metrics
82
+ execution_time = time.time() - start_time
83
+ self._execution_count += 1
84
+ self._total_time += execution_time
85
+ result.execution_time = execution_time
86
+
87
+ return result
88
+
89
+ except Exception as e:
90
+ self._error_count += 1
91
+ execution_time = time.time() - start_time
92
+
93
+ return ExecutionResult(
94
+ data=None,
95
+ success=False,
96
+ error=str(e),
97
+ execution_time=execution_time
98
+ )
99
+
100
+ @abstractmethod
101
+ def _do_execute(self, action: Action, context: ExecutionContext) -> ExecutionResult:
102
+ """
103
+ Execute the actual operation (implemented by subclasses).
104
+
105
+ Args:
106
+ action: The action to execute
107
+ context: Execution context
108
+
109
+ Returns:
110
+ ExecutionResult with data
111
+ """
112
+ pass
113
+
114
+ def validate(self, action: Action, context: ExecutionContext) -> bool:
115
+ """
116
+ Validate action before execution.
117
+
118
+ Default implementation checks basic requirements.
119
+ Subclasses can override for specific validation.
120
+ """
121
+ if not action or not action.type:
122
+ return False
123
+ if not context or not context.node:
124
+ return False
125
+ return True
126
+
127
+ def can_execute_on(self, node_type: NodeType) -> bool:
128
+ """
129
+ Check if this executor can operate on the given node type.
130
+
131
+ Args:
132
+ node_type: The node type to check
133
+
134
+ Returns:
135
+ True if this executor supports the node type
136
+ """
137
+ # Empty list means supports all types (universal operation)
138
+ if not self.SUPPORTED_NODE_TYPES:
139
+ return True
140
+ return node_type in self.SUPPORTED_NODE_TYPES
141
+
142
+ def validate_capability_or_raise(self, context: ExecutionContext) -> None:
143
+ """
144
+ Validate operation can execute on node, raise if not.
145
+
146
+ Args:
147
+ context: Execution context
148
+
149
+ Raises:
150
+ UnsupportedOperationError: If operation cannot execute on node type
151
+ """
152
+ # Get node's strategy type
153
+ if hasattr(context.node, '_strategy') and hasattr(context.node._strategy, 'STRATEGY_TYPE'):
154
+ node_type = context.node._strategy.STRATEGY_TYPE
155
+ elif hasattr(context.node, 'STRATEGY_TYPE'):
156
+ node_type = context.node.STRATEGY_TYPE
157
+ else:
158
+ # Default to TREE for backward compatibility
159
+ node_type = NodeType.TREE
160
+
161
+ # Check if operation can execute on this node type
162
+ if not self.can_execute_on(node_type):
163
+ supported = [nt.name for nt in self.SUPPORTED_NODE_TYPES]
164
+ raise UnsupportedOperationError(
165
+ self.OPERATION_NAME,
166
+ node_type,
167
+ f"Requires one of: {supported}"
168
+ )
169
+
170
+ def estimate_cost(self, action: Action, context: ExecutionContext) -> int:
171
+ """
172
+ Estimate execution cost.
173
+
174
+ Default implementation returns fixed cost.
175
+ Subclasses can override for more accurate estimates.
176
+ """
177
+ return 100
178
+
179
+ def get_stats(self) -> Dict[str, Any]:
180
+ """Get execution statistics for this executor."""
181
+ avg_time = self._total_time / self._execution_count if self._execution_count > 0 else 0
182
+
183
+ return {
184
+ 'operation': self.OPERATION_NAME,
185
+ 'execution_count': self._execution_count,
186
+ 'total_time': self._total_time,
187
+ 'average_time': avg_time,
188
+ 'error_count': self._error_count,
189
+ 'success_rate': (self._execution_count - self._error_count) / self._execution_count if self._execution_count > 0 else 1.0
190
+ }
191
+
192
+
193
+ class AUniversalOperationExecutor(AOperationExecutor):
194
+ """
195
+ Base class for universal operations that work on all node types.
196
+
197
+ Universal operations:
198
+ - SELECT, INSERT, UPDATE, DELETE
199
+ - WHERE, FILTER
200
+ - GROUP BY, COUNT, SUM, AVG
201
+ - PROJECT, EXTEND
202
+ """
203
+
204
+ # Universal operations support all node types (empty list)
205
+ SUPPORTED_NODE_TYPES: List[NodeType] = []
206
+
207
+
208
+ class ATreeOperationExecutor(AOperationExecutor):
209
+ """
210
+ Base class for tree-specific operations.
211
+
212
+ Tree operations:
213
+ - BETWEEN, RANGE
214
+ - ORDER BY
215
+ - MIN, MAX (optimal on trees)
216
+ """
217
+
218
+ # Only works on tree nodes
219
+ SUPPORTED_NODE_TYPES: List[NodeType] = [NodeType.TREE]
220
+ REQUIRED_CAPABILITIES: OperationCapability = OperationCapability.REQUIRES_ORDERED
221
+
222
+
223
+ class AGraphOperationExecutor(AOperationExecutor):
224
+ """
225
+ Base class for graph-specific operations.
226
+
227
+ Graph operations:
228
+ - MATCH, PATH
229
+ - OUT, IN_TRAVERSE
230
+ - Graph traversal
231
+ """
232
+
233
+ # Only works on graph nodes
234
+ SUPPORTED_NODE_TYPES: List[NodeType] = [NodeType.GRAPH, NodeType.TREE] # Trees can act as graphs
235
+
236
+
237
+ class ALinearOperationExecutor(AOperationExecutor):
238
+ """
239
+ Base class for linear-specific operations.
240
+
241
+ Linear operations:
242
+ - SLICING, INDEXING
243
+ - Sequential operations
244
+ """
245
+
246
+ # Only works on linear and matrix nodes
247
+ SUPPORTED_NODE_TYPES: List[NodeType] = [NodeType.LINEAR, NodeType.MATRIX]
248
+
249
+
250
+ __all__ = [
251
+ 'AOperationExecutor',
252
+ 'AUniversalOperationExecutor',
253
+ 'ATreeOperationExecutor',
254
+ 'AGraphOperationExecutor',
255
+ 'ALinearOperationExecutor',
256
+ 'UnsupportedOperationError',
257
+ ]
@@ -0,0 +1,204 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ #exonware/xwnode/src/exonware/xwnode/queries/executors/capability_checker.py
4
+
5
+ Operation Capability Checker
6
+
7
+ This module provides capability checking for operations on different node types.
8
+
9
+ Company: eXonware.com
10
+ Author: Eng. Muhammad AlShehri
11
+ Email: connect@exonware.com
12
+ Version: 0.0.1.15
13
+ Generation Date: 08-Oct-2025
14
+ """
15
+
16
+ from typing import Dict, List, Set
17
+
18
+ # Import NodeType from nodes module per DEV_GUIDELINES
19
+ from ...nodes.strategies.contracts import NodeType
20
+
21
+
22
+ # Operation-to-NodeType Compatibility Matrix
23
+ OPERATION_COMPATIBILITY = {
24
+ # Core CRUD Operations (Universal)
25
+ 'SELECT': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
26
+ 'INSERT': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
27
+ 'UPDATE': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
28
+ 'DELETE': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
29
+ 'CREATE': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
30
+ 'DROP': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
31
+
32
+ # Filtering Operations (Universal)
33
+ 'WHERE': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
34
+ 'FILTER': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
35
+ 'LIKE': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
36
+ 'IN': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
37
+ 'HAS': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
38
+
39
+ # Range Operations (Tree/Matrix)
40
+ 'BETWEEN': {NodeType.TREE, NodeType.MATRIX},
41
+ 'RANGE': {NodeType.TREE, NodeType.MATRIX},
42
+
43
+ # Aggregation Operations (Universal)
44
+ 'GROUP': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
45
+ 'BY': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
46
+ 'HAVING': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
47
+ 'SUMMARIZE': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
48
+ 'SUM': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
49
+ 'COUNT': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
50
+ 'AVG': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
51
+ 'MIN': {NodeType.LINEAR, NodeType.TREE, NodeType.MATRIX}, # Optimal on trees
52
+ 'MAX': {NodeType.LINEAR, NodeType.TREE, NodeType.MATRIX}, # Optimal on trees
53
+ 'DISTINCT': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
54
+
55
+ # Ordering Operations (Tree/Linear)
56
+ 'ORDER': {NodeType.TREE, NodeType.LINEAR},
57
+
58
+ # Join Operations (Universal conceptually)
59
+ 'JOIN': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
60
+ 'UNION': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
61
+ 'WITH': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
62
+ 'OPTIONAL': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
63
+
64
+ # Graph Operations
65
+ 'MATCH': {NodeType.GRAPH, NodeType.TREE, NodeType.HYBRID},
66
+ 'PATH': {NodeType.GRAPH, NodeType.TREE, NodeType.HYBRID},
67
+ 'OUT': {NodeType.GRAPH, NodeType.TREE, NodeType.HYBRID},
68
+ 'IN_TRAVERSE': {NodeType.GRAPH, NodeType.TREE, NodeType.HYBRID},
69
+ 'RETURN': {NodeType.GRAPH, NodeType.TREE, NodeType.HYBRID},
70
+
71
+ # Projection Operations (Universal)
72
+ 'PROJECT': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
73
+ 'EXTEND': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
74
+
75
+ # Array Operations (Linear/Matrix)
76
+ 'SLICING': {NodeType.LINEAR, NodeType.MATRIX},
77
+ 'INDEXING': {NodeType.LINEAR, NodeType.MATRIX, NodeType.TREE},
78
+
79
+ # Search Operations (Universal)
80
+ 'TERM': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
81
+
82
+ # Data Operations (Universal)
83
+ 'LOAD': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
84
+ 'STORE': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
85
+ 'MERGE': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
86
+ 'ALTER': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
87
+
88
+ # Control Flow Operations (Universal)
89
+ 'FOREACH': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
90
+ 'LET': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
91
+ 'FOR': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
92
+
93
+ # Window Operations (Time-series, works on linear/tree)
94
+ 'WINDOW': {NodeType.LINEAR, NodeType.TREE},
95
+ 'AGGREGATE': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
96
+
97
+ # Metadata Operations (Universal)
98
+ 'DESCRIBE': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
99
+ 'CONSTRUCT': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
100
+ 'ASK': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
101
+
102
+ # Advanced Operations (Universal)
103
+ 'SUBSCRIBE': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
104
+ 'SUBSCRIPTION': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
105
+ 'MUTATION': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
106
+ 'PIPE': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
107
+ 'OPTIONS': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
108
+ 'VALUES': {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID},
109
+ }
110
+
111
+
112
+ def check_operation_compatibility(operation: str, node_type: NodeType) -> bool:
113
+ """
114
+ Check if an operation is compatible with a node type.
115
+
116
+ Args:
117
+ operation: Operation name (e.g., "SELECT")
118
+ node_type: Node type to check
119
+
120
+ Returns:
121
+ True if operation is compatible with node type
122
+ """
123
+ operation = operation.upper()
124
+
125
+ # Check compatibility matrix
126
+ if operation in OPERATION_COMPATIBILITY:
127
+ return node_type in OPERATION_COMPATIBILITY[operation]
128
+
129
+ # Unknown operation - assume universal (backward compatibility)
130
+ return True
131
+
132
+
133
+ def get_supported_operations(node_type: NodeType) -> List[str]:
134
+ """
135
+ Get list of operations supported by a node type.
136
+
137
+ Args:
138
+ node_type: Node type to check
139
+
140
+ Returns:
141
+ List of supported operation names
142
+ """
143
+ supported = []
144
+
145
+ for operation, compatible_types in OPERATION_COMPATIBILITY.items():
146
+ if node_type in compatible_types:
147
+ supported.append(operation)
148
+
149
+ return supported
150
+
151
+
152
+ def get_universal_operations() -> List[str]:
153
+ """
154
+ Get list of universal operations (work on all node types).
155
+
156
+ Returns:
157
+ List of universal operation names
158
+ """
159
+ universal = []
160
+ all_types = {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID}
161
+
162
+ for operation, compatible_types in OPERATION_COMPATIBILITY.items():
163
+ if compatible_types == all_types:
164
+ universal.append(operation)
165
+
166
+ return universal
167
+
168
+
169
+ def get_type_specific_operations(node_type: NodeType) -> List[str]:
170
+ """
171
+ Get operations that are specific to (or optimal for) a node type.
172
+
173
+ Args:
174
+ node_type: Node type to check
175
+
176
+ Returns:
177
+ List of type-specific operation names
178
+ """
179
+ specific = []
180
+ all_types = {NodeType.LINEAR, NodeType.TREE, NodeType.GRAPH, NodeType.MATRIX, NodeType.HYBRID}
181
+
182
+ for operation, compatible_types in OPERATION_COMPATIBILITY.items():
183
+ # If node type supports it but not all types support it
184
+ if node_type in compatible_types and compatible_types != all_types:
185
+ specific.append(operation)
186
+
187
+ return specific
188
+
189
+
190
+ # Global registry accessor
191
+ def get_global_registry() -> OperationRegistry:
192
+ """Get the global operation registry instance."""
193
+ return OperationRegistry()
194
+
195
+
196
+ __all__ = [
197
+ 'OperationRegistry',
198
+ 'get_operation_registry',
199
+ 'check_operation_compatibility',
200
+ 'get_supported_operations',
201
+ 'get_universal_operations',
202
+ 'get_type_specific_operations',
203
+ 'OPERATION_COMPATIBILITY',
204
+ ]
@@ -0,0 +1,166 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ #exonware/xwnode/src/exonware/xwnode/queries/executors/contracts.py
4
+
5
+ Operation Executor Contracts
6
+
7
+ This module defines the interfaces and data structures for query operation execution.
8
+
9
+ Company: eXonware.com
10
+ Author: Eng. Muhammad AlShehri
11
+ Email: connect@exonware.com
12
+ Version: 0.0.1.15
13
+ Generation Date: 08-Oct-2025
14
+ """
15
+
16
+ from abc import ABC, abstractmethod
17
+ from typing import Any, Dict, List, Optional
18
+ from dataclasses import dataclass, field
19
+
20
+ # Import shared types per DEV_GUIDELINES.md
21
+ from ...nodes.strategies.contracts import NodeType
22
+ from .types import OperationCapability
23
+
24
+
25
+ @dataclass
26
+ class Action:
27
+ """
28
+ Represents a single query action to be executed.
29
+
30
+ Actions are parsed from XWQuery Script and contain all information
31
+ needed to execute a specific operation.
32
+ """
33
+ type: str # e.g., "SELECT", "INSERT", "WHERE"
34
+ params: Dict[str, Any] # Operation parameters
35
+ id: str = "" # Unique action ID
36
+ line_number: int = 0 # Source line number
37
+ children: List['Action'] = field(default_factory=list) # Nested actions
38
+ metadata: Dict[str, Any] = field(default_factory=dict) # Additional metadata
39
+
40
+
41
+ @dataclass
42
+ class ExecutionContext:
43
+ """
44
+ Execution context for operation execution.
45
+
46
+ Contains all state needed during execution including the target node,
47
+ variables, transaction state, and configuration.
48
+ """
49
+ node: Any # Target XWNode to execute on
50
+ variables: Dict[str, Any] = field(default_factory=dict) # Query variables
51
+ transaction: Optional[Any] = None # Transaction object (if in transaction)
52
+ cache: Optional[Dict[str, Any]] = None # Result cache
53
+ parent_results: Dict[str, Any] = field(default_factory=dict) # Results from parent actions
54
+ options: Dict[str, Any] = field(default_factory=dict) # Execution options
55
+
56
+ def set_result(self, action_id: str, result: Any) -> None:
57
+ """Store result for later use by other actions."""
58
+ self.parent_results[action_id] = result
59
+
60
+ def get_result(self, action_id: str) -> Optional[Any]:
61
+ """Get result from previous action."""
62
+ return self.parent_results.get(action_id)
63
+
64
+
65
+ @dataclass
66
+ class ExecutionResult:
67
+ """
68
+ Result of operation execution.
69
+
70
+ Contains the data returned by the operation along with metadata
71
+ about the execution.
72
+ """
73
+ data: Any # Result data
74
+ affected_count: int = 0 # Number of items affected
75
+ execution_time: float = 0.0 # Execution time in seconds
76
+ metadata: Dict[str, Any] = field(default_factory=dict) # Additional metadata
77
+ success: bool = True # Whether execution succeeded
78
+ error: Optional[str] = None # Error message if failed
79
+
80
+
81
+ class IOperationExecutor(ABC):
82
+ """
83
+ Interface for operation executors.
84
+
85
+ All operation executors must implement this interface to be compatible
86
+ with the execution engine.
87
+ """
88
+
89
+ # Operation name (e.g., "SELECT", "INSERT")
90
+ OPERATION_NAME: str = ""
91
+
92
+ # Supported node types (empty = all types)
93
+ SUPPORTED_NODE_TYPES: List[NodeType] = []
94
+
95
+ # Required capabilities
96
+ REQUIRED_CAPABILITIES: OperationCapability = OperationCapability.NONE
97
+
98
+ @abstractmethod
99
+ def execute(self, action: Action, context: ExecutionContext) -> ExecutionResult:
100
+ """
101
+ Execute the operation.
102
+
103
+ Args:
104
+ action: The action to execute
105
+ context: Execution context with node and state
106
+
107
+ Returns:
108
+ ExecutionResult with data and metadata
109
+
110
+ Raises:
111
+ UnsupportedOperationError: If operation cannot execute on node type
112
+ ExecutionError: If execution fails
113
+ """
114
+ pass
115
+
116
+ @abstractmethod
117
+ def validate(self, action: Action, context: ExecutionContext) -> bool:
118
+ """
119
+ Validate that the action can be executed.
120
+
121
+ Args:
122
+ action: The action to validate
123
+ context: Execution context
124
+
125
+ Returns:
126
+ True if action is valid and can be executed
127
+ """
128
+ pass
129
+
130
+ def can_execute_on(self, node_type: NodeType) -> bool:
131
+ """
132
+ Check if this executor can operate on the given node type.
133
+
134
+ Args:
135
+ node_type: The node type to check
136
+
137
+ Returns:
138
+ True if this executor supports the node type
139
+ """
140
+ # Empty list means supports all types
141
+ if not self.SUPPORTED_NODE_TYPES:
142
+ return True
143
+ return node_type in self.SUPPORTED_NODE_TYPES
144
+
145
+ def estimate_cost(self, action: Action, context: ExecutionContext) -> int:
146
+ """
147
+ Estimate execution cost (optional).
148
+
149
+ Args:
150
+ action: The action to estimate
151
+ context: Execution context
152
+
153
+ Returns:
154
+ Estimated cost (arbitrary units)
155
+ """
156
+ return 100 # Default cost
157
+
158
+
159
+ __all__ = [
160
+ 'IOperationExecutor',
161
+ 'Action',
162
+ 'ExecutionContext',
163
+ 'ExecutionResult',
164
+ 'OperationCapability',
165
+ 'NodeType',
166
+ ]
@@ -0,0 +1,17 @@
1
+ """Core CRUD operation executors."""
2
+
3
+ from .select_executor import SelectExecutor
4
+ from .insert_executor import InsertExecutor
5
+ from .update_executor import UpdateExecutor
6
+ from .delete_executor import DeleteExecutor
7
+ from .create_executor import CreateExecutor
8
+ from .drop_executor import DropExecutor
9
+
10
+ __all__ = [
11
+ 'SelectExecutor',
12
+ 'InsertExecutor',
13
+ 'UpdateExecutor',
14
+ 'DeleteExecutor',
15
+ 'CreateExecutor',
16
+ 'DropExecutor',
17
+ ]