athena_cli/
cli.rs

1use clap::{Args, Parser, Subcommand};
2use humantime::parse_duration;
3use std::time::Duration;
4
5// Shared AWS arguments used by multiple commands
6#[derive(Args, Clone, Default)]
7pub struct AwsArgs {
8    /// AWS Profile name
9    #[arg(short, long, global = true)]
10    pub profile: Option<String>,
11
12    /// Workgroup name
13    #[arg(short, long, global = true)]
14    pub workgroup: Option<String>,
15
16    /// Database name
17    #[arg(short, long, global = true)]
18    pub database: Option<String>,
19
20    /// Catalog name
21    #[arg(long, global = true)]
22    pub catalog: Option<String>,
23
24    /// AWS Region
25    #[arg(long, global = true)]
26    pub region: Option<String>,
27
28    /// S3 output location (for query results)
29    #[arg(long, global = true)]
30    pub output_location: Option<String>,
31}
32
33// Global display settings
34#[derive(Args, Clone, Default)]
35pub struct DisplayArgs {
36    /// Suppress detailed output
37    #[arg(short, long, global = true)]
38    pub quiet: bool,
39}
40
41// Shared arguments for commands that support file output
42#[derive(Args, Clone)]
43pub struct OutputArgs {
44    /// Output directory for results
45    #[arg(short, long)]
46    pub output: Option<String>,
47}
48
49#[derive(Parser)]
50#[command(author, version, about, long_about = None)]
51pub struct Cli {
52    #[command(subcommand)]
53    pub command: Commands,
54
55    #[command(flatten)]
56    pub aws: AwsArgs,
57
58    #[command(flatten)]
59    pub display: DisplayArgs,
60}
61
62#[derive(Subcommand)]
63pub enum Commands {
64    /// Execute a query
65    Query(QueryArgs),
66
67    /// Database operations
68    Database {
69        #[command(subcommand)]
70        command: DatabaseCommands,
71    },
72
73    /// Table operations
74    Table {
75        #[command(subcommand)]
76        command: TableCommands,
77    },
78
79    /// Workgroup operations
80    Workgroup {
81        #[command(subcommand)]
82        command: WorkgroupCommands,
83    },
84
85    /// Show query history
86    History(HistoryArgs),
87
88    /// Inspect details of a specific query
89    Inspect(InspectArgs),
90
91    /// Download query results (shortcut for 'inspect -o')
92    #[command(alias = "dl")] // Optional: add even shorter alias
93    Download(DownloadArgs),
94}
95
96#[derive(Subcommand)]
97pub enum DatabaseCommands {
98    /// List available databases
99    List(DatabaseArgs),
100}
101
102#[derive(Subcommand)]
103pub enum TableCommands {
104    /// List tables in a database
105    List(TableArgs),
106
107    /// Describe table structure with columns and partitions
108    Describe(DescribeTableArgs),
109}
110
111#[derive(Subcommand)]
112pub enum WorkgroupCommands {
113    /// List workgroups
114    List(WorkgroupArgs),
115}
116
117#[derive(Args, Clone)]
118pub struct QueryArgs {
119    #[command(flatten)]
120    pub aws: AwsArgs,
121
122    /// SQL query to execute (can be a full SQL statement)
123    ///
124    /// Example: "SELECT * FROM my_database.my_table LIMIT 10"
125    pub query: String,
126
127    /// Query reuse time (e.g., "10m", "2h", "1h30m") - specifies how long cached results should be reused
128    ///
129    /// Athena will reuse query results for identical queries within this time period,
130    /// which can save on costs and improve performance. Set to 0 to disable result reuse.
131    #[arg(short = 'r', long, value_parser = parse_duration, default_value = "60m")]
132    pub reuse_time: Duration,
133}
134
135#[derive(Args, Clone)]
136pub struct DatabaseArgs {
137    // Empty - will use global catalog from AwsArgs
138    #[command(flatten)]
139    pub aws: AwsArgs,
140}
141
142#[derive(Args, Clone)]
143pub struct TableArgs {
144    /// Database name (overrides global settings)
145    #[arg(short = 'n', long)]
146    pub db: Option<String>,
147
148    /// Filter table names by pattern (e.g. "pp_*" for tables starting with pp_)
149    #[arg(short, long)]
150    pub filter: Option<String>,
151
152    /// Maximum number of tables to list
153    #[arg(short, long, default_value = "50")]
154    pub limit: i32,
155}
156
157#[derive(Args, Clone)]
158pub struct DescribeTableArgs {
159    /// Table identifier (can be 'database.table' or just 'table')
160    pub table: String,
161
162    /// Database name (alternative to using 'database.table' format)
163    #[arg(short = 'n', long)]
164    pub db: Option<String>,
165}
166
167#[derive(Args, Clone)]
168pub struct WorkgroupArgs {
169    /// Maximum number of workgroups to list
170    #[arg(short, long, default_value = "50")]
171    pub limit: i32,
172}
173
174#[derive(Args, Clone)]
175pub struct HistoryArgs {
176    /// Maximum number of history items to show (overrides config)
177    #[arg(short, long)]
178    pub limit: Option<i32>,
179
180    /// Show only queries with specific status (SUCCEEDED, FAILED, CANCELLED)
181    #[arg(short, long)]
182    pub status: Option<String>,
183}
184
185// For commands that support output
186#[derive(Args, Clone)]
187pub struct InspectArgs {
188    /// Query execution ID to inspect
189    pub query_id: String,
190
191    /// Output directory for query results (e.g., "." for current directory)
192    #[arg(short, long)]
193    pub output: Option<String>,
194
195    /// Quiet mode - only output the downloaded file path
196    #[arg(short, long)]
197    pub quiet: bool,
198}
199
200#[derive(Args, Clone)]
201pub struct DownloadArgs {
202    /// Query execution ID
203    pub query_id: String,
204
205    /// Output directory for results
206    #[arg(short, long, default_value = ".")]
207    pub output: Option<String>,
208}