diff --git a/src/command.rs b/src/command.rs index 12e659d..e1d8a56 100644 --- a/src/command.rs +++ b/src/command.rs @@ -553,6 +553,11 @@ pub enum DatabasesCommands { #[arg(long = "table")] tables: Vec, + /// When the database expires. Accepts a relative duration (e.g. 24h, 7d, 90m) + /// or an RFC 3339 timestamp. Defaults to 24h when omitted. + #[arg(long)] + expires_at: Option, + /// Output format #[arg(long = "output", short = 'o', default_value = "table", value_parser = ["table", "json", "yaml"])] output: String, diff --git a/src/databases.rs b/src/databases.rs index d6e0e1d..542cb08 100644 --- a/src/databases.rs +++ b/src/databases.rs @@ -130,6 +130,7 @@ pub fn create_database_request( description: Option<&str>, schema: &str, tables: &[String], + expires_at: Option<&str>, ) -> serde_json::Value { let mut req = serde_json::Map::new(); @@ -151,6 +152,13 @@ pub fn create_database_request( ); } + if let Some(exp) = expires_at { + req.insert( + "expires_at".to_string(), + serde_json::Value::String(exp.to_string()), + ); + } + serde_json::Value::Object(req) } @@ -414,11 +422,12 @@ pub fn create( description: Option<&str>, schema: &str, tables: &[String], + expires_at: Option<&str>, format: &str, ) { use crossterm::style::Stylize; - let body = create_database_request(description, schema, tables); + let body = create_database_request(description, schema, tables, expires_at); let api = ApiClient::new(Some(workspace_id)); let spinner = (format == "table").then(|| crate::util::spinner("Creating database...")); @@ -643,13 +652,13 @@ mod tests { #[test] fn create_database_request_empty_without_description_or_tables() { - let req = create_database_request(None, "public", &[]); + let req = create_database_request(None, "public", &[], None); assert_eq!(req, serde_json::json!({})); } #[test] fn create_database_request_includes_description() { - let req = create_database_request(Some("my db"), "public", &[]); + let req = create_database_request(Some("my db"), "public", &[], None); assert_eq!(req["description"], "my db"); assert!(req.get("schemas").is_none()); } @@ -660,6 +669,7 @@ mod tests { Some("sales"), "public", &["orders".to_string(), "customers".to_string()], + None, ); assert_eq!(req["description"], "sales"); assert_eq!(req["schemas"][0]["name"], "public"); @@ -669,11 +679,23 @@ mod tests { #[test] fn create_database_request_schemas_without_description() { - let req = create_database_request(None, "analytics", &["events".to_string()]); + let req = create_database_request(None, "analytics", &["events".to_string()], None); assert!(req.get("description").is_none()); assert_eq!(req["schemas"][0]["name"], "analytics"); } + #[test] + fn create_database_request_includes_expires_at_when_provided() { + let req = create_database_request(None, "public", &[], Some("24h")); + assert_eq!(req["expires_at"], "24h"); + } + + #[test] + fn create_database_request_omits_expires_at_when_none() { + let req = create_database_request(None, "public", &[], None); + assert!(req.get("expires_at").is_none()); + } + fn full_detail(id: &str, desc: &str, conn_id: &str) -> String { format!( r#"{{"id":"{id}","description":"{desc}","default_connection_id":"{conn_id}","attachments":[]}}"# @@ -855,13 +877,14 @@ mod tests { Some("mydb"), "public", &["gdp".to_string()], + None, )) .unwrap(), )) .create(); let api = ApiClient::test_new(&server.url(), "k", Some("ws-test")); - let body = create_database_request(Some("mydb"), "public", &["gdp".to_string()]); + let body = create_database_request(Some("mydb"), "public", &["gdp".to_string()], None); let (status, resp_body) = api.post_raw("/databases", &body); assert_eq!(status.as_u16(), 201); let parsed: CreateDatabaseResponse = serde_json::from_str(&resp_body).unwrap(); diff --git a/src/main.rs b/src/main.rs index 8957ae7..8286e4f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -387,12 +387,14 @@ fn main() { description, schema, tables, + expires_at, output, }) => databases::create( &workspace_id, description.as_deref(), &schema, &tables, + expires_at.as_deref(), &output, ), Some(DatabasesCommands::Set { id_or_description }) => {