exonware-xwnode 0.0.1.12__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 (132) hide show
  1. exonware/__init__.py +14 -0
  2. exonware/xwnode/__init__.py +127 -0
  3. exonware/xwnode/base.py +676 -0
  4. exonware/xwnode/config.py +178 -0
  5. exonware/xwnode/contracts.py +730 -0
  6. exonware/xwnode/errors.py +503 -0
  7. exonware/xwnode/facade.py +460 -0
  8. exonware/xwnode/strategies/__init__.py +158 -0
  9. exonware/xwnode/strategies/advisor.py +463 -0
  10. exonware/xwnode/strategies/edges/__init__.py +32 -0
  11. exonware/xwnode/strategies/edges/adj_list.py +227 -0
  12. exonware/xwnode/strategies/edges/adj_matrix.py +391 -0
  13. exonware/xwnode/strategies/edges/base.py +169 -0
  14. exonware/xwnode/strategies/flyweight.py +328 -0
  15. exonware/xwnode/strategies/impls/__init__.py +13 -0
  16. exonware/xwnode/strategies/impls/_base_edge.py +403 -0
  17. exonware/xwnode/strategies/impls/_base_node.py +307 -0
  18. exonware/xwnode/strategies/impls/edge_adj_list.py +353 -0
  19. exonware/xwnode/strategies/impls/edge_adj_matrix.py +445 -0
  20. exonware/xwnode/strategies/impls/edge_bidir_wrapper.py +455 -0
  21. exonware/xwnode/strategies/impls/edge_block_adj_matrix.py +539 -0
  22. exonware/xwnode/strategies/impls/edge_coo.py +533 -0
  23. exonware/xwnode/strategies/impls/edge_csc.py +447 -0
  24. exonware/xwnode/strategies/impls/edge_csr.py +492 -0
  25. exonware/xwnode/strategies/impls/edge_dynamic_adj_list.py +503 -0
  26. exonware/xwnode/strategies/impls/edge_flow_network.py +555 -0
  27. exonware/xwnode/strategies/impls/edge_hyperedge_set.py +516 -0
  28. exonware/xwnode/strategies/impls/edge_neural_graph.py +650 -0
  29. exonware/xwnode/strategies/impls/edge_octree.py +574 -0
  30. exonware/xwnode/strategies/impls/edge_property_store.py +655 -0
  31. exonware/xwnode/strategies/impls/edge_quadtree.py +519 -0
  32. exonware/xwnode/strategies/impls/edge_rtree.py +820 -0
  33. exonware/xwnode/strategies/impls/edge_temporal_edgeset.py +558 -0
  34. exonware/xwnode/strategies/impls/edge_tree_graph_basic.py +271 -0
  35. exonware/xwnode/strategies/impls/edge_weighted_graph.py +411 -0
  36. exonware/xwnode/strategies/manager.py +775 -0
  37. exonware/xwnode/strategies/metrics.py +538 -0
  38. exonware/xwnode/strategies/migration.py +432 -0
  39. exonware/xwnode/strategies/nodes/__init__.py +50 -0
  40. exonware/xwnode/strategies/nodes/_base_node.py +307 -0
  41. exonware/xwnode/strategies/nodes/adjacency_list.py +267 -0
  42. exonware/xwnode/strategies/nodes/aho_corasick.py +345 -0
  43. exonware/xwnode/strategies/nodes/array_list.py +209 -0
  44. exonware/xwnode/strategies/nodes/base.py +247 -0
  45. exonware/xwnode/strategies/nodes/deque.py +200 -0
  46. exonware/xwnode/strategies/nodes/hash_map.py +135 -0
  47. exonware/xwnode/strategies/nodes/heap.py +307 -0
  48. exonware/xwnode/strategies/nodes/linked_list.py +232 -0
  49. exonware/xwnode/strategies/nodes/node_aho_corasick.py +520 -0
  50. exonware/xwnode/strategies/nodes/node_array_list.py +175 -0
  51. exonware/xwnode/strategies/nodes/node_avl_tree.py +371 -0
  52. exonware/xwnode/strategies/nodes/node_b_plus_tree.py +542 -0
  53. exonware/xwnode/strategies/nodes/node_bitmap.py +420 -0
  54. exonware/xwnode/strategies/nodes/node_bitset_dynamic.py +513 -0
  55. exonware/xwnode/strategies/nodes/node_bloom_filter.py +347 -0
  56. exonware/xwnode/strategies/nodes/node_btree.py +357 -0
  57. exonware/xwnode/strategies/nodes/node_count_min_sketch.py +470 -0
  58. exonware/xwnode/strategies/nodes/node_cow_tree.py +473 -0
  59. exonware/xwnode/strategies/nodes/node_cuckoo_hash.py +392 -0
  60. exonware/xwnode/strategies/nodes/node_fenwick_tree.py +301 -0
  61. exonware/xwnode/strategies/nodes/node_hash_map.py +269 -0
  62. exonware/xwnode/strategies/nodes/node_heap.py +191 -0
  63. exonware/xwnode/strategies/nodes/node_hyperloglog.py +407 -0
  64. exonware/xwnode/strategies/nodes/node_linked_list.py +409 -0
  65. exonware/xwnode/strategies/nodes/node_lsm_tree.py +400 -0
  66. exonware/xwnode/strategies/nodes/node_ordered_map.py +390 -0
  67. exonware/xwnode/strategies/nodes/node_ordered_map_balanced.py +565 -0
  68. exonware/xwnode/strategies/nodes/node_patricia.py +512 -0
  69. exonware/xwnode/strategies/nodes/node_persistent_tree.py +378 -0
  70. exonware/xwnode/strategies/nodes/node_radix_trie.py +452 -0
  71. exonware/xwnode/strategies/nodes/node_red_black_tree.py +497 -0
  72. exonware/xwnode/strategies/nodes/node_roaring_bitmap.py +570 -0
  73. exonware/xwnode/strategies/nodes/node_segment_tree.py +289 -0
  74. exonware/xwnode/strategies/nodes/node_set_hash.py +354 -0
  75. exonware/xwnode/strategies/nodes/node_set_tree.py +480 -0
  76. exonware/xwnode/strategies/nodes/node_skip_list.py +316 -0
  77. exonware/xwnode/strategies/nodes/node_splay_tree.py +393 -0
  78. exonware/xwnode/strategies/nodes/node_suffix_array.py +487 -0
  79. exonware/xwnode/strategies/nodes/node_treap.py +387 -0
  80. exonware/xwnode/strategies/nodes/node_tree_graph_hybrid.py +1434 -0
  81. exonware/xwnode/strategies/nodes/node_trie.py +252 -0
  82. exonware/xwnode/strategies/nodes/node_union_find.py +187 -0
  83. exonware/xwnode/strategies/nodes/node_xdata_optimized.py +369 -0
  84. exonware/xwnode/strategies/nodes/priority_queue.py +209 -0
  85. exonware/xwnode/strategies/nodes/queue.py +161 -0
  86. exonware/xwnode/strategies/nodes/sparse_matrix.py +206 -0
  87. exonware/xwnode/strategies/nodes/stack.py +152 -0
  88. exonware/xwnode/strategies/nodes/trie.py +274 -0
  89. exonware/xwnode/strategies/nodes/union_find.py +283 -0
  90. exonware/xwnode/strategies/pattern_detector.py +603 -0
  91. exonware/xwnode/strategies/performance_monitor.py +487 -0
  92. exonware/xwnode/strategies/queries/__init__.py +24 -0
  93. exonware/xwnode/strategies/queries/base.py +236 -0
  94. exonware/xwnode/strategies/queries/cql.py +201 -0
  95. exonware/xwnode/strategies/queries/cypher.py +181 -0
  96. exonware/xwnode/strategies/queries/datalog.py +70 -0
  97. exonware/xwnode/strategies/queries/elastic_dsl.py +70 -0
  98. exonware/xwnode/strategies/queries/eql.py +70 -0
  99. exonware/xwnode/strategies/queries/flux.py +70 -0
  100. exonware/xwnode/strategies/queries/gql.py +70 -0
  101. exonware/xwnode/strategies/queries/graphql.py +240 -0
  102. exonware/xwnode/strategies/queries/gremlin.py +181 -0
  103. exonware/xwnode/strategies/queries/hiveql.py +214 -0
  104. exonware/xwnode/strategies/queries/hql.py +70 -0
  105. exonware/xwnode/strategies/queries/jmespath.py +219 -0
  106. exonware/xwnode/strategies/queries/jq.py +66 -0
  107. exonware/xwnode/strategies/queries/json_query.py +66 -0
  108. exonware/xwnode/strategies/queries/jsoniq.py +248 -0
  109. exonware/xwnode/strategies/queries/kql.py +70 -0
  110. exonware/xwnode/strategies/queries/linq.py +238 -0
  111. exonware/xwnode/strategies/queries/logql.py +70 -0
  112. exonware/xwnode/strategies/queries/mql.py +68 -0
  113. exonware/xwnode/strategies/queries/n1ql.py +210 -0
  114. exonware/xwnode/strategies/queries/partiql.py +70 -0
  115. exonware/xwnode/strategies/queries/pig.py +215 -0
  116. exonware/xwnode/strategies/queries/promql.py +70 -0
  117. exonware/xwnode/strategies/queries/sparql.py +220 -0
  118. exonware/xwnode/strategies/queries/sql.py +275 -0
  119. exonware/xwnode/strategies/queries/xml_query.py +66 -0
  120. exonware/xwnode/strategies/queries/xpath.py +223 -0
  121. exonware/xwnode/strategies/queries/xquery.py +258 -0
  122. exonware/xwnode/strategies/queries/xwnode_executor.py +332 -0
  123. exonware/xwnode/strategies/queries/xwquery_strategy.py +424 -0
  124. exonware/xwnode/strategies/registry.py +604 -0
  125. exonware/xwnode/strategies/simple.py +273 -0
  126. exonware/xwnode/strategies/utils.py +532 -0
  127. exonware/xwnode/types.py +912 -0
  128. exonware/xwnode/version.py +78 -0
  129. exonware_xwnode-0.0.1.12.dist-info/METADATA +169 -0
  130. exonware_xwnode-0.0.1.12.dist-info/RECORD +132 -0
  131. exonware_xwnode-0.0.1.12.dist-info/WHEEL +4 -0
  132. exonware_xwnode-0.0.1.12.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,236 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Query Strategy Base Classes
