exonware-xwnode 0.0.1.21__py3-none-any.whl → 0.0.1.23__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 +8 -1
- exonware/xwnode/__init__.py +18 -5
- exonware/xwnode/add_strategy_types.py +165 -0
- exonware/xwnode/base.py +7 -5
- exonware/xwnode/common/__init__.py +1 -1
- exonware/xwnode/common/graph/__init__.py +30 -0
- exonware/xwnode/common/graph/caching.py +131 -0
- exonware/xwnode/common/graph/contracts.py +100 -0
- exonware/xwnode/common/graph/errors.py +44 -0
- exonware/xwnode/common/graph/indexing.py +260 -0
- exonware/xwnode/common/graph/manager.py +568 -0
- exonware/xwnode/common/management/__init__.py +3 -5
- exonware/xwnode/common/management/manager.py +9 -9
- exonware/xwnode/common/management/migration.py +6 -6
- exonware/xwnode/common/monitoring/__init__.py +3 -5
- exonware/xwnode/common/monitoring/metrics.py +7 -3
- exonware/xwnode/common/monitoring/pattern_detector.py +2 -2
- exonware/xwnode/common/monitoring/performance_monitor.py +6 -2
- exonware/xwnode/common/patterns/__init__.py +3 -5
- exonware/xwnode/common/patterns/advisor.py +1 -1
- exonware/xwnode/common/patterns/flyweight.py +6 -2
- exonware/xwnode/common/patterns/registry.py +203 -184
- exonware/xwnode/common/utils/__init__.py +25 -11
- exonware/xwnode/common/utils/simple.py +1 -1
- exonware/xwnode/config.py +3 -8
- exonware/xwnode/contracts.py +4 -105
- exonware/xwnode/defs.py +413 -159
- exonware/xwnode/edges/strategies/__init__.py +86 -4
- exonware/xwnode/edges/strategies/_base_edge.py +2 -2
- exonware/xwnode/edges/strategies/adj_list.py +287 -121
- exonware/xwnode/edges/strategies/adj_matrix.py +316 -222
- exonware/xwnode/edges/strategies/base.py +1 -1
- exonware/xwnode/edges/strategies/{edge_bidir_wrapper.py → bidir_wrapper.py} +45 -4
- exonware/xwnode/edges/strategies/bitemporal.py +520 -0
- exonware/xwnode/edges/strategies/{edge_block_adj_matrix.py → block_adj_matrix.py} +77 -6
- exonware/xwnode/edges/strategies/bv_graph.py +664 -0
- exonware/xwnode/edges/strategies/compressed_graph.py +217 -0
- exonware/xwnode/edges/strategies/{edge_coo.py → coo.py} +46 -4
- exonware/xwnode/edges/strategies/{edge_csc.py → csc.py} +45 -4
- exonware/xwnode/edges/strategies/{edge_csr.py → csr.py} +94 -12
- exonware/xwnode/edges/strategies/{edge_dynamic_adj_list.py → dynamic_adj_list.py} +46 -4
- exonware/xwnode/edges/strategies/edge_list.py +168 -0
- exonware/xwnode/edges/strategies/edge_property_store.py +2 -2
- exonware/xwnode/edges/strategies/euler_tour.py +560 -0
- exonware/xwnode/edges/strategies/{edge_flow_network.py → flow_network.py} +2 -2
- exonware/xwnode/edges/strategies/graphblas.py +449 -0
- exonware/xwnode/edges/strategies/hnsw.py +637 -0
- exonware/xwnode/edges/strategies/hop2_labels.py +467 -0
- exonware/xwnode/edges/strategies/{edge_hyperedge_set.py → hyperedge_set.py} +2 -2
- exonware/xwnode/edges/strategies/incidence_matrix.py +250 -0
- exonware/xwnode/edges/strategies/k2_tree.py +613 -0
- exonware/xwnode/edges/strategies/link_cut.py +626 -0
- exonware/xwnode/edges/strategies/multiplex.py +532 -0
- exonware/xwnode/edges/strategies/{edge_neural_graph.py → neural_graph.py} +2 -2
- exonware/xwnode/edges/strategies/{edge_octree.py → octree.py} +69 -11
- exonware/xwnode/edges/strategies/{edge_quadtree.py → quadtree.py} +66 -10
- exonware/xwnode/edges/strategies/roaring_adj.py +438 -0
- exonware/xwnode/edges/strategies/{edge_rtree.py → rtree.py} +43 -5
- exonware/xwnode/edges/strategies/{edge_temporal_edgeset.py → temporal_edgeset.py} +24 -5
- exonware/xwnode/edges/strategies/{edge_tree_graph_basic.py → tree_graph_basic.py} +78 -7
- exonware/xwnode/edges/strategies/{edge_weighted_graph.py → weighted_graph.py} +188 -10
- exonware/xwnode/errors.py +3 -6
- exonware/xwnode/facade.py +20 -20
- exonware/xwnode/nodes/strategies/__init__.py +29 -9
- exonware/xwnode/nodes/strategies/adjacency_list.py +650 -177
- exonware/xwnode/nodes/strategies/aho_corasick.py +358 -183
- exonware/xwnode/nodes/strategies/array_list.py +36 -3
- exonware/xwnode/nodes/strategies/art.py +581 -0
- exonware/xwnode/nodes/strategies/{node_avl_tree.py → avl_tree.py} +77 -6
- exonware/xwnode/nodes/strategies/{node_b_plus_tree.py → b_plus_tree.py} +81 -40
- exonware/xwnode/nodes/strategies/{node_btree.py → b_tree.py} +79 -9
- exonware/xwnode/nodes/strategies/base.py +469 -98
- exonware/xwnode/nodes/strategies/{node_bitmap.py → bitmap.py} +12 -12
- exonware/xwnode/nodes/strategies/{node_bitset_dynamic.py → bitset_dynamic.py} +11 -11
- exonware/xwnode/nodes/strategies/{node_bloom_filter.py → bloom_filter.py} +15 -2
- exonware/xwnode/nodes/strategies/bloomier_filter.py +519 -0
- exonware/xwnode/nodes/strategies/bw_tree.py +531 -0
- exonware/xwnode/nodes/strategies/contracts.py +1 -1
- exonware/xwnode/nodes/strategies/{node_count_min_sketch.py → count_min_sketch.py} +3 -2
- exonware/xwnode/nodes/strategies/{node_cow_tree.py → cow_tree.py} +135 -13
- exonware/xwnode/nodes/strategies/crdt_map.py +629 -0
- exonware/xwnode/nodes/strategies/{node_cuckoo_hash.py → cuckoo_hash.py} +2 -2
- exonware/xwnode/nodes/strategies/{node_xdata_optimized.py → data_interchange_optimized.py} +21 -4
- exonware/xwnode/nodes/strategies/dawg.py +876 -0
- exonware/xwnode/nodes/strategies/deque.py +321 -153
- exonware/xwnode/nodes/strategies/extendible_hash.py +93 -0
- exonware/xwnode/nodes/strategies/{node_fenwick_tree.py → fenwick_tree.py} +111 -19
- exonware/xwnode/nodes/strategies/hamt.py +403 -0
- exonware/xwnode/nodes/strategies/hash_map.py +354 -67
- exonware/xwnode/nodes/strategies/heap.py +105 -5
- exonware/xwnode/nodes/strategies/hopscotch_hash.py +525 -0
- exonware/xwnode/nodes/strategies/{node_hyperloglog.py → hyperloglog.py} +6 -5
- exonware/xwnode/nodes/strategies/interval_tree.py +742 -0
- exonware/xwnode/nodes/strategies/kd_tree.py +703 -0
- exonware/xwnode/nodes/strategies/learned_index.py +533 -0
- exonware/xwnode/nodes/strategies/linear_hash.py +93 -0
- exonware/xwnode/nodes/strategies/linked_list.py +316 -119
- exonware/xwnode/nodes/strategies/{node_lsm_tree.py → lsm_tree.py} +219 -15
- exonware/xwnode/nodes/strategies/masstree.py +130 -0
- exonware/xwnode/nodes/strategies/{node_persistent_tree.py → persistent_tree.py} +149 -9
- exonware/xwnode/nodes/strategies/priority_queue.py +544 -132
- exonware/xwnode/nodes/strategies/queue.py +249 -120
- exonware/xwnode/nodes/strategies/{node_red_black_tree.py → red_black_tree.py} +183 -72
- exonware/xwnode/nodes/strategies/{node_roaring_bitmap.py → roaring_bitmap.py} +19 -6
- exonware/xwnode/nodes/strategies/rope.py +717 -0
- exonware/xwnode/nodes/strategies/{node_segment_tree.py → segment_tree.py} +106 -106
- exonware/xwnode/nodes/strategies/{node_set_hash.py → set_hash.py} +30 -29
- exonware/xwnode/nodes/strategies/{node_skip_list.py → skip_list.py} +74 -6
- exonware/xwnode/nodes/strategies/sparse_matrix.py +427 -131
- exonware/xwnode/nodes/strategies/{node_splay_tree.py → splay_tree.py} +55 -6
- exonware/xwnode/nodes/strategies/stack.py +244 -112
- exonware/xwnode/nodes/strategies/{node_suffix_array.py → suffix_array.py} +5 -1
- exonware/xwnode/nodes/strategies/t_tree.py +94 -0
- exonware/xwnode/nodes/strategies/{node_treap.py → treap.py} +75 -6
- exonware/xwnode/nodes/strategies/{node_tree_graph_hybrid.py → tree_graph_hybrid.py} +46 -5
- exonware/xwnode/nodes/strategies/trie.py +153 -9
- exonware/xwnode/nodes/strategies/union_find.py +111 -5
- exonware/xwnode/nodes/strategies/veb_tree.py +856 -0
- exonware/xwnode/strategies/__init__.py +5 -51
- exonware/xwnode/version.py +3 -3
- {exonware_xwnode-0.0.1.21.dist-info → exonware_xwnode-0.0.1.23.dist-info}/METADATA +23 -3
- exonware_xwnode-0.0.1.23.dist-info/RECORD +130 -0
- exonware/xwnode/edges/strategies/edge_adj_list.py +0 -353
- exonware/xwnode/edges/strategies/edge_adj_matrix.py +0 -445
- exonware/xwnode/nodes/strategies/_base_node.py +0 -307
- exonware/xwnode/nodes/strategies/node_aho_corasick.py +0 -525
- exonware/xwnode/nodes/strategies/node_array_list.py +0 -179
- exonware/xwnode/nodes/strategies/node_hash_map.py +0 -273
- exonware/xwnode/nodes/strategies/node_heap.py +0 -196
- exonware/xwnode/nodes/strategies/node_linked_list.py +0 -413
- exonware/xwnode/nodes/strategies/node_trie.py +0 -257
- exonware/xwnode/nodes/strategies/node_union_find.py +0 -192
- exonware/xwnode/queries/executors/__init__.py +0 -47
- exonware/xwnode/queries/executors/advanced/__init__.py +0 -37
- exonware/xwnode/queries/executors/advanced/aggregate_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/ask_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/construct_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/describe_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/for_loop_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/foreach_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/join_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/let_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/mutation_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/options_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/pipe_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/subscribe_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/subscription_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/union_executor.py +0 -50
- exonware/xwnode/queries/executors/advanced/window_executor.py +0 -51
- exonware/xwnode/queries/executors/advanced/with_cte_executor.py +0 -50
- exonware/xwnode/queries/executors/aggregation/__init__.py +0 -21
- exonware/xwnode/queries/executors/aggregation/avg_executor.py +0 -50
- exonware/xwnode/queries/executors/aggregation/count_executor.py +0 -38
- exonware/xwnode/queries/executors/aggregation/distinct_executor.py +0 -50
- exonware/xwnode/queries/executors/aggregation/group_executor.py +0 -50
- exonware/xwnode/queries/executors/aggregation/having_executor.py +0 -50
- exonware/xwnode/queries/executors/aggregation/max_executor.py +0 -50
- exonware/xwnode/queries/executors/aggregation/min_executor.py +0 -50
- exonware/xwnode/queries/executors/aggregation/sum_executor.py +0 -50
- exonware/xwnode/queries/executors/aggregation/summarize_executor.py +0 -50
- exonware/xwnode/queries/executors/array/__init__.py +0 -9
- exonware/xwnode/queries/executors/array/indexing_executor.py +0 -51
- exonware/xwnode/queries/executors/array/slicing_executor.py +0 -51
- exonware/xwnode/queries/executors/base.py +0 -257
- exonware/xwnode/queries/executors/capability_checker.py +0 -204
- exonware/xwnode/queries/executors/contracts.py +0 -166
- exonware/xwnode/queries/executors/core/__init__.py +0 -17
- exonware/xwnode/queries/executors/core/create_executor.py +0 -96
- exonware/xwnode/queries/executors/core/delete_executor.py +0 -99
- exonware/xwnode/queries/executors/core/drop_executor.py +0 -100
- exonware/xwnode/queries/executors/core/insert_executor.py +0 -39
- exonware/xwnode/queries/executors/core/select_executor.py +0 -152
- exonware/xwnode/queries/executors/core/update_executor.py +0 -102
- exonware/xwnode/queries/executors/data/__init__.py +0 -13
- exonware/xwnode/queries/executors/data/alter_executor.py +0 -50
- exonware/xwnode/queries/executors/data/load_executor.py +0 -50
- exonware/xwnode/queries/executors/data/merge_executor.py +0 -50
- exonware/xwnode/queries/executors/data/store_executor.py +0 -50
- exonware/xwnode/queries/executors/defs.py +0 -93
- exonware/xwnode/queries/executors/engine.py +0 -221
- exonware/xwnode/queries/executors/errors.py +0 -68
- exonware/xwnode/queries/executors/filtering/__init__.py +0 -25
- exonware/xwnode/queries/executors/filtering/between_executor.py +0 -80
- exonware/xwnode/queries/executors/filtering/filter_executor.py +0 -79
- exonware/xwnode/queries/executors/filtering/has_executor.py +0 -70
- exonware/xwnode/queries/executors/filtering/in_executor.py +0 -70
- exonware/xwnode/queries/executors/filtering/like_executor.py +0 -76
- exonware/xwnode/queries/executors/filtering/optional_executor.py +0 -76
- exonware/xwnode/queries/executors/filtering/range_executor.py +0 -80
- exonware/xwnode/queries/executors/filtering/term_executor.py +0 -77
- exonware/xwnode/queries/executors/filtering/values_executor.py +0 -71
- exonware/xwnode/queries/executors/filtering/where_executor.py +0 -44
- exonware/xwnode/queries/executors/graph/__init__.py +0 -15
- exonware/xwnode/queries/executors/graph/in_traverse_executor.py +0 -51
- exonware/xwnode/queries/executors/graph/match_executor.py +0 -51
- exonware/xwnode/queries/executors/graph/out_executor.py +0 -51
- exonware/xwnode/queries/executors/graph/path_executor.py +0 -51
- exonware/xwnode/queries/executors/graph/return_executor.py +0 -51
- exonware/xwnode/queries/executors/ordering/__init__.py +0 -9
- exonware/xwnode/queries/executors/ordering/by_executor.py +0 -50
- exonware/xwnode/queries/executors/ordering/order_executor.py +0 -51
- exonware/xwnode/queries/executors/projection/__init__.py +0 -9
- exonware/xwnode/queries/executors/projection/extend_executor.py +0 -50
- exonware/xwnode/queries/executors/projection/project_executor.py +0 -50
- exonware/xwnode/queries/executors/registry.py +0 -173
- exonware/xwnode/queries/parsers/__init__.py +0 -26
- exonware/xwnode/queries/parsers/base.py +0 -86
- exonware/xwnode/queries/parsers/contracts.py +0 -46
- exonware/xwnode/queries/parsers/errors.py +0 -53
- exonware/xwnode/queries/parsers/sql_param_extractor.py +0 -318
- exonware/xwnode/queries/strategies/__init__.py +0 -24
- exonware/xwnode/queries/strategies/base.py +0 -236
- exonware/xwnode/queries/strategies/cql.py +0 -201
- exonware/xwnode/queries/strategies/cypher.py +0 -181
- exonware/xwnode/queries/strategies/datalog.py +0 -70
- exonware/xwnode/queries/strategies/elastic_dsl.py +0 -70
- exonware/xwnode/queries/strategies/eql.py +0 -70
- exonware/xwnode/queries/strategies/flux.py +0 -70
- exonware/xwnode/queries/strategies/gql.py +0 -70
- exonware/xwnode/queries/strategies/graphql.py +0 -240
- exonware/xwnode/queries/strategies/gremlin.py +0 -181
- exonware/xwnode/queries/strategies/hiveql.py +0 -214
- exonware/xwnode/queries/strategies/hql.py +0 -70
- exonware/xwnode/queries/strategies/jmespath.py +0 -219
- exonware/xwnode/queries/strategies/jq.py +0 -66
- exonware/xwnode/queries/strategies/json_query.py +0 -66
- exonware/xwnode/queries/strategies/jsoniq.py +0 -248
- exonware/xwnode/queries/strategies/kql.py +0 -70
- exonware/xwnode/queries/strategies/linq.py +0 -238
- exonware/xwnode/queries/strategies/logql.py +0 -70
- exonware/xwnode/queries/strategies/mql.py +0 -68
- exonware/xwnode/queries/strategies/n1ql.py +0 -210
- exonware/xwnode/queries/strategies/partiql.py +0 -70
- exonware/xwnode/queries/strategies/pig.py +0 -215
- exonware/xwnode/queries/strategies/promql.py +0 -70
- exonware/xwnode/queries/strategies/sparql.py +0 -220
- exonware/xwnode/queries/strategies/sql.py +0 -275
- exonware/xwnode/queries/strategies/xml_query.py +0 -66
- exonware/xwnode/queries/strategies/xpath.py +0 -223
- exonware/xwnode/queries/strategies/xquery.py +0 -258
- exonware/xwnode/queries/strategies/xwnode_executor.py +0 -332
- exonware/xwnode/queries/strategies/xwquery.py +0 -456
- exonware_xwnode-0.0.1.21.dist-info/RECORD +0 -214
- /exonware/xwnode/nodes/strategies/{node_ordered_map.py → ordered_map.py} +0 -0
- /exonware/xwnode/nodes/strategies/{node_ordered_map_balanced.py → ordered_map_balanced.py} +0 -0
- /exonware/xwnode/nodes/strategies/{node_patricia.py → patricia.py} +0 -0
- /exonware/xwnode/nodes/strategies/{node_radix_trie.py → radix_trie.py} +0 -0
- /exonware/xwnode/nodes/strategies/{node_set_tree.py → set_tree.py} +0 -0
- {exonware_xwnode-0.0.1.21.dist-info → exonware_xwnode-0.0.1.23.dist-info}/WHEEL +0 -0
- {exonware_xwnode-0.0.1.21.dist-info → exonware_xwnode-0.0.1.23.dist-info}/licenses/LICENSE +0 -0
@@ -1,201 +0,0 @@
|
|
1
|
-
#!/usr/bin/env python3
|
2
|
-
"""
|
3
|
-
CQL Query Strategy
|
4
|
-
|
5
|
-
This module implements the CQL query strategy for Cassandra Query Language operations.
|
6
|
-
|
7
|
-
Company: eXonware.com
|
8
|
-
Author: Eng. Muhammad AlShehri
|
9
|
-
Email: connect@exonware.com
|
10
|
-
Version: 0.0.1.21
|
11
|
-
Generation Date: January 2, 2025
|
12
|
-
"""
|
13
|
-
|
14
|
-
import re
|
15
|
-
from typing import Any, Dict, List, Optional, Union
|
16
|
-
from .base import AStructuredQueryStrategy
|
17
|
-
from ...errors import XWNodeTypeError, XWNodeValueError
|
18
|
-
from ...contracts import QueryMode, QueryTrait
|
19
|
-
|
20
|
-
|
21
|
-
class CQLStrategy(AStructuredQueryStrategy):
|
22
|
-
"""
|
23
|
-
CQL query strategy for Cassandra Query Language operations.
|
24
|
-
|
25
|
-
Supports:
|
26
|
-
- CQL 3.0+ features
|
27
|
-
- SELECT, INSERT, UPDATE, DELETE operations
|
28
|
-
- CREATE, DROP, ALTER operations
|
29
|
-
- Batch operations
|
30
|
-
- Time-to-live (TTL) operations
|
31
|
-
"""
|
32
|
-
|
33
|
-
def __init__(self, **options):
|
34
|
-
super().__init__(**options)
|
35
|
-
self._mode = QueryMode.CQL
|
36
|
-
self._traits = QueryTrait.STRUCTURED | QueryTrait.ANALYTICAL | QueryTrait.BATCH
|
37
|
-
|
38
|
-
def execute(self, query: str, **kwargs) -> Any:
|
39
|
-
"""Execute CQL query."""
|
40
|
-
if not self.validate_query(query):
|
41
|
-
raise XWNodeValueError(f"Invalid CQL query: {query}")
|
42
|
-
|
43
|
-
query_type = self._get_query_type(query)
|
44
|
-
|
45
|
-
if query_type == "SELECT":
|
46
|
-
return self._execute_select(query, **kwargs)
|
47
|
-
elif query_type == "INSERT":
|
48
|
-
return self._execute_insert(query, **kwargs)
|
49
|
-
elif query_type == "UPDATE":
|
50
|
-
return self._execute_update(query, **kwargs)
|
51
|
-
elif query_type == "DELETE":
|
52
|
-
return self._execute_delete(query, **kwargs)
|
53
|
-
else:
|
54
|
-
raise XWNodeValueError(f"Unsupported query type: {query_type}")
|
55
|
-
|
56
|
-
def validate_query(self, query: str) -> bool:
|
57
|
-
"""Validate CQL query syntax."""
|
58
|
-
if not query or not isinstance(query, str):
|
59
|
-
return False
|
60
|
-
|
61
|
-
# Basic CQL validation
|
62
|
-
query = query.strip().upper()
|
63
|
-
valid_operations = ["SELECT", "INSERT", "UPDATE", "DELETE", "CREATE", "DROP", "ALTER", "USE", "TRUNCATE", "BATCH", "GRANT", "REVOKE", "LIST", "DESCRIBE", "EXPLAIN"]
|
64
|
-
|
65
|
-
for operation in valid_operations:
|
66
|
-
if query.startswith(operation):
|
67
|
-
return True
|
68
|
-
|
69
|
-
return False
|
70
|
-
|
71
|
-
def get_query_plan(self, query: str) -> Dict[str, Any]:
|
72
|
-
"""Get CQL query execution plan."""
|
73
|
-
query_type = self._get_query_type(query)
|
74
|
-
|
75
|
-
return {
|
76
|
-
"query_type": query_type,
|
77
|
-
"operation": query_type,
|
78
|
-
"complexity": self._estimate_complexity(query),
|
79
|
-
"estimated_cost": self._estimate_cost(query),
|
80
|
-
"operations": self._extract_operations(query),
|
81
|
-
"optimization_hints": self._get_optimization_hints(query)
|
82
|
-
}
|
83
|
-
|
84
|
-
def select_query(self, table: str, columns: List[str], where_clause: str = None) -> Any:
|
85
|
-
"""Execute SELECT query."""
|
86
|
-
query = f"SELECT {', '.join(columns)} FROM {table}"
|
87
|
-
if where_clause:
|
88
|
-
query += f" WHERE {where_clause}"
|
89
|
-
|
90
|
-
return self.execute(query)
|
91
|
-
|
92
|
-
def insert_query(self, table: str, data: Dict[str, Any]) -> Any:
|
93
|
-
"""Execute INSERT query."""
|
94
|
-
columns = list(data.keys())
|
95
|
-
values = list(data.values())
|
96
|
-
|
97
|
-
query = f"INSERT INTO {table} ({', '.join(columns)}) VALUES ({', '.join(['?' for _ in values])})"
|
98
|
-
return self.execute(query, values=values)
|
99
|
-
|
100
|
-
def update_query(self, table: str, data: Dict[str, Any], where_clause: str = None) -> Any:
|
101
|
-
"""Execute UPDATE query."""
|
102
|
-
set_clause = ', '.join([f"{k} = ?" for k in data.keys()])
|
103
|
-
query = f"UPDATE {table} SET {set_clause}"
|
104
|
-
|
105
|
-
if where_clause:
|
106
|
-
query += f" WHERE {where_clause}"
|
107
|
-
|
108
|
-
return self.execute(query, values=list(data.values()))
|
109
|
-
|
110
|
-
def delete_query(self, table: str, where_clause: str = None) -> Any:
|
111
|
-
"""Execute DELETE query."""
|
112
|
-
query = f"DELETE FROM {table}"
|
113
|
-
if where_clause:
|
114
|
-
query += f" WHERE {where_clause}"
|
115
|
-
|
116
|
-
return self.execute(query)
|
117
|
-
|
118
|
-
def join_query(self, tables: List[str], join_conditions: List[str]) -> Any:
|
119
|
-
"""Execute JOIN query."""
|
120
|
-
# CQL doesn't support traditional JOINs, use denormalization
|
121
|
-
raise XWNodeValueError("CQL doesn't support JOIN operations. Use denormalization instead.")
|
122
|
-
|
123
|
-
def aggregate_query(self, table: str, functions: List[str], group_by: List[str] = None) -> Any:
|
124
|
-
"""Execute aggregate query."""
|
125
|
-
query = f"SELECT {', '.join(functions)} FROM {table}"
|
126
|
-
if group_by:
|
127
|
-
query += f" GROUP BY {', '.join(group_by)}"
|
128
|
-
|
129
|
-
return self.execute(query)
|
130
|
-
|
131
|
-
def _get_query_type(self, query: str) -> str:
|
132
|
-
"""Extract query type from CQL query."""
|
133
|
-
query = query.strip().upper()
|
134
|
-
for operation in ["SELECT", "INSERT", "UPDATE", "DELETE", "CREATE", "DROP", "ALTER", "USE", "TRUNCATE", "BATCH", "GRANT", "REVOKE", "LIST", "DESCRIBE", "EXPLAIN"]:
|
135
|
-
if query.startswith(operation):
|
136
|
-
return operation
|
137
|
-
return "UNKNOWN"
|
138
|
-
|
139
|
-
def _execute_select(self, query: str, **kwargs) -> Any:
|
140
|
-
"""Execute SELECT query."""
|
141
|
-
return {"result": "CQL SELECT executed", "query": query}
|
142
|
-
|
143
|
-
def _execute_insert(self, query: str, **kwargs) -> Any:
|
144
|
-
"""Execute INSERT query."""
|
145
|
-
return {"result": "CQL INSERT executed", "query": query}
|
146
|
-
|
147
|
-
def _execute_update(self, query: str, **kwargs) -> Any:
|
148
|
-
"""Execute UPDATE query."""
|
149
|
-
return {"result": "CQL UPDATE executed", "query": query}
|
150
|
-
|
151
|
-
def _execute_delete(self, query: str, **kwargs) -> Any:
|
152
|
-
"""Execute DELETE query."""
|
153
|
-
return {"result": "CQL DELETE executed", "query": query}
|
154
|
-
|
155
|
-
def _estimate_complexity(self, query: str) -> str:
|
156
|
-
"""Estimate query complexity."""
|
157
|
-
operations = self._extract_operations(query)
|
158
|
-
|
159
|
-
if len(operations) > 5:
|
160
|
-
return "HIGH"
|
161
|
-
elif len(operations) > 2:
|
162
|
-
return "MEDIUM"
|
163
|
-
else:
|
164
|
-
return "LOW"
|
165
|
-
|
166
|
-
def _estimate_cost(self, query: str) -> int:
|
167
|
-
"""Estimate query cost."""
|
168
|
-
complexity = self._estimate_complexity(query)
|
169
|
-
if complexity == "HIGH":
|
170
|
-
return 120
|
171
|
-
elif complexity == "MEDIUM":
|
172
|
-
return 60
|
173
|
-
else:
|
174
|
-
return 30
|
175
|
-
|
176
|
-
def _extract_operations(self, query: str) -> List[str]:
|
177
|
-
"""Extract CQL operations from query."""
|
178
|
-
operations = []
|
179
|
-
|
180
|
-
cql_operations = ["SELECT", "INSERT", "UPDATE", "DELETE", "CREATE", "DROP", "ALTER", "USE", "TRUNCATE", "BATCH", "GRANT", "REVOKE", "LIST", "DESCRIBE", "EXPLAIN"]
|
181
|
-
|
182
|
-
for operation in cql_operations:
|
183
|
-
if operation in query.upper():
|
184
|
-
operations.append(operation)
|
185
|
-
|
186
|
-
return operations
|
187
|
-
|
188
|
-
def _get_optimization_hints(self, query: str) -> List[str]:
|
189
|
-
"""Get query optimization hints."""
|
190
|
-
hints = []
|
191
|
-
|
192
|
-
if "SELECT *" in query.upper():
|
193
|
-
hints.append("Consider specifying columns instead of using *")
|
194
|
-
|
195
|
-
if "WHERE" not in query.upper() and "SELECT" in query.upper():
|
196
|
-
hints.append("Consider adding WHERE clause to limit results")
|
197
|
-
|
198
|
-
if "ORDER BY" in query.upper():
|
199
|
-
hints.append("Consider using clustering columns for ORDER BY operations")
|
200
|
-
|
201
|
-
return hints
|
@@ -1,181 +0,0 @@
|
|
1
|
-
#!/usr/bin/env python3
|
2
|
-
"""
|
3
|
-
Cypher Query Strategy
|
4
|
-
|
5
|
-
This module implements the Cypher query strategy for Neo4j graph queries.
|
6
|
-
|
7
|
-
Company: eXonware.com
|
8
|
-
Author: Eng. Muhammad AlShehri
|
9
|
-
Email: connect@exonware.com
|
10
|
-
Version: 0.0.1.21
|
11
|
-
Generation Date: January 2, 2025
|
12
|
-
"""
|
13
|
-
|
14
|
-
import re
|
15
|
-
from typing import Any, Dict, List, Optional, Union
|
16
|
-
from .base import AGraphQueryStrategy
|
17
|
-
from ...errors import XWNodeTypeError, XWNodeValueError
|
18
|
-
from ...contracts import QueryMode, QueryTrait
|
19
|
-
|
20
|
-
|
21
|
-
class CypherStrategy(AGraphQueryStrategy):
|
22
|
-
"""
|
23
|
-
Cypher query strategy for Neo4j graph queries.
|
24
|
-
|
25
|
-
Supports:
|
26
|
-
- Cypher query language
|
27
|
-
- MATCH, CREATE, MERGE, DELETE operations
|
28
|
-
- WHERE clauses and conditions
|
29
|
-
- RETURN and WITH clauses
|
30
|
-
- Path expressions and patterns
|
31
|
-
"""
|
32
|
-
|
33
|
-
def __init__(self, **options):
|
34
|
-
super().__init__(**options)
|
35
|
-
self._mode = QueryMode.CYPHER
|
36
|
-
self._traits = QueryTrait.GRAPH | QueryTrait.STRUCTURED | QueryTrait.ANALYTICAL
|
37
|
-
|
38
|
-
def execute(self, query: str, **kwargs) -> Any:
|
39
|
-
"""Execute Cypher query."""
|
40
|
-
if not self.validate_query(query):
|
41
|
-
raise XWNodeValueError(f"Invalid Cypher query: {query}")
|
42
|
-
|
43
|
-
query_type = self._get_query_type(query)
|
44
|
-
|
45
|
-
if query_type == "MATCH":
|
46
|
-
return self._execute_match(query, **kwargs)
|
47
|
-
elif query_type == "CREATE":
|
48
|
-
return self._execute_create(query, **kwargs)
|
49
|
-
elif query_type == "MERGE":
|
50
|
-
return self._execute_merge(query, **kwargs)
|
51
|
-
elif query_type == "DELETE":
|
52
|
-
return self._execute_delete(query, **kwargs)
|
53
|
-
else:
|
54
|
-
raise XWNodeValueError(f"Unsupported query type: {query_type}")
|
55
|
-
|
56
|
-
def validate_query(self, query: str) -> bool:
|
57
|
-
"""Validate Cypher query syntax."""
|
58
|
-
if not query or not isinstance(query, str):
|
59
|
-
return False
|
60
|
-
|
61
|
-
# Basic Cypher validation
|
62
|
-
query = query.strip().upper()
|
63
|
-
valid_operations = ["MATCH", "CREATE", "MERGE", "DELETE", "SET", "REMOVE", "RETURN", "WITH", "UNWIND", "CALL", "LOAD", "USING"]
|
64
|
-
|
65
|
-
for operation in valid_operations:
|
66
|
-
if query.startswith(operation):
|
67
|
-
return True
|
68
|
-
|
69
|
-
return False
|
70
|
-
|
71
|
-
def get_query_plan(self, query: str) -> Dict[str, Any]:
|
72
|
-
"""Get Cypher query execution plan."""
|
73
|
-
query_type = self._get_query_type(query)
|
74
|
-
|
75
|
-
return {
|
76
|
-
"query_type": query_type,
|
77
|
-
"operation": query_type,
|
78
|
-
"complexity": self._estimate_complexity(query),
|
79
|
-
"estimated_cost": self._estimate_cost(query),
|
80
|
-
"patterns": self._extract_patterns(query),
|
81
|
-
"optimization_hints": self._get_optimization_hints(query)
|
82
|
-
}
|
83
|
-
|
84
|
-
def path_query(self, start: Any, end: Any) -> List[Any]:
|
85
|
-
"""Execute path query."""
|
86
|
-
query = f"MATCH p = (start {{id: '{start}'}})-[*]->(end {{id: '{end}'}}) RETURN p"
|
87
|
-
return self.execute(query)
|
88
|
-
|
89
|
-
def neighbor_query(self, node: Any) -> List[Any]:
|
90
|
-
"""Execute neighbor query."""
|
91
|
-
query = f"MATCH (n {{id: '{node}'}})-[r]-(neighbor) RETURN neighbor"
|
92
|
-
return self.execute(query)
|
93
|
-
|
94
|
-
def shortest_path_query(self, start: Any, end: Any) -> List[Any]:
|
95
|
-
"""Execute shortest path query."""
|
96
|
-
query = f"MATCH p = shortestPath((start {{id: '{start}'}})-[*]->(end {{id: '{end}'}})) RETURN p"
|
97
|
-
return self.execute(query)
|
98
|
-
|
99
|
-
def connected_components_query(self) -> List[List[Any]]:
|
100
|
-
"""Execute connected components query."""
|
101
|
-
query = "MATCH (n) RETURN n, size((n)-[*]-()) as component_size"
|
102
|
-
return self.execute(query)
|
103
|
-
|
104
|
-
def cycle_detection_query(self) -> List[List[Any]]:
|
105
|
-
"""Execute cycle detection query."""
|
106
|
-
query = "MATCH p = (n)-[r*]->(n) RETURN p"
|
107
|
-
return self.execute(query)
|
108
|
-
|
109
|
-
def _get_query_type(self, query: str) -> str:
|
110
|
-
"""Extract query type from Cypher query."""
|
111
|
-
query = query.strip().upper()
|
112
|
-
for operation in ["MATCH", "CREATE", "MERGE", "DELETE", "SET", "REMOVE", "RETURN", "WITH", "UNWIND", "CALL", "LOAD", "USING"]:
|
113
|
-
if query.startswith(operation):
|
114
|
-
return operation
|
115
|
-
return "UNKNOWN"
|
116
|
-
|
117
|
-
def _execute_match(self, query: str, **kwargs) -> Any:
|
118
|
-
"""Execute MATCH query."""
|
119
|
-
return {"result": "Cypher MATCH executed", "query": query}
|
120
|
-
|
121
|
-
def _execute_create(self, query: str, **kwargs) -> Any:
|
122
|
-
"""Execute CREATE query."""
|
123
|
-
return {"result": "Cypher CREATE executed", "query": query}
|
124
|
-
|
125
|
-
def _execute_merge(self, query: str, **kwargs) -> Any:
|
126
|
-
"""Execute MERGE query."""
|
127
|
-
return {"result": "Cypher MERGE executed", "query": query}
|
128
|
-
|
129
|
-
def _execute_delete(self, query: str, **kwargs) -> Any:
|
130
|
-
"""Execute DELETE query."""
|
131
|
-
return {"result": "Cypher DELETE executed", "query": query}
|
132
|
-
|
133
|
-
def _estimate_complexity(self, query: str) -> str:
|
134
|
-
"""Estimate query complexity."""
|
135
|
-
patterns = self._extract_patterns(query)
|
136
|
-
|
137
|
-
if len(patterns) > 5:
|
138
|
-
return "HIGH"
|
139
|
-
elif len(patterns) > 2:
|
140
|
-
return "MEDIUM"
|
141
|
-
else:
|
142
|
-
return "LOW"
|
143
|
-
|
144
|
-
def _estimate_cost(self, query: str) -> int:
|
145
|
-
"""Estimate query cost."""
|
146
|
-
complexity = self._estimate_complexity(query)
|
147
|
-
if complexity == "HIGH":
|
148
|
-
return 160
|
149
|
-
elif complexity == "MEDIUM":
|
150
|
-
return 80
|
151
|
-
else:
|
152
|
-
return 40
|
153
|
-
|
154
|
-
def _extract_patterns(self, query: str) -> List[str]:
|
155
|
-
"""Extract Cypher patterns from query."""
|
156
|
-
patterns = []
|
157
|
-
|
158
|
-
# Look for node patterns
|
159
|
-
node_patterns = re.findall(r'\([^)]+\)', query)
|
160
|
-
patterns.extend(node_patterns)
|
161
|
-
|
162
|
-
# Look for relationship patterns
|
163
|
-
rel_patterns = re.findall(r'\[[^\]]+\]', query)
|
164
|
-
patterns.extend(rel_patterns)
|
165
|
-
|
166
|
-
return patterns
|
167
|
-
|
168
|
-
def _get_optimization_hints(self, query: str) -> List[str]:
|
169
|
-
"""Get query optimization hints."""
|
170
|
-
hints = []
|
171
|
-
|
172
|
-
if "MATCH" in query.upper() and "WHERE" not in query.upper():
|
173
|
-
hints.append("Consider adding WHERE clause to limit results")
|
174
|
-
|
175
|
-
if "shortestPath" in query:
|
176
|
-
hints.append("Consider using indexes for shortestPath operations")
|
177
|
-
|
178
|
-
if "RETURN *" in query.upper():
|
179
|
-
hints.append("Consider specifying specific properties instead of using *")
|
180
|
-
|
181
|
-
return hints
|
@@ -1,70 +0,0 @@
|
|
1
|
-
#!/usr/bin/env python3
|
2
|
-
"""
|
3
|
-
Datalog Query Strategy
|
4
|
-
|
5
|
-
This module implements the Datalog query strategy for Datalog operations.
|
6
|
-
|
7
|
-
Company: eXonware.com
|
8
|
-
Author: Eng. Muhammad AlShehri
|
9
|
-
Email: connect@exonware.com
|
10
|
-
Version: 0.0.1.21
|
11
|
-
Generation Date: January 2, 2025
|
12
|
-
"""
|
13
|
-
|
14
|
-
from typing import Any, Dict, List, Optional
|
15
|
-
from .base import AStructuredQueryStrategy
|
16
|
-
from ...errors import XWNodeValueError
|
17
|
-
from ...contracts import QueryMode, QueryTrait
|
18
|
-
|
19
|
-
|
20
|
-
class DatalogStrategy(AStructuredQueryStrategy):
|
21
|
-
"""Datalog query strategy for Datalog operations."""
|
22
|
-
|
23
|
-
def __init__(self, **options):
|
24
|
-
super().__init__(**options)
|
25
|
-
self._mode = QueryMode.DATALOG
|
26
|
-
self._traits = QueryTrait.STRUCTURED | QueryTrait.ANALYTICAL | QueryTrait.BATCH
|
27
|
-
|
28
|
-
def execute(self, query: str, **kwargs) -> Any:
|
29
|
-
"""Execute Datalog query."""
|
30
|
-
if not self.validate_query(query):
|
31
|
-
raise XWNodeValueError(f"Invalid Datalog query: {query}")
|
32
|
-
return {"result": "Datalog query executed", "query": query}
|
33
|
-
|
34
|
-
def validate_query(self, query: str) -> bool:
|
35
|
-
"""Validate Datalog query syntax."""
|
36
|
-
if not query or not isinstance(query, str):
|
37
|
-
return False
|
38
|
-
return any(op in query for op in [":-", "?", "!", "assert", "retract"])
|
39
|
-
|
40
|
-
def get_query_plan(self, query: str) -> Dict[str, Any]:
|
41
|
-
"""Get Datalog query execution plan."""
|
42
|
-
return {
|
43
|
-
"query_type": "Datalog",
|
44
|
-
"complexity": "HIGH",
|
45
|
-
"estimated_cost": 200
|
46
|
-
}
|
47
|
-
|
48
|
-
def select_query(self, table: str, columns: List[str], where_clause: str = None) -> Any:
|
49
|
-
"""Execute SELECT query."""
|
50
|
-
return self.execute(f"?- {table}({', '.join(columns)})")
|
51
|
-
|
52
|
-
def insert_query(self, table: str, data: Dict[str, Any]) -> Any:
|
53
|
-
"""Execute INSERT query."""
|
54
|
-
return self.execute(f"assert({table}({', '.join(data.values())}))")
|
55
|
-
|
56
|
-
def update_query(self, table: str, data: Dict[str, Any], where_clause: str = None) -> Any:
|
57
|
-
"""Execute UPDATE query."""
|
58
|
-
return self.execute(f"retract({table}({where_clause})), assert({table}({', '.join(data.values())}))")
|
59
|
-
|
60
|
-
def delete_query(self, table: str, where_clause: str = None) -> Any:
|
61
|
-
"""Execute DELETE query."""
|
62
|
-
return self.execute(f"retract({table}({where_clause}))")
|
63
|
-
|
64
|
-
def join_query(self, tables: List[str], join_conditions: List[str]) -> Any:
|
65
|
-
"""Execute JOIN query."""
|
66
|
-
return self.execute(f"?- {tables[0]}(X), {tables[1]}(X)")
|
67
|
-
|
68
|
-
def aggregate_query(self, table: str, functions: List[str], group_by: List[str] = None) -> Any:
|
69
|
-
"""Execute aggregate query."""
|
70
|
-
return self.execute(f"?- {table}(X), aggregate({functions[0]}, X)")
|
@@ -1,70 +0,0 @@
|
|
1
|
-
#!/usr/bin/env python3
|
2
|
-
"""
|
3
|
-
Elasticsearch DSL Query Strategy
|
4
|
-
|
5
|
-
This module implements the Elasticsearch DSL query strategy for Elasticsearch Query DSL operations.
|
6
|
-
|
7
|
-
Company: eXonware.com
|
8
|
-
Author: Eng. Muhammad AlShehri
|
9
|
-
Email: connect@exonware.com
|
10
|
-
Version: 0.0.1.21
|
11
|
-
Generation Date: January 2, 2025
|
12
|
-
"""
|
13
|
-
|
14
|
-
from typing import Any, Dict, List, Optional
|
15
|
-
from .base import AStructuredQueryStrategy
|
16
|
-
from ...errors import XWNodeValueError
|
17
|
-
from ...contracts import QueryMode, QueryTrait
|
18
|
-
|
19
|
-
|
20
|
-
class ElasticDSLStrategy(AStructuredQueryStrategy):
|
21
|
-
"""Elasticsearch DSL query strategy for Elasticsearch Query DSL operations."""
|
22
|
-
|
23
|
-
def __init__(self, **options):
|
24
|
-
super().__init__(**options)
|
25
|
-
self._mode = QueryMode.ELASTIC_DSL
|
26
|
-
self._traits = QueryTrait.STRUCTURED | QueryTrait.ANALYTICAL | QueryTrait.SEARCH
|
27
|
-
|
28
|
-
def execute(self, query: str, **kwargs) -> Any:
|
29
|
-
"""Execute Elasticsearch DSL query."""
|
30
|
-
if not self.validate_query(query):
|
31
|
-
raise XWNodeValueError(f"Invalid Elasticsearch DSL query: {query}")
|
32
|
-
return {"result": "Elasticsearch DSL query executed", "query": query}
|
33
|
-
|
34
|
-
def validate_query(self, query: str) -> bool:
|
35
|
-
"""Validate Elasticsearch DSL query syntax."""
|
36
|
-
if not query or not isinstance(query, str):
|
37
|
-
return False
|
38
|
-
return any(op in query for op in ["query", "match", "term", "bool", "filter", "must", "should"])
|
39
|
-
|
40
|
-
def get_query_plan(self, query: str) -> Dict[str, Any]:
|
41
|
-
"""Get Elasticsearch DSL query execution plan."""
|
42
|
-
return {
|
43
|
-
"query_type": "ELASTIC_DSL",
|
44
|
-
"complexity": "HIGH",
|
45
|
-
"estimated_cost": 120
|
46
|
-
}
|
47
|
-
|
48
|
-
def select_query(self, table: str, columns: List[str], where_clause: str = None) -> Any:
|
49
|
-
"""Execute SELECT query."""
|
50
|
-
return self.execute(f"GET /{table}/_search")
|
51
|
-
|
52
|
-
def insert_query(self, table: str, data: Dict[str, Any]) -> Any:
|
53
|
-
"""Execute INSERT query."""
|
54
|
-
return self.execute(f"POST /{table}/_doc")
|
55
|
-
|
56
|
-
def update_query(self, table: str, data: Dict[str, Any], where_clause: str = None) -> Any:
|
57
|
-
"""Execute UPDATE query."""
|
58
|
-
return self.execute(f"POST /{table}/_update_by_query")
|
59
|
-
|
60
|
-
def delete_query(self, table: str, where_clause: str = None) -> Any:
|
61
|
-
"""Execute DELETE query."""
|
62
|
-
return self.execute(f"POST /{table}/_delete_by_query")
|
63
|
-
|
64
|
-
def join_query(self, tables: List[str], join_conditions: List[str]) -> Any:
|
65
|
-
"""Execute JOIN query."""
|
66
|
-
return self.execute(f"GET /{tables[0]}/_search")
|
67
|
-
|
68
|
-
def aggregate_query(self, table: str, functions: List[str], group_by: List[str] = None) -> Any:
|
69
|
-
"""Execute aggregate query."""
|
70
|
-
return self.execute(f"GET /{table}/_search")
|
@@ -1,70 +0,0 @@
|
|
1
|
-
#!/usr/bin/env python3
|
2
|
-
"""
|
3
|
-
EQL Query Strategy
|
4
|
-
|
5
|
-
This module implements the EQL query strategy for Elasticsearch Query Language operations.
|
6
|
-
|
7
|
-
Company: eXonware.com
|
8
|
-
Author: Eng. Muhammad AlShehri
|
9
|
-
Email: connect@exonware.com
|
10
|
-
Version: 0.0.1.21
|
11
|
-
Generation Date: January 2, 2025
|
12
|
-
"""
|
13
|
-
|
14
|
-
from typing import Any, Dict, List, Optional
|
15
|
-
from .base import AStructuredQueryStrategy
|
16
|
-
from ...errors import XWNodeValueError
|
17
|
-
from ...contracts import QueryMode, QueryTrait
|
18
|
-
|
19
|
-
|
20
|
-
class EQLStrategy(AStructuredQueryStrategy):
|
21
|
-
"""EQL query strategy for Elasticsearch Query Language operations."""
|
22
|
-
|
23
|
-
def __init__(self, **options):
|
24
|
-
super().__init__(**options)
|
25
|
-
self._mode = QueryMode.EQL
|
26
|
-
self._traits = QueryTrait.STRUCTURED | QueryTrait.ANALYTICAL | QueryTrait.BATCH
|
27
|
-
|
28
|
-
def execute(self, query: str, **kwargs) -> Any:
|
29
|
-
"""Execute EQL query."""
|
30
|
-
if not self.validate_query(query):
|
31
|
-
raise XWNodeValueError(f"Invalid EQL query: {query}")
|
32
|
-
return {"result": "EQL query executed", "query": query}
|
33
|
-
|
34
|
-
def validate_query(self, query: str) -> bool:
|
35
|
-
"""Validate EQL query syntax."""
|
36
|
-
if not query or not isinstance(query, str):
|
37
|
-
return False
|
38
|
-
return any(op in query.upper() for op in ["SEQUENCE", "JOIN", "FILTER", "WHERE"])
|
39
|
-
|
40
|
-
def get_query_plan(self, query: str) -> Dict[str, Any]:
|
41
|
-
"""Get EQL query execution plan."""
|
42
|
-
return {
|
43
|
-
"query_type": "EQL",
|
44
|
-
"complexity": "MEDIUM",
|
45
|
-
"estimated_cost": 100
|
46
|
-
}
|
47
|
-
|
48
|
-
def select_query(self, table: str, columns: List[str], where_clause: str = None) -> Any:
|
49
|
-
"""Execute SELECT query."""
|
50
|
-
return self.execute(f"SELECT {', '.join(columns)} FROM {table}")
|
51
|
-
|
52
|
-
def insert_query(self, table: str, data: Dict[str, Any]) -> Any:
|
53
|
-
"""Execute INSERT query."""
|
54
|
-
return self.execute(f"INSERT INTO {table} VALUES {data}")
|
55
|
-
|
56
|
-
def update_query(self, table: str, data: Dict[str, Any], where_clause: str = None) -> Any:
|
57
|
-
"""Execute UPDATE query."""
|
58
|
-
return self.execute(f"UPDATE {table} SET {data}")
|
59
|
-
|
60
|
-
def delete_query(self, table: str, where_clause: str = None) -> Any:
|
61
|
-
"""Execute DELETE query."""
|
62
|
-
return self.execute(f"DELETE FROM {table}")
|
63
|
-
|
64
|
-
def join_query(self, tables: List[str], join_conditions: List[str]) -> Any:
|
65
|
-
"""Execute JOIN query."""
|
66
|
-
return self.execute(f"JOIN {tables[0]} WITH {tables[1]}")
|
67
|
-
|
68
|
-
def aggregate_query(self, table: str, functions: List[str], group_by: List[str] = None) -> Any:
|
69
|
-
"""Execute aggregate query."""
|
70
|
-
return self.execute(f"AGGREGATE {', '.join(functions)} FROM {table}")
|
@@ -1,70 +0,0 @@
|
|
1
|
-
#!/usr/bin/env python3
|
2
|
-
"""
|
3
|
-
Flux Query Strategy
|
4
|
-
|
5
|
-
This module implements the Flux query strategy for InfluxDB Flux operations.
|
6
|
-
|
7
|
-
Company: eXonware.com
|
8
|
-
Author: Eng. Muhammad AlShehri
|
9
|
-
Email: connect@exonware.com
|
10
|
-
Version: 0.0.1.21
|
11
|
-
Generation Date: January 2, 2025
|
12
|
-
"""
|
13
|
-
|
14
|
-
from typing import Any, Dict, List, Optional
|
15
|
-
from .base import AStructuredQueryStrategy
|
16
|
-
from ...errors import XWNodeValueError
|
17
|
-
from ...contracts import QueryMode, QueryTrait
|
18
|
-
|
19
|
-
|
20
|
-
class FluxStrategy(AStructuredQueryStrategy):
|
21
|
-
"""Flux query strategy for InfluxDB Flux operations."""
|
22
|
-
|
23
|
-
def __init__(self, **options):
|
24
|
-
super().__init__(**options)
|
25
|
-
self._mode = QueryMode.FLUX
|
26
|
-
self._traits = QueryTrait.STRUCTURED | QueryTrait.ANALYTICAL | QueryTrait.BATCH
|
27
|
-
|
28
|
-
def execute(self, query: str, **kwargs) -> Any:
|
29
|
-
"""Execute Flux query."""
|
30
|
-
if not self.validate_query(query):
|
31
|
-
raise XWNodeValueError(f"Invalid Flux query: {query}")
|
32
|
-
return {"result": "Flux query executed", "query": query}
|
33
|
-
|
34
|
-
def validate_query(self, query: str) -> bool:
|
35
|
-
"""Validate Flux query syntax."""
|
36
|
-
if not query or not isinstance(query, str):
|
37
|
-
return False
|
38
|
-
return any(op in query for op in ["from", "range", "filter", "aggregate", "yield"])
|
39
|
-
|
40
|
-
def get_query_plan(self, query: str) -> Dict[str, Any]:
|
41
|
-
"""Get Flux query execution plan."""
|
42
|
-
return {
|
43
|
-
"query_type": "Flux",
|
44
|
-
"complexity": "MEDIUM",
|
45
|
-
"estimated_cost": 110
|
46
|
-
}
|
47
|
-
|
48
|
-
def select_query(self, table: str, columns: List[str], where_clause: str = None) -> Any:
|
49
|
-
"""Execute SELECT query."""
|
50
|
-
return self.execute(f"from(bucket: \"{table}\") | filter(fn: (r) => r._field =~ /{columns[0]}/)")
|
51
|
-
|
52
|
-
def insert_query(self, table: str, data: Dict[str, Any]) -> Any:
|
53
|
-
"""Execute INSERT query."""
|
54
|
-
return self.execute(f"INSERT INTO {table} VALUES {data}")
|
55
|
-
|
56
|
-
def update_query(self, table: str, data: Dict[str, Any], where_clause: str = None) -> Any:
|
57
|
-
"""Execute UPDATE query."""
|
58
|
-
return self.execute(f"UPDATE {table} SET {data}")
|
59
|
-
|
60
|
-
def delete_query(self, table: str, where_clause: str = None) -> Any:
|
61
|
-
"""Execute DELETE query."""
|
62
|
-
return self.execute(f"DELETE FROM {table}")
|
63
|
-
|
64
|
-
def join_query(self, tables: List[str], join_conditions: List[str]) -> Any:
|
65
|
-
"""Execute JOIN query."""
|
66
|
-
return self.execute(f"join(tables: {{t1: {tables[0]}, t2: {tables[1]}}})")
|
67
|
-
|
68
|
-
def aggregate_query(self, table: str, functions: List[str], group_by: List[str] = None) -> Any:
|
69
|
-
"""Execute aggregate query."""
|
70
|
-
return self.execute(f"from(bucket: \"{table}\") | aggregateWindow(every: 1m, fn: {functions[0]})")
|