Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .claude/settings.local.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
"Bash(grep:*)",
"Bash(cargo fmt:*)",
"Bash(./target/release/dft:*)",
"Bash(/Users/matth/OpenSource/datafusion-tui/target/debug/dft:*)"
"Bash(/Users/matth/OpenSource/datafusion-tui/target/debug/dft:*)",
"Bash(./target/debug/dft:*)"
],
"deny": [],
"ask": []
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,9 @@ jobs:
awslocal s3 mv data/aggregate_test_100.csv s3://test/
awslocal s3 mb s3://tpch-db
echo "Test Execution complete!"
- name: Run CLI tests
- name: Run TUI tests
run: |
cargo test tui_cases
cargo test --features=tui tui_cases

test-s3:
name: Extension / S3
Expand Down
12 changes: 8 additions & 4 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,14 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
# Build the project (default features: functions-parquet, s3)
cargo build

# Build with TUI support
cargo build --features=tui

# Build with all features
cargo build --all-features

# Run the TUI (default interface)
cargo run
# Run the TUI (requires tui feature)
cargo run --features=tui

# Run CLI with a query
cargo run -- -c "SELECT 1 + 2"
Expand Down Expand Up @@ -93,8 +96,8 @@ cargo test db
# Run CLI tests
cargo test cli_cases

# Run TUI tests
cargo test tui_cases
# Run TUI tests (requires tui feature)
cargo test --features=tui tui_cases

# Run feature-specific tests
cargo test --features=flightsql extension_cases::flightsql -- --test-threads=1
Expand Down Expand Up @@ -196,6 +199,7 @@ Both servers share the same `ExecutionContext` from `datafusion-app`.

The project uses extensive feature flags to keep binary size manageable:

