Skip to content

Commit

Permalink
Merge branch 'main' into hiltontj/meta-cache-write-path
Browse files Browse the repository at this point in the history
  • Loading branch information
hiltontj committed Nov 22, 2024
2 parents 20c74a7 + 3cde24f commit 20d09a8
Show file tree
Hide file tree
Showing 21 changed files with 620 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,31 @@ use secrecy::ExposeSecret;

use crate::commands::common::InfluxDb3Config;

#[derive(Debug, clap::Parser)]
enum Command {
Delete(Config),
}

#[derive(Debug, clap::Parser)]
pub(crate) struct ManageDatabaseConfig {
#[clap(subcommand)]
command: Command,
}

#[derive(Debug, clap::Parser)]
pub struct Config {
enum Command {
Delete(DatabaseConfig),
}

#[derive(Debug, clap::Parser)]
pub struct DatabaseConfig {
#[clap(flatten)]
influxdb3_config: InfluxDb3Config,
}

pub async fn delete_database(manage_db_config: ManageDatabaseConfig) -> Result<(), Box<dyn Error>> {
match manage_db_config.command {
pub async fn delete_database(config: ManageDatabaseConfig) -> Result<(), Box<dyn Error>> {
match config.command {
Command::Delete(config) => {
let InfluxDb3Config {
host_url,
database_name,
auth_token,
} = config.influxdb3_config;

println!(
"Are you sure you want to delete {:?}? Enter 'yes' to confirm",
database_name
Expand Down
2 changes: 2 additions & 0 deletions influxdb3/src/commands/manage/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod database;
pub mod table;
60 changes: 60 additions & 0 deletions influxdb3/src/commands/manage/table.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
use std::{error::Error, io};

use secrecy::ExposeSecret;

use crate::commands::common::InfluxDb3Config;

#[derive(Debug, clap::Parser)]
pub(crate) struct ManageTableConfig {
#[clap(subcommand)]
command: Command,
}

#[derive(Debug, clap::Parser)]
enum Command {
Delete(TableConfig),
}

#[derive(Debug, clap::Parser)]
pub struct TableConfig {
#[clap(short = 't', long = "table")]
table: String,

#[clap(flatten)]
influxdb3_config: InfluxDb3Config,
}

pub async fn delete_table(config: ManageTableConfig) -> Result<(), Box<dyn Error>> {
match config.command {
Command::Delete(config) => {
let InfluxDb3Config {
host_url,
database_name,
auth_token,
} = config.influxdb3_config;
println!(
"Are you sure you want to delete {:?}.{:?}? Enter 'yes' to confirm",
database_name, &config.table,
);
let mut confirmation = String::new();
let _ = io::stdin().read_line(&mut confirmation);
if confirmation.trim() != "yes" {
println!("Cannot delete table without confirmation");
} else {
let mut client = influxdb3_client::Client::new(host_url)?;
if let Some(t) = auth_token {
client = client.with_auth_token(t.expose_secret());
}
client
.api_v3_configure_table_delete(&database_name, &config.table)
.await?;

println!(
"Table {:?}.{:?} deleted successfully",
&database_name, &config.table
);
}
}
}
Ok(())
}
17 changes: 13 additions & 4 deletions influxdb3/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ use trogging::{

mod commands {
pub(crate) mod common;
pub mod database;
pub mod last_cache;
pub mod manage;
pub mod query;
pub mod serve;
pub mod token;
Expand Down Expand Up @@ -94,7 +94,10 @@ enum Command {
LastCache(commands::last_cache::Config),

/// Manage database (delete only for the moment)
Database(commands::database::ManageDatabaseConfig),
Database(commands::manage::database::ManageDatabaseConfig),

/// Manage table (delete only for the moment)
Table(commands::manage::table::ManageTableConfig),
}

fn main() -> Result<(), std::io::Error> {
Expand Down Expand Up @@ -152,12 +155,18 @@ fn main() -> Result<(), std::io::Error> {
std::process::exit(ReturnCode::Failure as _)
}
}
Some(Command::Database(db_config)) => {
if let Err(e) = commands::database::delete_database(db_config).await {
Some(Command::Database(config)) => {
if let Err(e) = commands::manage::database::delete_database(config).await {
eprintln!("Database delete command failed: {e}");
std::process::exit(ReturnCode::Failure as _)
}
}
Some(Command::Table(config)) => {
if let Err(e) = commands::manage::table::delete_table(config).await {
eprintln!("Table delete command failed: {e}");
std::process::exit(ReturnCode::Failure as _)
}
}
}
});

Expand Down
57 changes: 57 additions & 0 deletions influxdb3/tests/server/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,60 @@ async fn test_delete_missing_database() {
debug!(result = ?result, "delete missing database");
assert_contains!(&result, "404");
}

#[test_log::test(tokio::test)]
async fn test_delete_table() {
let server = TestServer::spawn().await;
let server_addr = server.client_addr();
let db_name = "foo";
let table_name = "cpu";
server
.write_lp_to_db(
db_name,
format!("{table_name},t1=a,t2=b,t3=c f1=true,f2=\"hello\",f3=4i,f4=4u,f5=5 1000"),
influxdb3_client::Precision::Second,
)
.await
.expect("write to db");
let result = run_with_confirmation(&[
"table",
"delete",
"--dbname",
db_name,
"--table",
table_name,
"--host",
&server_addr,
]);
debug!(result = ?result, "delete table");
assert_contains!(&result, "Table \"foo\".\"cpu\" deleted successfully");
}

#[test_log::test(tokio::test)]
async fn test_delete_missing_table() {
let server = TestServer::spawn().await;
let server_addr = server.client_addr();
let db_name = "foo";
let table_name = "mem";
server
.write_lp_to_db(
db_name,
format!("{table_name},t1=a,t2=b,t3=c f1=true,f2=\"hello\",f3=4i,f4=4u,f5=5 1000"),
influxdb3_client::Precision::Second,
)
.await
.expect("write to db");

let result = run_with_confirmation_and_err(&[
"table",
"delete",
"--dbname",
db_name,
"--table",
"cpu",
"--host",
&server_addr,
]);
debug!(result = ?result, "delete missing table");
assert_contains!(&result, "404");
}
165 changes: 165 additions & 0 deletions influxdb3/tests/server/configure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -508,3 +508,168 @@ async fn api_v3_configure_db_delete_missing_query_param() {
.expect("delete database call succeed");
assert_eq!(StatusCode::BAD_REQUEST, resp.status());
}

#[test_log::test(tokio::test)]
async fn api_v3_configure_table_delete() {
let db_name = "foo";
let tbl_name = "tbl";
let server = TestServer::spawn().await;
let client = reqwest::Client::new();
let url = format!(
"{base}/api/v3/configure/table?db={db_name}&table={tbl_name}",
base = server.client_addr()
);

server
.write_lp_to_db(
db_name,
format!("{tbl_name},t1=a,t2=b,t3=c f1=true,f2=\"hello\",f3=4i,f4=4u,f5=5 1000"),
influxdb3_client::Precision::Second,
)
.await
.expect("write to db");

let resp = client
.delete(&url)
.send()
.await
.expect("delete table call succeed");
assert_eq!(200, resp.status());

// check foo db has table with name in tbl-YYYYMMDD.. format
let result = server
.api_v3_query_influxql(&[("q", "SHOW MEASUREMENTS on foo"), ("format", "json")])
.await
.json::<Value>()
.await
.unwrap();
debug!(result = ?result, ">> RESULT");
let array_result = result.as_array().unwrap();
assert_eq!(1, array_result.len());
let first_db = array_result.first().unwrap();
assert_contains!(
first_db
.as_object()
.unwrap()
.get("name")
.unwrap()
.as_str()
.unwrap(),
"tbl-"
);

server
.write_lp_to_db(
db_name,
format!("{tbl_name},t1=a,t2=b,t3=c f1=true,f2=\"hello\",f3=4i,f4=4u,f5=5 1000"),
influxdb3_client::Precision::Second,
)
.await
.expect("write to db");

let result = server
.api_v3_query_influxql(&[("q", "SHOW MEASUREMENTS on foo"), ("format", "json")])
.await
.json::<Value>()
.await
.unwrap();
debug!(result = ?result, ">> RESULT");
let array_result = result.as_array().unwrap();
// check there are 2 tables now, tbl and tbl-*
assert_eq!(2, array_result.len());
let first_db = array_result.first().unwrap();
let second_db = array_result.get(1).unwrap();
assert_eq!(
"tbl",
first_db
.as_object()
.unwrap()
.get("name")
.unwrap()
.as_str()
.unwrap(),
);
assert_contains!(
second_db
.as_object()
.unwrap()
.get("name")
.unwrap()
.as_str()
.unwrap(),
"tbl-"
);
}

#[tokio::test]
async fn api_v3_configure_table_delete_no_db() {
let db_name = "db";
let server = TestServer::spawn().await;
let client = reqwest::Client::new();
let url = format!(
"{base}/api/v3/configure/table?db={db_name}&table=foo",
base = server.client_addr()
);

let resp = client
.delete(&url)
.send()
.await
.expect("delete database call succeed");
assert_eq!(StatusCode::NOT_FOUND, resp.status());
}

#[tokio::test]
async fn api_v3_configure_table_delete_missing_query_param() {
let server = TestServer::spawn().await;
let client = reqwest::Client::new();
let url = format!("{base}/api/v3/configure/table", base = server.client_addr());

let resp = client
.delete(&url)
.send()
.await
.expect("delete table call succeed");
assert_eq!(StatusCode::BAD_REQUEST, resp.status());
}

#[tokio::test]
async fn try_deleting_table_after_db_is_deleted() {
let db_name = "db";
let tbl_name = "tbl";
let server = TestServer::spawn().await;
let client = reqwest::Client::new();
let delete_db_url = format!(
"{base}/api/v3/configure/database?db={db_name}",
base = server.client_addr()
);
let delete_table_url = format!(
"{base}/api/v3/configure/table?db={db_name}&table={tbl_name}",
base = server.client_addr()
);
server
.write_lp_to_db(
db_name,
format!("{tbl_name},t1=a,t2=b,t3=c f1=true,f2=\"hello\",f3=4i,f4=4u,f5=5 1000"),
influxdb3_client::Precision::Second,
)
.await
.expect("write to db");

// db call should succeed
let resp = client
.delete(&delete_db_url)
.send()
.await
.expect("delete database call succeed");

assert_eq!(StatusCode::OK, resp.status());

// but table delete call should fail with NOT_FOUND
let resp = client
.delete(&delete_table_url)
.send()
.await
.expect("delete table call succeed");
assert_eq!(StatusCode::NOT_FOUND, resp.status());
}
Loading

0 comments on commit 20d09a8

Please sign in to comment.