4
+
5
+ This module defines the abstract base classes for all query strategy implementations:
6
+ - AQueryStrategy: Base strategy for all query implementations
7
+
8
+ Company: eXonware.com
9
+ Author: Eng. Muhammad AlShehri
10
+ Email: connect@exonware.com
11
+ Version: 0.0.1.12
12
+ Generation Date: January 2, 2025
13
+ """
14
+
15
+ from abc import ABC, abstractmethod
16
+ from typing import Any, Optional, List, Dict, Union, Type
17
+ from datetime import datetime
18
+
19
+ from ...contracts import iQuery, iQueryResult, IQueryStrategy, QueryMode, QueryTrait
20
+ from ...errors import XWNodeTypeError, XWNodeValueError
21
+ from ...base import XWNodeBase
22
+
23
+
24
+ class AQueryStrategy(IQueryStrategy):
25
+ """Base strategy for all query implementations with XWQuery Script support."""
26
+
27
+ def __init__(self, **options):
28
+ """Initialize query strategy."""
29
+ self._options = options
30
+ self._mode = options.get('mode', QueryMode.AUTO)
31
+ self._traits = options.get('traits', QueryTrait.NONE)
32
+
33
+ @abstractmethod
34
+ def execute(self, query: str, **kwargs) -> Any:
35
+ """Execute query."""
36
+ pass
37
+
38
+ @abstractmethod
39
+ def validate_query(self, query: str) -> bool:
40
+ """Validate query syntax."""
41
+ pass
42
+
43
+ @abstractmethod
44
+ def get_query_plan(self, query: str) -> Dict[str, Any]:
45
+ """Get query execution plan."""
46
+ pass
47
+
48
+ def get_mode(self) -> QueryMode:
49
+ """Get strategy mode."""
50
+ return self._mode
51
+
52
+ def get_traits(self) -> QueryTrait:
53
+ """Get strategy traits."""
54
+ return self._traits
55
+
56
+ def to_native(self) -> 'XWQueryScriptStrategy':
57
+ """Convert this strategy to XWQueryScriptStrategy using actions."""
58
+ from .xwquery_strategy import XWQueryScriptStrategy
59
+ return XWQueryScriptStrategy()
60
+
61
+ def to_actions_tree(self, query: str) -> XWNodeBase:
62
+ """Convert query to actions tree - default implementation."""
63
+ script_strategy = self.to_native().from_format(query, self.get_query_type())
64
+ return script_strategy.get_actions_tree()
65
+
66
+ def from_actions_tree(self, actions_tree: XWNodeBase) -> str:
67
+ """Convert actions tree to query - default implementation."""
68
+ script_strategy = self.to_native()
69
+ script_strategy._actions_tree = actions_tree
70
+ return script_strategy.to_format(self.get_query_type())
71
+
72
+ def get_query_type(self) -> str:
73
+ """Get the query type for this strategy."""
74
+ return self.__class__.__name__.replace('Strategy', '').upper()
75
+
76
+
77
+ class AQueryActionExecutor(AQueryStrategy):
78
+ """Abstract base for query action executors with XWQuery Script support."""
79
+
80
+ @abstractmethod
81
+ def execute_query(self, query: str, query_type: str, **kwargs) -> Any:
82
+ """Execute a query on this backend."""
83
+ pass
84
+
85
+ @abstractmethod
86
+ def validate_query(self, query: str, query_type: str) -> bool:
87
+ """Validate if this backend can handle the query."""
88
+ pass
89
+
90
+ @abstractmethod
91
+ def get_supported_query_types(self) -> List[str]:
92
+ """Get list of query types this backend supports."""
93
+ pass
94
+
95
+ def to_native(self) -> 'XWQueryScriptStrategy':
96
+ """Convert this executor to XWQueryScriptStrategy using actions."""
97
+ from .xwquery_strategy import XWQueryScriptStrategy
98
+ return XWQueryScriptStrategy()
99
+
100
+ def to_actions_tree(self, query: str) -> XWNodeBase:
101
+ """Convert query to actions tree - default implementation."""
102
+ script_strategy = self.to_native().from_format(query, self.get_query_type())
103
+ return script_strategy.get_actions_tree()
104
+
105
+ def from_actions_tree(self, actions_tree: XWNodeBase) -> str:
106
+ """Convert actions tree to query - default implementation."""
107
+ script_strategy = self.to_native()
108
+ script_strategy._actions_tree = actions_tree
109
+ return script_strategy.to_format(self.get_query_type())
110
+
111
+
112
+ class ALinearQueryStrategy(AQueryStrategy):
113
+ """Linear query capabilities."""
114
+
115
+ def find_by_index(self, index: int) -> Any:
116
+ """Find element by index."""
117
+ raise NotImplementedError("Subclasses must implement find_by_index")
118
+
119
+ def find_by_value(self, value: Any) -> List[int]:
120
+ """Find indices by value."""
121
+ raise NotImplementedError("Subclasses must implement find_by_value")
122
+
123
+ def range_query(self, start_index: int, end_index: int) -> List[Any]:
124
+ """Query range of indices."""
125
+ raise NotImplementedError("Subclasses must implement range_query")
126
+
127
+ def count_occurrences(self, value: Any) -> int:
128
+ """Count occurrences of value."""
129
+ raise NotImplementedError("Subclasses must implement count_occurrences")
130
+
131
+
132
+ class ATreeQueryStrategy(AQueryStrategy):
133
+ """Tree query capabilities."""
134
+
135
+ def find_by_key(self, key: Any) -> Any:
136
+ """Find by key."""
137
+ raise NotImplementedError("Subclasses must implement find_by_key")
138
+
139
+ def range_query(self, start_key: Any, end_key: Any) -> List[Any]:
140
+ """Range query."""
141
+ raise NotImplementedError("Subclasses must implement range_query")
142
+
143
+ def prefix_query(self, prefix: str) -> List[Any]:
144
+ """Find all keys with prefix."""
145
+ raise NotImplementedError("Subclasses must implement prefix_query")
146
+
147
+ def suffix_query(self, suffix: str) -> List[Any]:
148
+ """Find all keys with suffix."""
149
+ raise NotImplementedError("Subclasses must implement suffix_query")
150
+
151
+
152
+ class AGraphQueryStrategy(AQueryStrategy):
153
+ """Graph query capabilities."""
154
+
155
+ def path_query(self, start: Any, end: Any) -> List[Any]:
156
+ """Path query."""
157
+ raise NotImplementedError("Subclasses must implement path_query")
158
+
159
+ def neighbor_query(self, node: Any) -> List[Any]:
160
+ """Neighbor query."""
161
+ raise NotImplementedError("Subclasses must implement neighbor_query")
162
+
163
+ def shortest_path_query(self, start: Any, end: Any) -> List[Any]:
164
+ """Shortest path query."""
165
+ raise NotImplementedError("Subclasses must implement shortest_path_query")
166
+
167
+ def connected_components_query(self) -> List[List[Any]]:
168
+ """Connected components query."""
169
+ raise NotImplementedError("Subclasses must implement connected_components_query")
170
+
171
+ def cycle_detection_query(self) -> List[List[Any]]:
172
+ """Cycle detection query."""
173
+ raise NotImplementedError("Subclasses must implement cycle_detection_query")
174
+
175
+
176
+ class AStructuredQueryStrategy(AQueryStrategy):
177
+ """Structured query capabilities for SQL-like languages."""
178
+
179
+ @abstractmethod
180
+ def select_query(self, table: str, columns: List[str], where_clause: str = None) -> Any:
181
+ """Execute SELECT query."""
182
+ pass
183
+
184
+ @abstractmethod
185
+ def insert_query(self, table: str, data: Dict[str, Any]) -> Any:
186
+ """Execute INSERT query."""
187
+ pass
188
+
189
+ @abstractmethod
190
+ def update_query(self, table: str, data: Dict[str, Any], where_clause: str = None) -> Any:
191
+ """Execute UPDATE query."""
192
+ pass
193
+
194
+ @abstractmethod
195
+ def delete_query(self, table: str, where_clause: str = None) -> Any:
196
+ """Execute DELETE query."""
197
+ pass
198
+
199
+ @abstractmethod
200
+ def join_query(self, tables: List[str], join_conditions: List[str]) -> Any:
201
+ """Execute JOIN query."""
202
+ pass
203
+
204
+ @abstractmethod
205
+ def aggregate_query(self, table: str, functions: List[str], group_by: List[str] = None) -> Any:
206
+ """Execute aggregate query."""
207
+ pass
208
+
209
+
210
+ class ADocumentQueryStrategy(AQueryStrategy):
211
+ """Document query capabilities for JSON/XML-like languages."""
212
+
213
+ @abstractmethod
214
+ def path_query(self, path: str) -> Any:
215
+ """Execute path-based query."""
216
+ pass
217
+
218
+ @abstractmethod
219
+ def filter_query(self, filter_expression: str) -> Any:
220
+ """Execute filter query."""
221
+ pass
222
+
223
+ @abstractmethod
224
+ def projection_query(self, fields: List[str]) -> Any:
225
+ """Execute projection query."""
226
+ pass
227
+
228
+ @abstractmethod
229
+ def sort_query(self, sort_fields: List[str], order: str = "asc") -> Any:
230
+ """Execute sort query."""
231
+ pass
232
+
233
+ @abstractmethod
234
+ def limit_query(self, limit: int, offset: int = 0) -> Any:
235
+ """Execute limit query."""
236
+ pass
@@ -0,0 +1,201 @@
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.12
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
@@ -0,0 +1,181 @@
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.12
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
@@ -0,0 +1,70 @@
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.12
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)")