exonware-xwnode 0.0.1.12__py3-none-any.whl → 0.0.1.14__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.
- exonware/__init__.py +1 -1
- exonware/xwnode/__init__.py +1 -1
- exonware/xwnode/base.py +1 -1
- exonware/xwnode/common/__init__.py +20 -0
- exonware/xwnode/common/management/__init__.py +26 -0
- exonware/xwnode/{strategies → common/management}/manager.py +2 -2
- exonware/xwnode/common/monitoring/__init__.py +26 -0
- exonware/xwnode/{strategies → common/monitoring}/metrics.py +2 -2
- exonware/xwnode/{strategies → common/monitoring}/pattern_detector.py +2 -2
- exonware/xwnode/{strategies → common/monitoring}/performance_monitor.py +2 -2
- exonware/xwnode/common/patterns/__init__.py +26 -0
- exonware/xwnode/{strategies → common/patterns}/advisor.py +1 -1
- exonware/xwnode/{strategies → common/patterns}/flyweight.py +4 -4
- exonware/xwnode/{strategies → common/patterns}/registry.py +109 -112
- exonware/xwnode/common/utils/__init__.py +26 -0
- exonware/xwnode/{strategies/edges → edges/strategies}/__init__.py +1 -1
- exonware/xwnode/{strategies/edges → edges/strategies}/base.py +3 -3
- exonware/xwnode/facade.py +4 -3
- exonware/xwnode/{strategies/nodes → nodes/strategies}/__init__.py +1 -1
- exonware/xwnode/{strategies/nodes → nodes/strategies}/adjacency_list.py +7 -2
- exonware/xwnode/{strategies/nodes → nodes/strategies}/aho_corasick.py +6 -1
- exonware/xwnode/{strategies/nodes → nodes/strategies}/array_list.py +6 -1
- exonware/xwnode/{strategies/nodes → nodes/strategies}/base.py +24 -4
- exonware/xwnode/nodes/strategies/contracts.py +116 -0
- exonware/xwnode/{strategies/nodes → nodes/strategies}/deque.py +7 -2
- exonware/xwnode/{strategies/nodes → nodes/strategies}/hash_map.py +4 -0
- exonware/xwnode/{strategies/nodes → nodes/strategies}/heap.py +6 -1
- exonware/xwnode/{strategies/nodes → nodes/strategies}/linked_list.py +6 -1
- exonware/xwnode/{strategies/nodes → nodes/strategies}/node_aho_corasick.py +6 -1
- exonware/xwnode/{strategies/nodes → nodes/strategies}/node_array_list.py +4 -0
- exonware/xwnode/{strategies/nodes → nodes/strategies}/node_avl_tree.py +6 -1
- exonware/xwnode/{strategies/nodes → nodes/strategies}/node_b_plus_tree.py +6 -1
- exonware/xwnode/{strategies/nodes → nodes/strategies}/node_bitmap.py +6 -1
- exonware/xwnode/{strategies/nodes → nodes/strategies}/node_bitset_dynamic.py +6 -1
- exonware/xwnode/{strategies/nodes → nodes/strategies}/node_bloom_filter.py +4 -0
- exonware/xwnode/{strategies/nodes → nodes/strategies}/node_btree.py +6 -1
- exonware/xwnode/{strategies/nodes → nodes/strategies}/node_count_min_sketch.py +4 -0
- exonware/xwnode/{strategies/nodes → nodes/strategies}/node_cow_tree.py +6 -1
- exonware/xwnode/{strategies/nodes → nodes/strategies}/node_fenwick_tree.py +6 -1
- exonware/xwnode/{strategies/nodes → nodes/strategies}/node_hash_map.py +4 -0
- exonware/xwnode/{strategies/nodes → nodes/strategies}/node_heap.py +6 -1
- exonware/xwnode/{strategies/nodes → nodes/strategies}/node_hyperloglog.py +4 -0
- exonware/xwnode/{strategies/nodes → nodes/strategies}/node_linked_list.py +4 -0
- exonware/xwnode/{strategies/nodes → nodes/strategies}/node_lsm_tree.py +6 -1
- exonware/xwnode/{strategies/nodes → nodes/strategies}/node_ordered_map.py +6 -1
- exonware/xwnode/{strategies/nodes → nodes/strategies}/node_ordered_map_balanced.py +6 -1
- exonware/xwnode/{strategies/nodes → nodes/strategies}/node_patricia.py +6 -1
- exonware/xwnode/{strategies/nodes → nodes/strategies}/node_persistent_tree.py +6 -1
- exonware/xwnode/{strategies/nodes → nodes/strategies}/node_radix_trie.py +6 -1
- exonware/xwnode/{strategies/nodes → nodes/strategies}/node_red_black_tree.py +6 -1
- exonware/xwnode/{strategies/nodes → nodes/strategies}/node_roaring_bitmap.py +6 -1
- exonware/xwnode/{strategies/nodes → nodes/strategies}/node_segment_tree.py +6 -1
- exonware/xwnode/{strategies/nodes → nodes/strategies}/node_set_hash.py +4 -0
- exonware/xwnode/{strategies/nodes → nodes/strategies}/node_set_tree.py +6 -1
- exonware/xwnode/{strategies/nodes → nodes/strategies}/node_skip_list.py +6 -1
- exonware/xwnode/{strategies/nodes → nodes/strategies}/node_splay_tree.py +6 -1
- exonware/xwnode/{strategies/nodes → nodes/strategies}/node_suffix_array.py +6 -1
- exonware/xwnode/{strategies/nodes → nodes/strategies}/node_treap.py +6 -1
- exonware/xwnode/{strategies/nodes → nodes/strategies}/node_tree_graph_hybrid.py +4 -0
- exonware/xwnode/{strategies/nodes → nodes/strategies}/node_trie.py +6 -1
- exonware/xwnode/{strategies/nodes → nodes/strategies}/node_union_find.py +6 -1
- exonware/xwnode/{strategies/nodes → nodes/strategies}/node_xdata_optimized.py +4 -0
- exonware/xwnode/{strategies/nodes → nodes/strategies}/priority_queue.py +7 -2
- exonware/xwnode/{strategies/nodes → nodes/strategies}/queue.py +7 -2
- exonware/xwnode/{strategies/nodes → nodes/strategies}/sparse_matrix.py +7 -2
- exonware/xwnode/{strategies/nodes → nodes/strategies}/stack.py +7 -2
- exonware/xwnode/{strategies/nodes → nodes/strategies}/trie.py +6 -1
- exonware/xwnode/{strategies/nodes → nodes/strategies}/union_find.py +6 -1
- exonware/xwnode/queries/executors/__init__.py +47 -0
- exonware/xwnode/queries/executors/advanced/__init__.py +37 -0
- exonware/xwnode/queries/executors/advanced/aggregate_executor.py +50 -0
- exonware/xwnode/queries/executors/advanced/ask_executor.py +50 -0
- exonware/xwnode/queries/executors/advanced/construct_executor.py +50 -0
- exonware/xwnode/queries/executors/advanced/describe_executor.py +50 -0
- exonware/xwnode/queries/executors/advanced/for_loop_executor.py +50 -0
- exonware/xwnode/queries/executors/advanced/foreach_executor.py +50 -0
- exonware/xwnode/queries/executors/advanced/join_executor.py +50 -0
- exonware/xwnode/queries/executors/advanced/let_executor.py +50 -0
- exonware/xwnode/queries/executors/advanced/mutation_executor.py +50 -0
- exonware/xwnode/queries/executors/advanced/options_executor.py +50 -0
- exonware/xwnode/queries/executors/advanced/pipe_executor.py +50 -0
- exonware/xwnode/queries/executors/advanced/subscribe_executor.py +50 -0
- exonware/xwnode/queries/executors/advanced/subscription_executor.py +50 -0
- exonware/xwnode/queries/executors/advanced/union_executor.py +50 -0
- exonware/xwnode/queries/executors/advanced/window_executor.py +51 -0
- exonware/xwnode/queries/executors/advanced/with_cte_executor.py +50 -0
- exonware/xwnode/queries/executors/aggregation/__init__.py +21 -0
- exonware/xwnode/queries/executors/aggregation/avg_executor.py +50 -0
- exonware/xwnode/queries/executors/aggregation/count_executor.py +38 -0
- exonware/xwnode/queries/executors/aggregation/distinct_executor.py +50 -0
- exonware/xwnode/queries/executors/aggregation/group_executor.py +50 -0
- exonware/xwnode/queries/executors/aggregation/having_executor.py +50 -0
- exonware/xwnode/queries/executors/aggregation/max_executor.py +50 -0
- exonware/xwnode/queries/executors/aggregation/min_executor.py +50 -0
- exonware/xwnode/queries/executors/aggregation/sum_executor.py +50 -0
- exonware/xwnode/queries/executors/aggregation/summarize_executor.py +50 -0
- exonware/xwnode/queries/executors/array/__init__.py +9 -0
- exonware/xwnode/queries/executors/array/indexing_executor.py +51 -0
- exonware/xwnode/queries/executors/array/slicing_executor.py +51 -0
- exonware/xwnode/queries/executors/base.py +257 -0
- exonware/xwnode/queries/executors/capability_checker.py +204 -0
- exonware/xwnode/queries/executors/contracts.py +166 -0
- exonware/xwnode/queries/executors/core/__init__.py +17 -0
- exonware/xwnode/queries/executors/core/create_executor.py +96 -0
- exonware/xwnode/queries/executors/core/delete_executor.py +99 -0
- exonware/xwnode/queries/executors/core/drop_executor.py +100 -0
- exonware/xwnode/queries/executors/core/insert_executor.py +39 -0
- exonware/xwnode/queries/executors/core/select_executor.py +152 -0
- exonware/xwnode/queries/executors/core/update_executor.py +102 -0
- exonware/xwnode/queries/executors/data/__init__.py +13 -0
- exonware/xwnode/queries/executors/data/alter_executor.py +50 -0
- exonware/xwnode/queries/executors/data/load_executor.py +50 -0
- exonware/xwnode/queries/executors/data/merge_executor.py +50 -0
- exonware/xwnode/queries/executors/data/store_executor.py +50 -0
- exonware/xwnode/queries/executors/engine.py +221 -0
- exonware/xwnode/queries/executors/errors.py +68 -0
- exonware/xwnode/queries/executors/filtering/__init__.py +25 -0
- exonware/xwnode/queries/executors/filtering/between_executor.py +80 -0
- exonware/xwnode/queries/executors/filtering/filter_executor.py +79 -0
- exonware/xwnode/queries/executors/filtering/has_executor.py +70 -0
- exonware/xwnode/queries/executors/filtering/in_executor.py +70 -0
- exonware/xwnode/queries/executors/filtering/like_executor.py +76 -0
- exonware/xwnode/queries/executors/filtering/optional_executor.py +76 -0
- exonware/xwnode/queries/executors/filtering/range_executor.py +80 -0
- exonware/xwnode/queries/executors/filtering/term_executor.py +77 -0
- exonware/xwnode/queries/executors/filtering/values_executor.py +71 -0
- exonware/xwnode/queries/executors/filtering/where_executor.py +44 -0
- exonware/xwnode/queries/executors/graph/__init__.py +15 -0
- exonware/xwnode/queries/executors/graph/in_traverse_executor.py +51 -0
- exonware/xwnode/queries/executors/graph/match_executor.py +51 -0
- exonware/xwnode/queries/executors/graph/out_executor.py +51 -0
- exonware/xwnode/queries/executors/graph/path_executor.py +51 -0
- exonware/xwnode/queries/executors/graph/return_executor.py +51 -0
- exonware/xwnode/queries/executors/ordering/__init__.py +9 -0
- exonware/xwnode/queries/executors/ordering/by_executor.py +50 -0
- exonware/xwnode/queries/executors/ordering/order_executor.py +51 -0
- exonware/xwnode/queries/executors/projection/__init__.py +9 -0
- exonware/xwnode/queries/executors/projection/extend_executor.py +50 -0
- exonware/xwnode/queries/executors/projection/project_executor.py +50 -0
- exonware/xwnode/queries/executors/registry.py +173 -0
- exonware/xwnode/queries/executors/types.py +93 -0
- exonware/xwnode/{strategies/queries → queries/strategies}/__init__.py +1 -1
- exonware/xwnode/{strategies/queries → queries/strategies}/base.py +1 -1
- exonware/xwnode/{strategies/queries → queries/strategies}/cql.py +1 -1
- exonware/xwnode/{strategies/queries → queries/strategies}/cypher.py +1 -1
- exonware/xwnode/{strategies/queries → queries/strategies}/datalog.py +1 -1
- exonware/xwnode/{strategies/queries → queries/strategies}/elastic_dsl.py +1 -1
- exonware/xwnode/{strategies/queries → queries/strategies}/eql.py +1 -1
- exonware/xwnode/{strategies/queries → queries/strategies}/flux.py +1 -1
- exonware/xwnode/{strategies/queries → queries/strategies}/gql.py +1 -1
- exonware/xwnode/{strategies/queries → queries/strategies}/graphql.py +1 -1
- exonware/xwnode/{strategies/queries → queries/strategies}/gremlin.py +1 -1
- exonware/xwnode/{strategies/queries → queries/strategies}/hiveql.py +1 -1
- exonware/xwnode/{strategies/queries → queries/strategies}/hql.py +1 -1
- exonware/xwnode/{strategies/queries → queries/strategies}/jmespath.py +1 -1
- exonware/xwnode/{strategies/queries → queries/strategies}/jq.py +1 -1
- exonware/xwnode/{strategies/queries → queries/strategies}/json_query.py +1 -1
- exonware/xwnode/{strategies/queries → queries/strategies}/jsoniq.py +1 -1
- exonware/xwnode/{strategies/queries → queries/strategies}/kql.py +1 -1
- exonware/xwnode/{strategies/queries → queries/strategies}/linq.py +1 -1
- exonware/xwnode/{strategies/queries → queries/strategies}/logql.py +1 -1
- exonware/xwnode/{strategies/queries → queries/strategies}/mql.py +1 -1
- exonware/xwnode/{strategies/queries → queries/strategies}/n1ql.py +1 -1
- exonware/xwnode/{strategies/queries → queries/strategies}/partiql.py +1 -1
- exonware/xwnode/{strategies/queries → queries/strategies}/pig.py +1 -1
- exonware/xwnode/{strategies/queries → queries/strategies}/promql.py +1 -1
- exonware/xwnode/{strategies/queries → queries/strategies}/sparql.py +1 -1
- exonware/xwnode/{strategies/queries → queries/strategies}/sql.py +1 -1
- exonware/xwnode/{strategies/queries → queries/strategies}/xml_query.py +1 -1
- exonware/xwnode/{strategies/queries → queries/strategies}/xpath.py +1 -1
- exonware/xwnode/{strategies/queries → queries/strategies}/xquery.py +1 -1
- exonware/xwnode/{strategies/queries → queries/strategies}/xwnode_executor.py +1 -1
- exonware/xwnode/{strategies/queries/xwquery_strategy.py → queries/strategies/xwquery.py} +1 -1
- exonware/xwnode/strategies/__init__.py +8 -8
- exonware/xwnode/version.py +3 -3
- {exonware_xwnode-0.0.1.12.dist-info → exonware_xwnode-0.0.1.14.dist-info}/METADATA +2 -2
- exonware_xwnode-0.0.1.14.dist-info/RECORD +209 -0
- exonware/xwnode/strategies/impls/__init__.py +0 -13
- exonware/xwnode/strategies/nodes/_base_node.py +0 -307
- exonware_xwnode-0.0.1.12.dist-info/RECORD +0 -132
- /exonware/xwnode/{strategies → common/management}/migration.py +0 -0
- /exonware/xwnode/{strategies → common/utils}/simple.py +0 -0
- /exonware/xwnode/{strategies → common/utils}/utils.py +0 -0
- /exonware/xwnode/{strategies/impls → edges/strategies}/_base_edge.py +0 -0
- /exonware/xwnode/{strategies/edges → edges/strategies}/adj_list.py +0 -0
- /exonware/xwnode/{strategies/edges → edges/strategies}/adj_matrix.py +0 -0
- /exonware/xwnode/{strategies/impls → edges/strategies}/edge_adj_list.py +0 -0
- /exonware/xwnode/{strategies/impls → edges/strategies}/edge_adj_matrix.py +0 -0
- /exonware/xwnode/{strategies/impls → edges/strategies}/edge_bidir_wrapper.py +0 -0
- /exonware/xwnode/{strategies/impls → edges/strategies}/edge_block_adj_matrix.py +0 -0
- /exonware/xwnode/{strategies/impls → edges/strategies}/edge_coo.py +0 -0
- /exonware/xwnode/{strategies/impls → edges/strategies}/edge_csc.py +0 -0
- /exonware/xwnode/{strategies/impls → edges/strategies}/edge_csr.py +0 -0
- /exonware/xwnode/{strategies/impls → edges/strategies}/edge_dynamic_adj_list.py +0 -0
- /exonware/xwnode/{strategies/impls → edges/strategies}/edge_flow_network.py +0 -0
- /exonware/xwnode/{strategies/impls → edges/strategies}/edge_hyperedge_set.py +0 -0
- /exonware/xwnode/{strategies/impls → edges/strategies}/edge_neural_graph.py +0 -0
- /exonware/xwnode/{strategies/impls → edges/strategies}/edge_octree.py +0 -0
- /exonware/xwnode/{strategies/impls → edges/strategies}/edge_property_store.py +0 -0
- /exonware/xwnode/{strategies/impls → edges/strategies}/edge_quadtree.py +0 -0
- /exonware/xwnode/{strategies/impls → edges/strategies}/edge_rtree.py +0 -0
- /exonware/xwnode/{strategies/impls → edges/strategies}/edge_temporal_edgeset.py +0 -0
- /exonware/xwnode/{strategies/impls → edges/strategies}/edge_tree_graph_basic.py +0 -0
- /exonware/xwnode/{strategies/impls → edges/strategies}/edge_weighted_graph.py +0 -0
- /exonware/xwnode/{strategies/impls → nodes/strategies}/_base_node.py +0 -0
- /exonware/xwnode/{strategies/nodes → nodes/strategies}/node_cuckoo_hash.py +0 -0
- {exonware_xwnode-0.0.1.12.dist-info → exonware_xwnode-0.0.1.14.dist-info}/WHEEL +0 -0
- {exonware_xwnode-0.0.1.12.dist-info → exonware_xwnode-0.0.1.14.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,50 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
#exonware/xwnode/src/exonware/xwnode/queries/executors/data/load_executor.py
|
4
|
+
|
5
|
+
LOAD Executor
|
6
|
+
|
7
|
+
Company: eXonware.com
|
8
|
+
Author: Eng. Muhammad AlShehri
|
9
|
+
Email: connect@exonware.com
|
10
|
+
Version: 0.0.1.14
|
11
|
+
Generation Date: 09-Oct-2025
|
12
|
+
"""
|
13
|
+
|
14
|
+
from typing import Any, Dict, List
|
15
|
+
from ..base import AUniversalOperationExecutor
|
16
|
+
from ..contracts import Action, ExecutionContext, ExecutionResult
|
17
|
+
from ..types import OperationType
|
18
|
+
|
19
|
+
class LoadExecutor(AUniversalOperationExecutor):
|
20
|
+
"""
|
21
|
+
LOAD operation executor.
|
22
|
+
|
23
|
+
Loads data from external sources
|
24
|
+
|
25
|
+
Capability: Universal
|
26
|
+
Operation Type: DATA_OPS
|
27
|
+
"""
|
28
|
+
|
29
|
+
OPERATION_NAME = "LOAD"
|
30
|
+
OPERATION_TYPE = OperationType.DATA_OPS
|
31
|
+
SUPPORTED_NODE_TYPES = [] # Universal
|
32
|
+
|
33
|
+
def _do_execute(self, action: Action, context: ExecutionContext) -> ExecutionResult:
|
34
|
+
"""Execute LOAD operation."""
|
35
|
+
params = action.params
|
36
|
+
node = context.node
|
37
|
+
|
38
|
+
result_data = self._execute_load(node, params, context)
|
39
|
+
|
40
|
+
return ExecutionResult(
|
41
|
+
success=True,
|
42
|
+
data=result_data,
|
43
|
+
operation=self.OPERATION_NAME,
|
44
|
+
metadata={'operation': self.OPERATION_NAME}
|
45
|
+
)
|
46
|
+
|
47
|
+
def _execute_load(self, node: Any, params: Dict, context: ExecutionContext) -> Dict:
|
48
|
+
"""Execute load logic."""
|
49
|
+
# Implementation here
|
50
|
+
return {'result': 'LOAD executed', 'params': params}
|
@@ -0,0 +1,50 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
#exonware/xwnode/src/exonware/xwnode/queries/executors/data/merge_executor.py
|
4
|
+
|
5
|
+
MERGE Executor
|
6
|
+
|
7
|
+
Company: eXonware.com
|
8
|
+
Author: Eng. Muhammad AlShehri
|
9
|
+
Email: connect@exonware.com
|
10
|
+
Version: 0.0.1.14
|
11
|
+
Generation Date: 09-Oct-2025
|
12
|
+
"""
|
13
|
+
|
14
|
+
from typing import Any, Dict, List
|
15
|
+
from ..base import AUniversalOperationExecutor
|
16
|
+
from ..contracts import Action, ExecutionContext, ExecutionResult
|
17
|
+
from ..types import OperationType
|
18
|
+
|
19
|
+
class MergeExecutor(AUniversalOperationExecutor):
|
20
|
+
"""
|
21
|
+
MERGE operation executor.
|
22
|
+
|
23
|
+
Merges/upserts data
|
24
|
+
|
25
|
+
Capability: Universal
|
26
|
+
Operation Type: DATA_OPS
|
27
|
+
"""
|
28
|
+
|
29
|
+
OPERATION_NAME = "MERGE"
|
30
|
+
OPERATION_TYPE = OperationType.DATA_OPS
|
31
|
+
SUPPORTED_NODE_TYPES = [] # Universal
|
32
|
+
|
33
|
+
def _do_execute(self, action: Action, context: ExecutionContext) -> ExecutionResult:
|
34
|
+
"""Execute MERGE operation."""
|
35
|
+
params = action.params
|
36
|
+
node = context.node
|
37
|
+
|
38
|
+
result_data = self._execute_merge(node, params, context)
|
39
|
+
|
40
|
+
return ExecutionResult(
|
41
|
+
success=True,
|
42
|
+
data=result_data,
|
43
|
+
operation=self.OPERATION_NAME,
|
44
|
+
metadata={'operation': self.OPERATION_NAME}
|
45
|
+
)
|
46
|
+
|
47
|
+
def _execute_merge(self, node: Any, params: Dict, context: ExecutionContext) -> Dict:
|
48
|
+
"""Execute merge logic."""
|
49
|
+
# Implementation here
|
50
|
+
return {'result': 'MERGE executed', 'params': params}
|
@@ -0,0 +1,50 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
#exonware/xwnode/src/exonware/xwnode/queries/executors/data/store_executor.py
|
4
|
+
|
5
|
+
STORE Executor
|
6
|
+
|
7
|
+
Company: eXonware.com
|
8
|
+
Author: Eng. Muhammad AlShehri
|
9
|
+
Email: connect@exonware.com
|
10
|
+
Version: 0.0.1.14
|
11
|
+
Generation Date: 09-Oct-2025
|
12
|
+
"""
|
13
|
+
|
14
|
+
from typing import Any, Dict, List
|
15
|
+
from ..base import AUniversalOperationExecutor
|
16
|
+
from ..contracts import Action, ExecutionContext, ExecutionResult
|
17
|
+
from ..types import OperationType
|
18
|
+
|
19
|
+
class StoreExecutor(AUniversalOperationExecutor):
|
20
|
+
"""
|
21
|
+
STORE operation executor.
|
22
|
+
|
23
|
+
Stores data to external destinations
|
24
|
+
|
25
|
+
Capability: Universal
|
26
|
+
Operation Type: DATA_OPS
|
27
|
+
"""
|
28
|
+
|
29
|
+
OPERATION_NAME = "STORE"
|
30
|
+
OPERATION_TYPE = OperationType.DATA_OPS
|
31
|
+
SUPPORTED_NODE_TYPES = [] # Universal
|
32
|
+
|
33
|
+
def _do_execute(self, action: Action, context: ExecutionContext) -> ExecutionResult:
|
34
|
+
"""Execute STORE operation."""
|
35
|
+
params = action.params
|
36
|
+
node = context.node
|
37
|
+
|
38
|
+
result_data = self._execute_store(node, params, context)
|
39
|
+
|
40
|
+
return ExecutionResult(
|
41
|
+
success=True,
|
42
|
+
data=result_data,
|
43
|
+
operation=self.OPERATION_NAME,
|
44
|
+
metadata={'operation': self.OPERATION_NAME}
|
45
|
+
)
|
46
|
+
|
47
|
+
def _execute_store(self, node: Any, params: Dict, context: ExecutionContext) -> Dict:
|
48
|
+
"""Execute store logic."""
|
49
|
+
# Implementation here
|
50
|
+
return {'result': 'STORE executed', 'params': params}
|
@@ -0,0 +1,221 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
#exonware/xwnode/src/exonware/xwnode/queries/executors/engine.py
|
4
|
+
|
5
|
+
Query Execution Engine
|
6
|
+
|
7
|
+
This module provides the main execution engine that orchestrates operation execution
|
8
|
+
with capability checking and routing.
|
9
|
+
|
10
|
+
Company: eXonware.com
|
11
|
+
Author: Eng. Muhammad AlShehri
|
12
|
+
Email: connect@exonware.com
|
13
|
+
Version: 0.0.1.14
|
14
|
+
Generation Date: 08-Oct-2025
|
15
|
+
"""
|
16
|
+
|
17
|
+
from typing import Any, List, Dict, Optional
|
18
|
+
from .contracts import Action, ExecutionContext, ExecutionResult, NodeType
|
19
|
+
from .registry import get_operation_registry, OperationRegistry
|
20
|
+
from .capability_checker import check_operation_compatibility
|
21
|
+
from .base import UnsupportedOperationError
|
22
|
+
from ...base import XWNodeBase
|
23
|
+
|
24
|
+
|
25
|
+
class ExecutionEngine:
|
26
|
+
"""
|
27
|
+
Main query execution engine.
|
28
|
+
|
29
|
+
Orchestrates execution of XWQuery operations on nodes with:
|
30
|
+
- Capability-aware routing
|
31
|
+
- Operation composition
|
32
|
+
- Error handling
|
33
|
+
- Performance monitoring
|
34
|
+
"""
|
35
|
+
|
36
|
+
def __init__(self, registry: Optional[OperationRegistry] = None):
|
37
|
+
"""
|
38
|
+
Initialize execution engine.
|
39
|
+
|
40
|
+
Args:
|
41
|
+
registry: Operation registry (uses global if not provided)
|
42
|
+
"""
|
43
|
+
self._registry = registry or get_operation_registry()
|
44
|
+
self._execution_history: List[Dict] = []
|
45
|
+
|
46
|
+
def execute(self, query: str, node: Any, **kwargs) -> ExecutionResult:
|
47
|
+
"""
|
48
|
+
Execute a query string on a node.
|
49
|
+
|
50
|
+
Args:
|
51
|
+
query: XWQuery script string
|
52
|
+
node: Target node to execute on
|
53
|
+
**kwargs: Additional execution options
|
54
|
+
|
55
|
+
Returns:
|
56
|
+
ExecutionResult with data
|
57
|
+
"""
|
58
|
+
# Parse query to actions tree
|
59
|
+
from ..strategies.xwquery import XWQueryScriptStrategy
|
60
|
+
|
61
|
+
script_strategy = XWQueryScriptStrategy()
|
62
|
+
parsed = script_strategy.parse_script(query)
|
63
|
+
actions_tree = parsed.get_actions_tree()
|
64
|
+
|
65
|
+
# Create execution context
|
66
|
+
context = ExecutionContext(
|
67
|
+
node=node,
|
68
|
+
variables=kwargs.get('variables', {}),
|
69
|
+
options=kwargs
|
70
|
+
)
|
71
|
+
|
72
|
+
# Execute actions tree
|
73
|
+
return self.execute_actions_tree(actions_tree, context)
|
74
|
+
|
75
|
+
def execute_actions_tree(self, actions_tree: XWNodeBase, context: ExecutionContext) -> ExecutionResult:
|
76
|
+
"""
|
77
|
+
Execute an actions tree.
|
78
|
+
|
79
|
+
Args:
|
80
|
+
actions_tree: Parsed actions tree
|
81
|
+
context: Execution context
|
82
|
+
|
83
|
+
Returns:
|
84
|
+
Combined execution result
|
85
|
+
"""
|
86
|
+
tree_data = actions_tree.to_native()
|
87
|
+
statements = tree_data.get('root', {}).get('statements', [])
|
88
|
+
|
89
|
+
results = []
|
90
|
+
|
91
|
+
for statement in statements:
|
92
|
+
# Create action from statement
|
93
|
+
action = Action(
|
94
|
+
type=statement.get('type', 'UNKNOWN'),
|
95
|
+
params=statement.get('params', {}),
|
96
|
+
id=statement.get('id', ''),
|
97
|
+
line_number=statement.get('line_number', 0)
|
98
|
+
)
|
99
|
+
|
100
|
+
# Execute action
|
101
|
+
result = self.execute_action(action, context)
|
102
|
+
results.append(result)
|
103
|
+
|
104
|
+
# Store result for later actions
|
105
|
+
if action.id:
|
106
|
+
context.set_result(action.id, result.data)
|
107
|
+
|
108
|
+
# Combine results
|
109
|
+
return self._combine_results(results)
|
110
|
+
|
111
|
+
def execute_action(self, action: Action, context: ExecutionContext) -> ExecutionResult:
|
112
|
+
"""
|
113
|
+
Execute a single action.
|
114
|
+
|
115
|
+
Args:
|
116
|
+
action: Action to execute
|
117
|
+
context: Execution context
|
118
|
+
|
119
|
+
Returns:
|
120
|
+
ExecutionResult
|
121
|
+
"""
|
122
|
+
# Get executor for this operation
|
123
|
+
executor = self._registry.get(action.type)
|
124
|
+
|
125
|
+
if not executor:
|
126
|
+
return ExecutionResult(
|
127
|
+
data=None,
|
128
|
+
success=False,
|
129
|
+
error=f"No executor registered for operation: {action.type}"
|
130
|
+
)
|
131
|
+
|
132
|
+
# Check capability before execution
|
133
|
+
try:
|
134
|
+
node_type = self._get_node_type(context.node)
|
135
|
+
|
136
|
+
if not executor.can_execute_on(node_type):
|
137
|
+
return ExecutionResult(
|
138
|
+
data=None,
|
139
|
+
success=False,
|
140
|
+
error=f"Operation {action.type} not supported on {node_type.name} nodes"
|
141
|
+
)
|
142
|
+
|
143
|
+
# Execute
|
144
|
+
result = executor.execute(action, context)
|
145
|
+
|
146
|
+
# Record execution
|
147
|
+
self._record_execution(action, result)
|
148
|
+
|
149
|
+
return result
|
150
|
+
|
151
|
+
except UnsupportedOperationError as e:
|
152
|
+
return ExecutionResult(
|
153
|
+
data=None,
|
154
|
+
success=False,
|
155
|
+
error=str(e)
|
156
|
+
)
|
157
|
+
except Exception as e:
|
158
|
+
return ExecutionResult(
|
159
|
+
data=None,
|
160
|
+
success=False,
|
161
|
+
error=f"Execution error: {str(e)}"
|
162
|
+
)
|
163
|
+
|
164
|
+
def _get_node_type(self, node: Any) -> NodeType:
|
165
|
+
"""Get node's strategy type."""
|
166
|
+
if hasattr(node, '_strategy') and hasattr(node._strategy, 'STRATEGY_TYPE'):
|
167
|
+
return node._strategy.STRATEGY_TYPE
|
168
|
+
elif hasattr(node, 'STRATEGY_TYPE'):
|
169
|
+
return node.STRATEGY_TYPE
|
170
|
+
return NodeType.TREE # Default
|
171
|
+
|
172
|
+
def _combine_results(self, results: List[ExecutionResult]) -> ExecutionResult:
|
173
|
+
"""Combine multiple execution results."""
|
174
|
+
if not results:
|
175
|
+
return ExecutionResult(data=[])
|
176
|
+
|
177
|
+
if len(results) == 1:
|
178
|
+
return results[0]
|
179
|
+
|
180
|
+
# Combine data from all results
|
181
|
+
combined_data = []
|
182
|
+
total_affected = 0
|
183
|
+
total_time = 0.0
|
184
|
+
all_success = True
|
185
|
+
|
186
|
+
for result in results:
|
187
|
+
if result.data:
|
188
|
+
if isinstance(result.data, list):
|
189
|
+
combined_data.extend(result.data)
|
190
|
+
else:
|
191
|
+
combined_data.append(result.data)
|
192
|
+
total_affected += result.affected_count
|
193
|
+
total_time += result.execution_time
|
194
|
+
all_success = all_success and result.success
|
195
|
+
|
196
|
+
return ExecutionResult(
|
197
|
+
data=combined_data,
|
198
|
+
affected_count=total_affected,
|
199
|
+
execution_time=total_time,
|
200
|
+
success=all_success
|
201
|
+
)
|
202
|
+
|
203
|
+
def _record_execution(self, action: Action, result: ExecutionResult) -> None:
|
204
|
+
"""Record execution in history."""
|
205
|
+
self._execution_history.append({
|
206
|
+
'action': action.type,
|
207
|
+
'success': result.success,
|
208
|
+
'affected_count': result.affected_count,
|
209
|
+
'execution_time': result.execution_time
|
210
|
+
})
|
211
|
+
|
212
|
+
def get_execution_history(self) -> List[Dict]:
|
213
|
+
"""Get execution history."""
|
214
|
+
return self._execution_history.copy()
|
215
|
+
|
216
|
+
def clear_history(self) -> None:
|
217
|
+
"""Clear execution history."""
|
218
|
+
self._execution_history.clear()
|
219
|
+
|
220
|
+
|
221
|
+
__all__ = ['ExecutionEngine']
|
@@ -0,0 +1,68 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
#exonware/xwnode/src/exonware/xwnode/queries/executors/errors.py
|
4
|
+
|
5
|
+
Executor Error Classes
|
6
|
+
|
7
|
+
Module-specific errors for query operation executors.
|
8
|
+
Extends root error classes per DEV_GUIDELINES.md - no redundancy.
|
9
|
+
|
10
|
+
Company: eXonware.com
|
11
|
+
Author: Eng. Muhammad AlShehri
|
12
|
+
Email: connect@exonware.com
|
13
|
+
Version: 0.0.1.14
|
14
|
+
Generation Date: 08-Oct-2025
|
15
|
+
"""
|
16
|
+
|
17
|
+
# Import and REUSE root error classes per DEV_GUIDELINES
|
18
|
+
from ...errors import (
|
19
|
+
XWNodeError,
|
20
|
+
XWNodeStrategyError,
|
21
|
+
XWNodeUnsupportedCapabilityError,
|
22
|
+
XWNodeValueError
|
23
|
+
)
|
24
|
+
from ...nodes.strategies.contracts import NodeType
|
25
|
+
|
26
|
+
|
27
|
+
class ExecutorError(XWNodeStrategyError):
|
28
|
+
"""
|
29
|
+
Base error for executor operations.
|
30
|
+
|
31
|
+
Extends XWNodeStrategyError from root - follows DEV_GUIDELINES principle:
|
32
|
+
"Never reinvent the wheel - reuse code from xwsystem library or xnode"
|
33
|
+
"""
|
34
|
+
pass
|
35
|
+
|
36
|
+
|
37
|
+
class OperationExecutionError(ExecutorError):
|
38
|
+
"""Raised when operation execution fails."""
|
39
|
+
|
40
|
+
def __init__(self, operation: str, reason: str, context: dict = None):
|
41
|
+
message = f"Operation '{operation}' execution failed: {reason}"
|
42
|
+
super().__init__(message)
|
43
|
+
self.operation = operation
|
44
|
+
self.reason = reason
|
45
|
+
self.add_context(**(context or {}))
|
46
|
+
|
47
|
+
|
48
|
+
class ValidationError(ExecutorError):
|
49
|
+
"""Raised when action validation fails."""
|
50
|
+
|
51
|
+
def __init__(self, action_type: str, reason: str):
|
52
|
+
message = f"Action validation failed for '{action_type}': {reason}"
|
53
|
+
super().__init__(message)
|
54
|
+
self.action_type = action_type
|
55
|
+
self.reason = reason
|
56
|
+
|
57
|
+
|
58
|
+
# REUSE existing error from root, don't duplicate
|
59
|
+
# Alias for convenience in this module
|
60
|
+
UnsupportedOperationError = XWNodeUnsupportedCapabilityError
|
61
|
+
|
62
|
+
|
63
|
+
__all__ = [
|
64
|
+
'ExecutorError',
|
65
|
+
'OperationExecutionError',
|
66
|
+
'ValidationError',
|
67
|
+
'UnsupportedOperationError', # Re-exported from root
|
68
|
+
]
|
@@ -0,0 +1,25 @@
|
|
1
|
+
"""Filtering operation executors."""
|
2
|
+
|
3
|
+
from .where_executor import WhereExecutor
|
4
|
+
from .filter_executor import FilterExecutor
|
5
|
+
from .like_executor import LikeExecutor
|
6
|
+
from .in_executor import InExecutor
|
7
|
+
from .has_executor import HasExecutor
|
8
|
+
from .between_executor import BetweenExecutor
|
9
|
+
from .range_executor import RangeExecutor
|
10
|
+
from .term_executor import TermExecutor
|
11
|
+
from .optional_executor import OptionalExecutor
|
12
|
+
from .values_executor import ValuesExecutor
|
13
|
+
|
14
|
+
__all__ = [
|
15
|
+
'WhereExecutor',
|
16
|
+
'FilterExecutor',
|
17
|
+
'LikeExecutor',
|
18
|
+
'InExecutor',
|
19
|
+
'HasExecutor',
|
20
|
+
'BetweenExecutor',
|
21
|
+
'RangeExecutor',
|
22
|
+
'TermExecutor',
|
23
|
+
'OptionalExecutor',
|
24
|
+
'ValuesExecutor',
|
25
|
+
]
|
@@ -0,0 +1,80 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
#exonware/xwnode/src/exonware/xwnode/queries/executors/filtering/between_executor.py
|
4
|
+
|
5
|
+
BETWEEN Executor
|
6
|
+
|
7
|
+
Company: eXonware.com
|
8
|
+
Author: Eng. Muhammad AlShehri
|
9
|
+
Email: connect@exonware.com
|
10
|
+
Version: 0.0.1.14
|
11
|
+
Generation Date: 08-Oct-2025
|
12
|
+
"""
|
13
|
+
|
14
|
+
from typing import Any, Dict, List
|
15
|
+
from ..base import AOperationExecutor
|
16
|
+
from ..contracts import Action, ExecutionContext, ExecutionResult
|
17
|
+
from ..types import OperationType
|
18
|
+
from ...nodes.strategies.contracts import NodeType
|
19
|
+
|
20
|
+
|
21
|
+
class BetweenExecutor(AOperationExecutor):
|
22
|
+
"""
|
23
|
+
BETWEEN operation executor - Tree/Matrix operation.
|
24
|
+
|
25
|
+
Checks if values are within a range (inclusive).
|
26
|
+
Optimized for TREE and MATRIX node types.
|
27
|
+
|
28
|
+
Capability: Tree/Matrix only
|
29
|
+
Operation Type: FILTERING
|
30
|
+
"""
|
31
|
+
|
32
|
+
OPERATION_NAME = "BETWEEN"
|
33
|
+
OPERATION_TYPE = OperationType.FILTERING
|
34
|
+
SUPPORTED_NODE_TYPES = [NodeType.TREE, NodeType.MATRIX, NodeType.HYBRID]
|
35
|
+
|
36
|
+
def _do_execute(self, action: Action, context: ExecutionContext) -> ExecutionResult:
|
37
|
+
"""Execute BETWEEN operation."""
|
38
|
+
params = action.params
|
39
|
+
field = params.get('field')
|
40
|
+
min_value = params.get('min')
|
41
|
+
max_value = params.get('max')
|
42
|
+
path = params.get('path', None)
|
43
|
+
|
44
|
+
node = context.node
|
45
|
+
result_data = self._execute_between(node, field, min_value, max_value, path, context)
|
46
|
+
|
47
|
+
return ExecutionResult(
|
48
|
+
success=True,
|
49
|
+
data=result_data,
|
50
|
+
operation=self.OPERATION_NAME,
|
51
|
+
metadata={'matched_count': len(result_data.get('items', []))}
|
52
|
+
)
|
53
|
+
|
54
|
+
def _execute_between(self, node: Any, field: str, min_val: Any, max_val: Any,
|
55
|
+
path: str, context: ExecutionContext) -> Dict:
|
56
|
+
"""Execute BETWEEN range check."""
|
57
|
+
matched_items = []
|
58
|
+
|
59
|
+
# Get data
|
60
|
+
if path:
|
61
|
+
data = node.get(path, default=[])
|
62
|
+
else:
|
63
|
+
data = node.to_native()
|
64
|
+
|
65
|
+
# Check range
|
66
|
+
if isinstance(data, list):
|
67
|
+
for item in data:
|
68
|
+
value = item.get(field) if isinstance(item, dict) else item
|
69
|
+
try:
|
70
|
+
if min_val <= value <= max_val:
|
71
|
+
matched_items.append(item)
|
72
|
+
except (TypeError, ValueError):
|
73
|
+
pass
|
74
|
+
|
75
|
+
return {
|
76
|
+
'items': matched_items,
|
77
|
+
'count': len(matched_items),
|
78
|
+
'range': {'min': min_val, 'max': max_val}
|
79
|
+
}
|
80
|
+
|
@@ -0,0 +1,79 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
#exonware/xwnode/src/exonware/xwnode/queries/executors/filtering/filter_executor.py
|
4
|
+
|
5
|
+
FILTER Executor
|
6
|
+
|
7
|
+
Company: eXonware.com
|
8
|
+
Author: Eng. Muhammad AlShehri
|
9
|
+
Email: connect@exonware.com
|
10
|
+
Version: 0.0.1.14
|
11
|
+
Generation Date: 08-Oct-2025
|
12
|
+
"""
|
13
|
+
|
14
|
+
from typing import Any, Dict, List, Callable
|
15
|
+
from ..base import AUniversalOperationExecutor
|
16
|
+
from ..contracts import Action, ExecutionContext, ExecutionResult
|
17
|
+
from ..types import OperationType
|
18
|
+
|
19
|
+
|
20
|
+
class FilterExecutor(AUniversalOperationExecutor):
|
21
|
+
"""
|
22
|
+
FILTER operation executor - Universal operation.
|
23
|
+
|
24
|
+
Filters data based on specified conditions.
|
25
|
+
General-purpose filtering that works on all node types.
|
26
|
+
|
27
|
+
Capability: Universal
|
28
|
+
Operation Type: FILTERING
|
29
|
+
"""
|
30
|
+
|
31
|
+
OPERATION_NAME = "FILTER"
|
32
|
+
OPERATION_TYPE = OperationType.FILTERING
|
33
|
+
SUPPORTED_NODE_TYPES = [] # Universal
|
34
|
+
|
35
|
+
def _do_execute(self, action: Action, context: ExecutionContext) -> ExecutionResult:
|
36
|
+
"""Execute FILTER operation."""
|
37
|
+
params = action.params
|
38
|
+
condition = params.get('condition', None)
|
39
|
+
path = params.get('path', None)
|
40
|
+
|
41
|
+
node = context.node
|
42
|
+
result_data = self._execute_filter(node, condition, path, context)
|
43
|
+
|
44
|
+
return ExecutionResult(
|
45
|
+
success=True,
|
46
|
+
data=result_data,
|
47
|
+
operation=self.OPERATION_NAME,
|
48
|
+
metadata={'filtered_count': len(result_data.get('items', []))}
|
49
|
+
)
|
50
|
+
|
51
|
+
def _execute_filter(self, node: Any, condition: Any, path: str, context: ExecutionContext) -> Dict:
|
52
|
+
"""Execute filter logic."""
|
53
|
+
filtered_items = []
|
54
|
+
|
55
|
+
# Get data to filter
|
56
|
+
if path:
|
57
|
+
data = node.get(path, default=[])
|
58
|
+
else:
|
59
|
+
data = node.to_native()
|
60
|
+
|
61
|
+
# Apply filter (simplified)
|
62
|
+
if isinstance(data, list):
|
63
|
+
for item in data:
|
64
|
+
if self._matches_filter(item, condition):
|
65
|
+
filtered_items.append(item)
|
66
|
+
elif isinstance(data, dict):
|
67
|
+
for key, value in data.items():
|
68
|
+
if self._matches_filter(value, condition):
|
69
|
+
filtered_items.append({key: value})
|
70
|
+
|
71
|
+
return {'items': filtered_items, 'count': len(filtered_items)}
|
72
|
+
|
73
|
+
def _matches_filter(self, item: Any, condition: Any) -> bool:
|
74
|
+
"""Check if item matches filter condition."""
|
75
|
+
if condition is None:
|
76
|
+
return True
|
77
|
+
# Simplified condition matching
|
78
|
+
return True
|
79
|
+
|
@@ -0,0 +1,70 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
#exonware/xwnode/src/exonware/xwnode/queries/executors/filtering/has_executor.py
|
4
|
+
|
5
|
+
HAS Executor
|
6
|
+
|
7
|
+
Company: eXonware.com
|
8
|
+
Author: Eng. Muhammad AlShehri
|
9
|
+
Email: connect@exonware.com
|
10
|
+
Version: 0.0.1.14
|
11
|
+
Generation Date: 08-Oct-2025
|
12
|
+
"""
|
13
|
+
|
14
|
+
from typing import Any, Dict, List
|
15
|
+
from ..base import AUniversalOperationExecutor
|
16
|
+
from ..contracts import Action, ExecutionContext, ExecutionResult
|
17
|
+
from ..types import OperationType
|
18
|
+
|
19
|
+
|
20
|
+
class HasExecutor(AUniversalOperationExecutor):
|
21
|
+
"""
|
22
|
+
HAS operation executor - Universal operation.
|
23
|
+
|
24
|
+
Checks if a property/field exists in data.
|
25
|
+
|
26
|
+
Capability: Universal
|
27
|
+
Operation Type: FILTERING
|
28
|
+
"""
|
29
|
+
|
30
|
+
OPERATION_NAME = "HAS"
|
31
|
+
OPERATION_TYPE = OperationType.FILTERING
|
32
|
+
SUPPORTED_NODE_TYPES = [] # Universal
|
33
|
+
|
34
|
+
def _do_execute(self, action: Action, context: ExecutionContext) -> ExecutionResult:
|
35
|
+
"""Execute HAS operation."""
|
36
|
+
params = action.params
|
37
|
+
property_name = params.get('property')
|
38
|
+
path = params.get('path', None)
|
39
|
+
|
40
|
+
node = context.node
|
41
|
+
result_data = self._execute_has(node, property_name, path, context)
|
42
|
+
|
43
|
+
return ExecutionResult(
|
44
|
+
success=True,
|
45
|
+
data=result_data,
|
46
|
+
operation=self.OPERATION_NAME,
|
47
|
+
metadata={'matched_count': len(result_data.get('items', []))}
|
48
|
+
)
|
49
|
+
|
50
|
+
def _execute_has(self, node: Any, property_name: str, path: str, context: ExecutionContext) -> Dict:
|
51
|
+
"""Execute HAS property check."""
|
52
|
+
matched_items = []
|
53
|
+
|
54
|
+
# Get data
|
55
|
+
if path:
|
56
|
+
data = node.get(path, default=[])
|
57
|
+
else:
|
58
|
+
data = node.to_native()
|
59
|
+
|
60
|
+
# Check property existence
|
61
|
+
if isinstance(data, list):
|
62
|
+
for item in data:
|
63
|
+
if isinstance(item, dict) and property_name in item:
|
64
|
+
matched_items.append(item)
|
65
|
+
elif isinstance(data, dict):
|
66
|
+
if property_name in data:
|
67
|
+
matched_items.append(data)
|
68
|
+
|
69
|
+
return {'items': matched_items, 'count': len(matched_items), 'property': property_name}
|
70
|
+
|