use anyhow::Result;
use clap::{Parser, Subcommand};
use f_ck::{QueryPlan, CachedEngine, DataWriter};
use std::fs;
#[derive(Parser)]
#[command(name = "f-ck")]
#[command(about = "f*ck - fields combined with columnar keys")]
#[command(version = "0.1.0")]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
Run {
#[arg(short, long, value_name = "FILE")]
query: String,
#[arg(short, long, value_name = "FILE")]
output: String,
#[arg(short, long, value_name = "FORMAT", default_value = "csv")]
format: String,
#[arg(short, long)]
preview: bool,
#[arg(short, long, value_name = "N")]
limit: Option<usize>,
#[arg(long)]
no_cache: bool,
#[arg(long)]
cache_stats: bool,
},
Schema {
#[arg(short, long, value_name = "FILE")]
output: Option<String>,
},
}
fn main() -> Result<()> {
let cli = Cli::parse();
match cli.command {
Commands::Run {
query,
output,
format,
preview,
limit,
no_cache,
cache_stats,
} => {
let query_json = fs::read_to_string(&query)
.map_err(|e| anyhow::anyhow!("Failed to read query file '{}': {}", query, e))?;
let query_plan = QueryPlan::from_json(&query_json)
.map_err(|e| anyhow::anyhow!("Failed to parse query: {}", e))?;
println!("Executing query with {} sources...", query_plan.sources.len());
let mut engine = CachedEngine::new();
if cache_stats {
let stats = engine.cache_stats();
println!("Cache Statistics:");
for (key, value) in stats {
println!(" {}: {}", key, value);
}
}
let result = if no_cache {
use f_ck::JoinEngine;
JoinEngine::execute_query(&query_plan)
} else {
engine.execute_query_cached(&query_plan)
}.map_err(|e| anyhow::anyhow!("Query execution failed: {}", e))?;
if preview {
let preview_output = DataWriter::preview_data(result, limit)?;
println!("Preview:\n{}", preview_output);
} else {
DataWriter::write_with_format(result, &output, &format)?;
println!("Results written to: {}", output);
}
}
Commands::Schema { output } => {
let schema = QueryPlan::json_schema()?;
if let Some(output_file) = output {
fs::write(&output_file, &schema)
.map_err(|e| anyhow::anyhow!("Failed to write schema to '{}': {}", output_file, e))?;
println!("JSON schema written to: {}", output_file);
} else {
println!("{}", schema);
}
}
}
Ok(())
}