- `tui` - Terminal user interface (ratatui-based)
- `s3` - S3 object store integration (default)
- `functions-parquet` - Parquet-specific functions (default)
- `functions-json` - JSON functions
Expand Down
11 changes: 7 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ arrow-flight = { features = [
axum = { features = ["macros"], optional = true, version = "0.7.9" }
clap = { features = ["derive"], version = "4.5.27" }
color-eyre = "0.6.3"
crossterm = { features = ["event-stream"], version = "0.28.1" }
crossterm = { features = ["event-stream"], optional = true, version = "0.28.1" }
datafusion = { version = "51" }
datafusion-app = { path = "crates/datafusion-app", version = "0.1.0" }
directories = "5.0.1"
Expand All @@ -39,7 +39,7 @@ object_store = "0.12"
parquet = "57"
pin-project-lite = { version = "0.2.14" }
prost = "0.14"
ratatui = "0.28.0"
ratatui = { optional = true, version = "0.28.0" }
serde = { features = ["derive"], version = "1.0.197" }
strum = "0.26.2"
tokio = { features = [
Expand All @@ -62,8 +62,10 @@ tpchgen = "2.0"
tpchgen-arrow = "2.0"
tracing = { features = ["log"], version = "0.1.41" }
tracing-subscriber = { features = ["env-filter"], version = "0.3.19" }
tui-logger = { features = ["tracing-support"], version = "0.12" }
tui-textarea = { features = ["search"], version = "0.6.1" }
tui-logger = { features = [
"tracing-support",
], optional = true, version = "0.12" }
tui-textarea = { features = ["search"], optional = true, version = "0.6.1" }
url = { features = ["serde"], version = "2.5.2" }
uuid = { optional = true, version = "1.10.0" }
vortex = { optional = true, version = "0.58" }
Expand Down Expand Up @@ -113,6 +115,7 @@ http = [
]
huggingface = ["datafusion-app/huggingface"]
s3 = ["datafusion-app/s3"]
tui = ["dep:crossterm", "dep:ratatui", "dep:tui-logger", "dep:tui-textarea"]
udfs-wasm = ["datafusion-app/udfs-wasm"]
vortex = [
"datafusion-app/vortex",
Expand Down
27 changes: 19 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ Documentation is undergoing a significant revamp - the new documentation will be

The project offers four complementary interfaces:

1. **Text User Interface (TUI)**: An interactive SQL IDE with real-time query analysis, benchmarking, and catalog exploration
1. **Text User Interface (TUI)**: An interactive SQL IDE with real-time query analysis, benchmarking, and catalog exploration (requires `tui` feature)
2. **Command Line Interface (CLI)**: A scriptable engine for executing queries from files or command line
3. **FlightSQL Server**: A standards-compliant SQL interface for programmatic access
4. **HTTP Server**: A REST API for SQL queries and catalog exploration
3. **FlightSQL Server**: A standards-compliant SQL interface for programmatic access (requires `flightsql` feature)
4. **HTTP Server**: A REST API for SQL queries and catalog exploration (requires `http` feature)

All interfaces share the same execution engine, allowing you to develop locally with the TUI and then seamlessly deploy with the server implementations.

Expand All @@ -29,10 +29,13 @@ All interfaces share the same execution engine, allowing you to develop locally

#### From crates.io (Recommended)
```sh
# If you have Rust installed
# Core CLI and server interfaces
cargo install datafusion-dft

# For full functionality with all features
# With TUI interface
cargo install datafusion-dft --features=tui

# For full functionality with all features (including TUI)
cargo install datafusion-dft --all-features
```

Expand All @@ -44,19 +47,27 @@ Common feature combinations:
# Core with S3 support
cargo install datafusion-dft --features=s3

# With TUI interface
cargo install datafusion-dft --features=tui

# TUI with S3 and data lake formats
cargo install datafusion-dft --features=tui,s3,deltalake

# Data lake formats
cargo install datafusion-dft --features=deltalake

# With JSON and Parquet functions
cargo install datafusion-dft --features=function-json,functions-parquet
cargo install datafusion-dft --features=functions-json,functions-parquet
```

See the [Features documentation](docs/features.md) for all available features.

**Note**: The TUI (Text User Interface) is optional and requires the `tui` feature flag. The CLI, FlightSQL server, and HTTP server are always available.

### Running the apps

```sh
# Interactive TUI (default)
# Interactive TUI (requires `tui` feature)
dft

# CLI with direct query execution
Expand Down Expand Up @@ -155,7 +166,7 @@ LOCATION 's3://bucket/delta_table';

#### Loading DDL

- **TUI**: DDL is automatically loaded at startup
- **TUI** (requires `tui` feature): DDL is automatically loaded at startup
- **CLI**: Add `--run-ddl` flag to execute DDL before your query
- **Custom Path**: Configure a custom DDL path in your config file
```toml
Expand Down
12 changes: 12 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ pub struct CliConfig {
pub execution: ExecutionConfig,
}

#[cfg(feature = "tui")]
#[derive(Clone, Debug, Default, Deserialize)]
pub struct TuiConfig {
#[serde(default = "default_execution_config")]
Expand Down Expand Up @@ -170,6 +171,7 @@ pub struct AppConfig {
pub shared: ExecutionConfig,
#[serde(default)]
pub cli: CliConfig,
#[cfg(feature = "tui")]
#[serde(default)]
pub tui: TuiConfig,
#[cfg(feature = "flightsql")]
Expand All @@ -189,10 +191,12 @@ fn default_execution_config() -> ExecutionConfig {
ExecutionConfig::default()
}

#[cfg(feature = "tui")]
fn default_display_config() -> DisplayConfig {
DisplayConfig::default()
}

#[cfg(feature = "tui")]
fn default_interaction_config() -> InteractionConfig {
InteractionConfig::default()
}
Expand Down Expand Up @@ -229,16 +233,19 @@ fn default_db_path() -> Url {
Url::parse(&with_schema).unwrap()
}

#[cfg(feature = "tui")]
#[derive(Clone, Debug, Deserialize)]
pub struct DisplayConfig {
#[serde(default = "default_frame_rate")]
pub frame_rate: f64,
}

#[cfg(feature = "tui")]
fn default_frame_rate() -> f64 {
30.0
}

#[cfg(feature = "tui")]
impl Default for DisplayConfig {
fn default() -> Self {
Self { frame_rate: 30.0 }
Expand All @@ -250,6 +257,7 @@ fn default_benchmark_iterations() -> usize {
10
}

#[cfg(feature = "tui")]
#[derive(Clone, Debug, Default, Deserialize)]
pub struct InteractionConfig {
#[serde(default = "default_mouse")]
Expand All @@ -258,10 +266,12 @@ pub struct InteractionConfig {
pub paste: bool,
}

#[cfg(feature = "tui")]
fn default_mouse() -> bool {
false
}

#[cfg(feature = "tui")]
fn default_paste() -> bool {
false
}
Expand All @@ -281,11 +291,13 @@ fn default_server_metrics_addr() -> SocketAddr {
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 9000)
}

#[cfg(feature = "tui")]
#[derive(Clone, Debug, Default, Deserialize)]
pub struct EditorConfig {
pub experimental_syntax_highlighting: bool,
}

#[cfg(feature = "tui")]
fn default_editor_config() -> EditorConfig {
EditorConfig::default()
}
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ pub mod db;
pub mod execution;
#[cfg(any(feature = "flightsql", feature = "http"))]
pub mod server;
#[cfg(feature = "tui")]
pub mod telemetry;
pub mod test_utils;
pub mod tpch;
#[cfg(feature = "tui")]
pub mod tui;

pub const APP_NAME: &str = "dft";
23 changes: 21 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,15 @@
// under the License.

use clap::Parser;
#[cfg(not(feature = "tui"))]
use color_eyre::eyre::eyre;
use color_eyre::Result;
use datafusion_dft::args::Command;
#[cfg(any(feature = "flightsql", feature = "http"))]
use datafusion_dft::server;
use datafusion_dft::{args::DftArgs, cli, config::create_config, tpch, tui};
#[cfg(feature = "tui")]
use datafusion_dft::tui;
use datafusion_dft::{args::DftArgs, cli, config::create_config, tpch};
#[cfg(feature = "http")]
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};

Expand Down Expand Up @@ -129,7 +133,22 @@ async fn app_entry_point(cli: DftArgs) -> Result<()> {
if !cli.files.is_empty() || !cli.commands.is_empty() {
cli::try_run(cli, cfg).await?;
} else {
tui::try_run(cli, cfg).await?;
#[cfg(feature = "tui")]
{
tui::try_run(cli, cfg).await?;
}
#[cfg(not(feature = "tui"))]
{
return Err(eyre!(
"TUI is not enabled in this build.\n\n\
To use the TUI interface, rebuild with:\n \
cargo install datafusion-dft --features=tui\n\n\
Or use the CLI interface:\n \
dft -c \"SELECT 1 + 2\"\n \
dft -f query.sql\n\n\
For more information, run: dft --help"
));
}
}

Ok(())
Expand Down
2 changes: 2 additions & 0 deletions tests/tui_cases/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
// specific language governing permissions and limitations
// under the License.

#![cfg(feature = "tui")]

mod ddl;
#[cfg(feature = "flightsql")]
mod flightsql_pagination;
Expand Down