sql_cli/services/
application_orchestrator.rs

1use crate::services::{DataLoaderService, QueryOrchestrator};
2use crate::ui::enhanced_tui::EnhancedTuiApp;
3use anyhow::Result;
4use tracing::info;
5
6/// Orchestrates the entire application lifecycle
7/// This removes file loading knowledge from the TUI
8pub struct ApplicationOrchestrator {
9    data_loader: DataLoaderService,
10    query_orchestrator: QueryOrchestrator,
11}
12
13impl ApplicationOrchestrator {
14    pub fn new(case_insensitive: bool, auto_hide_empty: bool) -> Self {
15        Self {
16            data_loader: DataLoaderService::new(case_insensitive),
17            query_orchestrator: QueryOrchestrator::new(case_insensitive, auto_hide_empty),
18        }
19    }
20
21    /// Create a TUI with an initial file loaded
22    /// The TUI doesn't need to know about file types or loading
23    pub fn create_tui_with_file(&self, file_path: &str) -> Result<EnhancedTuiApp> {
24        info!("Creating TUI with file: {}", file_path);
25
26        // Load the file using the data loader service
27        let load_result = self.data_loader.load_file(file_path)?;
28
29        // Get the status message before moving dataview
30        let status_message = load_result.status_message();
31        let source_path = load_result.source_path.clone();
32        let table_name = load_result.table_name.clone();
33        let raw_table_name = load_result.raw_table_name.clone();
34
35        // Create the TUI with just a DataView
36        let mut app = EnhancedTuiApp::new_with_dataview(load_result.dataview, &source_path)?;
37
38        // Set the initial status message
39        app.set_status_message(status_message);
40
41        // Pre-populate the SQL command with SELECT * FROM table
42        app.set_sql_query(&table_name, &raw_table_name);
43
44        Ok(app)
45    }
46
47    /// Load additional files into existing TUI
48    pub fn load_additional_file(&self, app: &mut EnhancedTuiApp, file_path: &str) -> Result<()> {
49        info!("Loading additional file: {}", file_path);
50
51        // Load the file
52        let load_result = self.data_loader.load_file(file_path)?;
53
54        // Get the status message before moving dataview
55        let status_message = load_result.status_message();
56        let source_path = load_result.source_path.clone();
57        let table_name = load_result.table_name.clone();
58        let raw_table_name = load_result.raw_table_name.clone();
59
60        // Add to the TUI (it will create a new buffer)
61        app.add_dataview(load_result.dataview, &source_path)?;
62
63        // Set status message
64        app.set_status_message(status_message);
65
66        // Pre-populate the SQL command with SELECT * FROM table for new buffer
67        app.set_sql_query(&table_name, &raw_table_name);
68
69        Ok(())
70    }
71
72    /// Execute a query in the TUI
73    /// Note: This is a simplified version - the TUI itself should use execute_query_v2
74    /// which properly handles the closures for apply_to_tui
75    pub fn execute_query(&mut self, app: &mut EnhancedTuiApp, query: &str) -> Result<()> {
76        // For now, just delegate to the TUI's own execute_query_v2 method
77        // This avoids the borrowing issues with closures
78        app.execute_query_v2(query)
79    }
80}
81
82/// Builder pattern for creating the orchestrator with configuration
83pub struct ApplicationOrchestratorBuilder {
84    case_insensitive: bool,
85    auto_hide_empty: bool,
86}
87
88impl ApplicationOrchestratorBuilder {
89    pub fn new() -> Self {
90        Self {
91            case_insensitive: false,
92            auto_hide_empty: false,
93        }
94    }
95
96    pub fn with_case_insensitive(mut self, value: bool) -> Self {
97        self.case_insensitive = value;
98        self
99    }
100
101    pub fn with_auto_hide_empty(mut self, value: bool) -> Self {
102        self.auto_hide_empty = value;
103        self
104    }
105
106    pub fn build(self) -> ApplicationOrchestrator {
107        ApplicationOrchestrator::new(self.case_insensitive, self.auto_hide_empty)
108    }
109}