1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3use std::time::Duration;
4
5#[derive(Debug, Clone, PartialEq)]
7pub struct InternalQuery {
8 pub operation: QueryOperation,
9 pub sources: Vec<DataSource>,
10 pub projections: Vec<Column>,
11 pub predicates: Vec<Predicate>,
12 pub joins: Vec<Join>,
13 pub ordering: Option<OrderBy>,
14 pub limit: Option<u64>,
15}
16
17#[derive(Debug, Clone, PartialEq)]
19pub enum QueryOperation {
20 Select,
21 Insert,
22 Update,
23 Delete,
24}
25
26#[derive(Debug, Clone, PartialEq)]
28pub struct DataSource {
29 pub object_type: String, pub identifier: String, pub alias: Option<String>,
32}
33
34#[derive(Debug, Clone, PartialEq)]
36pub struct Column {
37 pub name: String,
38 pub alias: Option<String>,
39 pub source: Option<String>, }
41
42#[derive(Debug, Clone, PartialEq)]
44pub struct Predicate {
45 pub column: String,
46 pub operator: PredicateOperator,
47 pub value: PredicateValue,
48}
49
50#[derive(Debug, Clone, PartialEq)]
52pub enum PredicateOperator {
53 Equal,
54 NotEqual,
55 GreaterThan,
56 GreaterThanOrEqual,
57 LessThan,
58 LessThanOrEqual,
59 Like,
60 In,
61 IsNull,
62 IsNotNull,
63}
64
65#[derive(Debug, Clone, PartialEq)]
67pub enum PredicateValue {
68 String(String),
69 Number(f64),
70 Integer(i64),
71 Boolean(bool),
72 Null,
73 List(Vec<PredicateValue>),
74}
75
76#[derive(Debug, Clone, PartialEq)]
78pub struct Join {
79 pub join_type: JoinType,
80 pub left_source: String,
81 pub right_source: String,
82 pub on_condition: Vec<JoinCondition>,
83}
84
85#[derive(Debug, Clone, PartialEq)]
87pub enum JoinType {
88 Inner,
89 Left,
90 Right,
91 Full,
92}
93
94#[derive(Debug, Clone, PartialEq)]
96pub struct JoinCondition {
97 pub left_column: String,
98 pub right_column: String,
99}
100
101#[derive(Debug, Clone, PartialEq)]
103pub struct OrderBy {
104 pub columns: Vec<OrderColumn>,
105}
106
107#[derive(Debug, Clone, PartialEq)]
109pub struct OrderColumn {
110 pub column: String,
111 pub direction: OrderDirection,
112}
113
114#[derive(Debug, Clone, PartialEq)]
116pub enum OrderDirection {
117 Ascending,
118 Descending,
119}
120
121#[derive(Debug, Clone)]
123pub struct QueryResult {
124 pub columns: Vec<ColumnMetadata>,
125 pub rows: Vec<Row>,
126 pub affected_rows: Option<u64>,
127 pub execution_time: Duration,
128}
129
130#[derive(Debug, Clone, PartialEq)]
132pub struct ColumnMetadata {
133 pub name: String,
134 pub data_type: DataType,
135 pub nullable: bool,
136}
137
138#[derive(Debug, Clone, PartialEq)]
140pub enum DataType {
141 Text,
142 Integer,
143 Float,
144 Boolean,
145 Date,
146 DateTime,
147 Json,
148 Binary,
149}
150
151#[derive(Debug, Clone)]
153pub struct Row {
154 pub values: Vec<Value>,
155}
156
157#[derive(Debug, Clone, PartialEq)]
159pub enum Value {
160 Text(String),
161 Integer(i64),
162 Float(f64),
163 Boolean(bool),
164 Date(String), DateTime(String), Json(String),
167 Binary(Vec<u8>),
168 Null,
169}
170
171#[derive(Debug, Clone)]
173pub struct Schema {
174 pub name: String,
175 pub columns: Vec<ColumnMetadata>,
176 pub primary_key: Option<Vec<String>>,
177 pub indexes: Vec<Index>,
178}
179
180#[derive(Debug, Clone)]
182pub struct Index {
183 pub name: String,
184 pub columns: Vec<String>,
185 pub unique: bool,
186}
187
188#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
190pub enum ConnectorType {
191 Mock,
192 PostgreSQL,
193 MySQL,
194 SQLite,
195 SqlServer,
196 File,
197 Rest,
198 LLM,
199 Custom(String),
200}
201
202#[derive(Debug, Clone)]
204pub struct ConnectorQuery {
205 pub connector_type: ConnectorType,
206 pub query: InternalQuery,
207 pub connection_params: HashMap<String, String>,
208}
209
210impl InternalQuery {
211 pub fn new(operation: QueryOperation) -> Self {
213 Self {
214 operation,
215 sources: Vec::new(),
216 projections: Vec::new(),
217 predicates: Vec::new(),
218 joins: Vec::new(),
219 ordering: None,
220 limit: None,
221 }
222 }
223}
224
225impl QueryResult {
226 pub fn new() -> Self {
228 Self {
229 columns: Vec::new(),
230 rows: Vec::new(),
231 affected_rows: None,
232 execution_time: Duration::from_millis(0),
233 }
234 }
235
236 pub fn row_count(&self) -> usize {
238 self.rows.len()
239 }
240
241 pub fn is_empty(&self) -> bool {
243 self.rows.is_empty()
244 }
245}
246
247impl Row {
248 pub fn new(values: Vec<Value>) -> Self {
250 Self { values }
251 }
252
253 pub fn get(&self, index: usize) -> Option<&Value> {
255 self.values.get(index)
256 }
257}
258
259impl Default for QueryResult {
260 fn default() -> Self {
261 Self::new()
262 }
263}
264#[cfg(test)]
265mod tests {
266 use super::*;
267
268 #[test]
269 fn test_internal_query_creation() {
270 let query = InternalQuery::new(QueryOperation::Select);
271 assert_eq!(query.operation, QueryOperation::Select);
272 assert!(query.sources.is_empty());
273 assert!(query.projections.is_empty());
274 assert!(query.predicates.is_empty());
275 assert!(query.joins.is_empty());
276 assert!(query.ordering.is_none());
277 assert!(query.limit.is_none());
278 }
279
280 #[test]
281 fn test_data_source_creation() {
282 let source = DataSource {
283 object_type: "postgres".to_string(),
284 identifier: "users".to_string(),
285 alias: Some("u".to_string()),
286 };
287 assert_eq!(source.object_type, "postgres");
288 assert_eq!(source.identifier, "users");
289 assert_eq!(source.alias, Some("u".to_string()));
290 }
291
292 #[test]
293 fn test_query_result_creation() {
294 let result = QueryResult::new();
295 assert!(result.is_empty());
296 assert_eq!(result.row_count(), 0);
297 assert!(result.columns.is_empty());
298 assert!(result.rows.is_empty());
299 assert!(result.affected_rows.is_none());
300 }
301
302 #[test]
303 fn test_row_creation_and_access() {
304 let values = vec![
305 Value::Text("John".to_string()),
306 Value::Integer(25),
307 Value::Boolean(true),
308 ];
309 let row = Row::new(values);
310
311 assert_eq!(row.get(0), Some(&Value::Text("John".to_string())));
312 assert_eq!(row.get(1), Some(&Value::Integer(25)));
313 assert_eq!(row.get(2), Some(&Value::Boolean(true)));
314 assert_eq!(row.get(3), None);
315 }
316
317 #[test]
318 fn test_predicate_value_types() {
319 let string_val = PredicateValue::String("test".to_string());
320 let number_val = PredicateValue::Number(3.14);
321 let int_val = PredicateValue::Integer(42);
322 let bool_val = PredicateValue::Boolean(true);
323 let null_val = PredicateValue::Null;
324
325 match string_val {
326 PredicateValue::String(s) => assert_eq!(s, "test"),
327 _ => panic!("Expected string value"),
328 }
329
330 match number_val {
331 PredicateValue::Number(n) => assert_eq!(n, 3.14),
332 _ => panic!("Expected number value"),
333 }
334
335 match int_val {
336 PredicateValue::Integer(i) => assert_eq!(i, 42),
337 _ => panic!("Expected integer value"),
338 }
339
340 match bool_val {
341 PredicateValue::Boolean(b) => assert!(b),
342 _ => panic!("Expected boolean value"),
343 }
344
345 match null_val {
346 PredicateValue::Null => {},
347 _ => panic!("Expected null value"),
348 }
349 }
350
351 #[test]
352 fn test_connector_type_serialization() {
353 let mock_type = ConnectorType::Mock;
354 let postgres_type = ConnectorType::PostgreSQL;
355 let custom_type = ConnectorType::Custom("MyConnector".to_string());
356
357 assert_eq!(mock_type, ConnectorType::Mock);
358 assert_eq!(postgres_type, ConnectorType::PostgreSQL);
359 assert_eq!(custom_type, ConnectorType::Custom("MyConnector".to_string()));
360 }
361}