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
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ repository = "https://github.com/sundy-li/arrow_cli"
edition = "2024"
license = "Apache-2.0"
name = "arrow_cli"
version = "0.2.2"
version = "0.2.3"


[dependencies]
Expand Down
30 changes: 10 additions & 20 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,14 @@ use clap::Parser;
use tonic::transport::{ClientTlsConfig, Endpoint};

#[derive(Debug, Parser, PartialEq)]
#[command(disable_help_flag = true)]
struct Args {
#[clap(short = 'u', long, default_value = "root", help = "User name")]
user: String,

#[clap(short = 'p', long, default_value = "", help = "User password")]
password: String,

#[clap(
short = 'h',
long,
default_value = "127.0.0.1",
help = "Flight SQL Server host"
)]
#[clap(long, default_value = "127.0.0.1", help = "Flight SQL Server host")]
host: String,
#[clap(
short = 'P',
Expand All @@ -36,38 +30,34 @@ struct Args {
#[clap(long)]
tls: bool,

#[clap(long, help = "Print help information")]
help: bool,

#[clap(long, default_value = "180", help = "Request timeout in seconds")]
timeout: u64,

#[clap(
long,
default_value = "false",
help = "Execute query using prepared statement"
)]
prepared: bool,
}

#[tokio::main]
pub async fn main() -> Result<(), ArrowError> {
let args = Args::parse();
if args.help {
print_usage();
return Ok(());
}

let protocol = if args.tls { "https" } else { "http" };
// Authenticate
let url = format!("{protocol}://{}:{}", args.host, args.port);
let endpoint = endpoint(&args, url)?;
let is_repl = atty::is(Stream::Stdin);
let mut session =
session::Session::try_new(endpoint, &args.user, &args.password, is_repl).await?;
session::Session::try_new(endpoint, &args.user, &args.password, is_repl, args.prepared)
.await?;

session.handle().await;
Ok(())
}

fn print_usage() {
let msg = r#"Usage: arrow_cli <--user <USER>|--password <PASSWORD>|--host <HOST>|--port <PORT>|--timeout <TIME>>"#;
println!("{}", msg);
}

fn endpoint(args: &Args, addr: String) -> Result<Endpoint, ArrowError> {
let mut endpoint = Endpoint::new(addr)
.map_err(|_| ArrowError::IpcError("Cannot create endpoint".to_string()))?
Expand Down
11 changes: 9 additions & 2 deletions src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub struct Session {
client: FlightSqlServiceClient<Channel>,
is_repl: bool,
prompt: String,
prepared: bool,
}

impl Session {
Expand All @@ -27,6 +28,7 @@ impl Session {
user: &str,
password: &str,
is_repl: bool,
prepared: bool,
) -> Result<Self, ArrowError> {
let channel = endpoint
.connect()
Expand All @@ -49,6 +51,7 @@ impl Session {
client,
is_repl,
prompt,
prepared,
})
}

Expand Down Expand Up @@ -127,8 +130,12 @@ impl Session {
}

let start = Instant::now();
let mut stmt = self.client.prepare(query.to_string(), None).await?;
let flight_info = stmt.execute().await?;
let flight_info = if self.prepared {
let mut stmt = self.client.prepare(query.to_string(), None).await?;
stmt.execute().await?
} else {
self.client.execute(query.to_string(), None).await?
};
let ticket_recv_duration = start.elapsed();
let mut batches: Vec<RecordBatch> = Vec::new();

Expand Down