sql_cli/ui/operations/
query_engine_integration.rs

1use crate::api_client::{QueryInfo, QueryResponse};
2use crate::data::data_view::DataView;
3use crate::data::datatable::{DataTable, DataValue};
4use crate::data::query_engine::QueryEngine;
5use anyhow::Result;
6use serde_json::{json, Value};
7use std::sync::Arc;
8
9/// Integration layer between QueryEngine and enhanced_tui
10/// Handles conversion between DataView and QueryResponse formats
11pub struct QueryEngineIntegration;
12
13impl QueryEngineIntegration {
14    /// Execute a query using QueryEngine and convert to QueryResponse format
15    pub fn execute_query(table: &DataTable, query: &str) -> Result<QueryResponse> {
16        // Need an Arc for QueryEngine
17        let table_arc = Arc::new(table.clone());
18        let engine = QueryEngine::new();
19        let view = engine.execute(table_arc, query)?;
20
21        // Convert DataView to QueryResponse format
22        Self::dataview_to_query_response(view)
23    }
24
25    /// Execute a query with hidden columns
26    pub fn execute_query_with_hidden_columns(
27        table: &DataTable,
28        query: &str,
29        hidden_columns: &[String],
30    ) -> Result<QueryResponse> {
31        // Need an Arc for QueryEngine
32        let table_arc = Arc::new(table.clone());
33        let engine = QueryEngine::new();
34        let mut view = engine.execute(table_arc, query)?;
35
36        // Hide the specified columns
37        for col_name in hidden_columns {
38            view.hide_column_by_name(col_name);
39        }
40
41        // Convert DataView to QueryResponse format
42        Self::dataview_to_query_response(view)
43    }
44
45    /// Convert a DataView to QueryResponse format for TUI compatibility
46    fn dataview_to_query_response(view: DataView) -> Result<QueryResponse> {
47        let mut rows = Vec::new();
48        let column_names = view.column_names();
49
50        // Get all rows from the view
51        let data_rows = view.get_rows();
52
53        // Convert each DataRow to JSON
54        for row in data_rows {
55            let mut row_obj = serde_json::Map::new();
56
57            for (col_idx, col_name) in column_names.iter().enumerate() {
58                let value = row.values.get(col_idx);
59                let json_value = match value {
60                    Some(data_value) => Self::datavalue_to_json(data_value),
61                    None => Value::Null,
62                };
63                row_obj.insert(col_name.clone(), json_value);
64            }
65
66            rows.push(Value::Object(row_obj));
67        }
68
69        Ok(QueryResponse {
70            data: rows.clone(),
71            count: rows.len(),
72            query: QueryInfo {
73                select: vec![],
74                where_clause: None,
75                order_by: None,
76            },
77            source: Some("QueryEngine".to_string()),
78            table: None,
79            cached: Some(false),
80        })
81    }
82
83    /// Execute query and return DataView directly (for future optimized path)
84    pub fn execute_to_view(table: Arc<DataTable>, query: &str) -> Result<DataView> {
85        let engine = QueryEngine::new();
86        engine.execute(table, query)
87    }
88
89    /// Convert DataValue to JSON Value
90    fn datavalue_to_json(value: &DataValue) -> Value {
91        match value {
92            DataValue::String(s) => json!(s),
93            DataValue::InternedString(s) => json!(s.as_ref()),
94            DataValue::Integer(i) => json!(i),
95            DataValue::Float(f) => json!(f),
96            DataValue::Boolean(b) => json!(b),
97            DataValue::DateTime(dt) => json!(dt),
98            DataValue::Null => Value::Null,
99        }
100    }
101}