use colored::Colorize;
use comfy_table::presets::UTF8_FULL;
use comfy_table::{Cell, Color, ContentArrangement, Table};
use std::collections::HashMap;
use crate::repl::QueryResult;
pub fn print_result(result: &QueryResult, format: &str) {
if result.rows.is_empty() {
println!("{}", "No results.".dimmed());
return;
}
match format.to_lowercase().as_str() {
"json" => match serde_json::to_string_pretty(&result.rows) {
Ok(json) => println!("{json}"),
Err(e) => eprintln!("{}", format!("Failed to serialize to JSON: {e}").red()),
},
_ => {
print_table(&result.rows);
}
}
}
pub fn print_table(rows: &[HashMap<String, serde_json::Value>]) {
if rows.is_empty() {
return;
}
let mut columns: Vec<String> = Vec::new();
for row in rows {
for key in row.keys() {
if !columns.contains(key) {
columns.push(key.clone());
}
}
}
columns.sort();
if let Some(pos) = columns.iter().position(|c| c == "id") {
columns.remove(pos);
columns.insert(0, "id".to_string());
}
let mut table = Table::new();
table
.load_preset(UTF8_FULL)
.set_content_arrangement(ContentArrangement::Dynamic);
let header: Vec<Cell> = columns
.iter()
.map(|c| Cell::new(c).fg(Color::Cyan))
.collect();
table.set_header(header);
for row in rows {
let cells: Vec<Cell> = columns
.iter()
.map(|col| {
let value = row.get(col).map_or("-".to_string(), |v| match v {
serde_json::Value::String(s) => s.clone(),
serde_json::Value::Null => "-".to_string(),
other => other.to_string(),
});
Cell::new(value)
})
.collect();
table.add_row(cells);
}
println!("{table}");
}
pub fn print_help() {
println!("\n{}", "VelesQL REPL Commands".bold().underline());
println!();
println!(" {} Show this help", ".help".yellow());
println!(" {} Exit the REPL", ".quit".yellow());
println!(" {} List all collections", ".collections".yellow());
println!(" {} Show collection schema", ".schema <name>".yellow());
println!(
" {} Detailed collection stats",
".describe <name>".yellow()
);
println!(
" {} Count records in collection",
".count <name>".yellow()
);
println!(" {} Show N sample records", ".sample <name> [n]".yellow());
println!(
" {} Browse with pagination",
".browse <name> [page]".yellow()
);
println!(" {} Export to JSON file", ".export <name> [file]".yellow());
println!(
" {} Toggle timing display",
".timing on|off".yellow()
);
println!(
" {} Set output format",
".format table|json".yellow()
);
println!(" {} Clear screen", ".clear".yellow());
println!();
println!("{}", "Data & Index Commands:".bold().underline());
println!();
println!(
" {} Show query execution plan",
".explain <query>".yellow()
);
println!(
" {} Analyze collection statistics",
".analyze <name>".yellow()
);
println!(
" {} List indexes on collection",
".indexes <name>".yellow()
);
println!(
" {} Delete points by ID",
".delete <name> <id> [id2..]".yellow()
);
println!(
" {} Flush collection to disk",
".flush <name>".yellow()
);
println!(
" {} Create index",
".create-index <name> <field> [--type secondary|property|range]".yellow()
);
println!(
" {} Drop index",
".drop-index <name> <label> <prop>".yellow()
);
println!();
println!("{}", "Advanced Search:".bold().underline());
println!();
println!(
" {} Sparse-only search",
".sparse-search <name> <idx> <json> [k]".yellow()
);
println!(
" {} Dense+sparse hybrid",
".hybrid-sparse <name> <dense> <sparse> [k] [--strategy rrf|average|max]".yellow()
);
println!(" {} Show query guard-rails", ".guardrails".yellow());
println!(" {} Agent memory (preview)", ".agent [cmd]".yellow());
println!();
println!("{}", "Session Commands:".bold().underline());
println!();
println!(
" {} Set session parameter",
"\\set <key> <value>".yellow()
);
println!(" {} Show session settings", "\\show [key]".yellow());
println!(" {} Reset settings", "\\reset [key]".yellow());
println!(
" {} Select active collection",
"\\use <collection>".yellow()
);
println!(" {} Database information", "\\info".yellow());
println!(" {} Quick benchmark", "\\bench <col> [n] [k]".yellow());
println!();
println!("{}", "Session Settings:".bold().underline());
println!();
println!(" {} fast, balanced, accurate, perfect", "mode".cyan());
println!(" {} 16-4096 (or auto from mode)", "ef_search".cyan());
println!(" {} Query timeout in ms", "timeout_ms".cyan());
println!(" {} Enable reranking (true/false)", "rerank".cyan());
println!(" {} Max results per query", "max_results".cyan());
println!();
println!("{}", "VelesQL Examples:".bold().underline());
println!();
println!(" {}", "SELECT * FROM documents LIMIT 10;".italic().white());
println!(
" {}",
"SELECT * FROM docs WHERE vector NEAR $v LIMIT 5 WITH (mode = 'fast');"
.italic()
.white()
);
println!(
" {}",
"SELECT * FROM items WHERE category = 'tech' LIMIT 20;"
.italic()
.white()
);
println!();
}