Skip to content

Commit e4c5923

Browse files
committed
Improve CLI help, version display, and REPL startup banner
- Add --version flag - Add usage examples to --help output - Show version in REPL banner - Show contextual sample query on startup (adapts to loaded spec) - List available commands and keyboard shortcuts
1 parent cdae4f3 commit e4c5923

2 files changed

Lines changed: 64 additions & 3 deletions

File tree

crates/sqlize/src/main.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,15 @@ use sqlize_core::exec::AuthConfig;
1313
use sqlize_core::spec::SpecInfo;
1414

1515
#[derive(Parser)]
16-
#[command(name = "sqlize", about = "SQL interface for REST APIs")]
16+
#[command(
17+
name = "sqlize",
18+
about = "SQL interface for REST APIs",
19+
version,
20+
after_help = "Examples:\n \
21+
sqlize --spec specs/github-minimal.json\n \
22+
sqlize --spec specs/github-minimal.json query \"SELECT name FROM orgs_repos WHERE org = 'rust-lang' LIMIT 5\"\n \
23+
sqlize --spec github:specs/github.json --spec stripe:specs/stripe.json"
24+
)]
1725
struct Cli {
1826
#[command(subcommand)]
1927
command: Option<Command>,
@@ -285,6 +293,7 @@ async fn main() -> anyhow::Result<()> {
285293
}
286294
None => {
287295
// Print banner
296+
eprintln!("sqlize v{}", env!("CARGO_PKG_VERSION"));
288297
if is_single_spec {
289298
let spec = &specs[0];
290299
eprintln!(

crates/sqlize/src/repl.rs

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -367,8 +367,60 @@ impl Completer for SqlCompleter {
367367
// ---------------------------------------------------------------------------
368368

369369
pub async fn run(catalog_set: Arc<CatalogSet>, ctx: Arc<SqlizeContext>, format: OutputFormat) {
370-
eprintln!("Type SQL (end with ;), or: SHOW TABLES, DESCRIBE <table>, EXPLAIN <sql>");
371-
eprintln!("Ctrl+D to exit.\n");
370+
eprintln!("Commands: SHOW TABLES, DESCRIBE <table>, EXPLAIN <query>");
371+
eprintln!("SQL ends with ; | Tab to complete | Ctrl+D to exit");
372+
373+
// Show a sample query — prefer tables named issues, pulls, or orgs_repos
374+
let all = catalog_set.all_tables();
375+
let preferred = [
376+
"issues",
377+
"pulls",
378+
"orgs_repos",
379+
"repos",
380+
"commits",
381+
"customers",
382+
];
383+
let sample_table = preferred
384+
.iter()
385+
.find_map(|name| all.iter().find(|(_, t)| t.name.as_str() == *name))
386+
.or_else(|| {
387+
all.iter().find(|(_, t)| {
388+
t.required_params().next().is_some() && t.result_columns().nth(1).is_some()
389+
})
390+
});
391+
if let Some((_, table)) = sample_table {
392+
let params: Vec<String> = table
393+
.required_params()
394+
.map(|c| format!("{} = '...'", c.name))
395+
.collect();
396+
let cols: Vec<&str> = table
397+
.columns
398+
.iter()
399+
.filter(|c| {
400+
matches!(
401+
c.role,
402+
sqlize_core::catalog::types::ColumnRole::ResponseField
403+
)
404+
})
405+
.take(3)
406+
.map(|c| c.name.as_str())
407+
.collect();
408+
if params.is_empty() {
409+
eprintln!(
410+
"\nTry: SELECT {} FROM {} LIMIT 5;",
411+
cols.join(", "),
412+
table.name,
413+
);
414+
} else {
415+
eprintln!(
416+
"\nTry: SELECT {} FROM {} WHERE {} LIMIT 5;",
417+
cols.join(", "),
418+
table.name,
419+
params.join(" AND "),
420+
);
421+
}
422+
}
423+
eprintln!();
372424

373425
let history_file = history_path();
374426
if let Some(parent) = history_file.parent() {

0 commit comments

Comments
 (0)