Skip to content
Open
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
13 changes: 13 additions & 0 deletions src/engine/duckdb/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,13 @@ pub struct DuckDbEngine;
/// Default schema used when no `--schema` is provided.
const DEFAULT_SCHEMA: &str = "main";

// `DatabaseEngine` declares these methods as returning futures, so each impl must be
// `async` whether or not its body awaits. The DuckDB driver is synchronous, so all three
// methods here have no `.await` and trip `clippy::unused_async` -- a lint that cannot be
// satisfied without hand-rolling `impl Future` bodies purely to appease it. The
// `postgres` and `mysql` impls are unaffected because their drivers genuinely await.
impl DatabaseEngine for DuckDbEngine {
#[allow(clippy::unused_async, clippy::unused_async_trait_impl)]
async fn validate_connection(config: &ConnectionConfig) -> Result<ConnectionInfo> {
let file_path = extract_file_path(config)?;
let conn = open_connection(&file_path)?;
Expand All @@ -60,6 +66,7 @@ impl DatabaseEngine for DuckDbEngine {
})
}

#[allow(clippy::unused_async, clippy::unused_async_trait_impl)]
async fn introspect(
config: &ConnectionConfig,
operation: &IntrospectOperation,
Expand Down Expand Up @@ -97,6 +104,7 @@ impl DatabaseEngine for DuckDbEngine {
Ok(result)
}

#[allow(clippy::unused_async, clippy::unused_async_trait_impl)]
async fn execute(
config: &ConnectionConfig,
query: &str,
Expand Down Expand Up @@ -810,6 +818,11 @@ fn duckdb_value_to_json(value: &Value) -> serde_json::Value {
Json::Object(obj)
}
Value::Union(inner) => duckdb_value_to_json(inner),
// `duckdb::types::Value` is #[non_exhaustive] as of duckdb 1.10505.0, so a
// wildcard is required. Rendering the Debug form keeps an unknown future
// variant VISIBLE in the JSON rather than silently nulling it out; the
// compiler's suggested `todo!()` would panic inside a live MCP server.
other => Json::String(format!("{other:?}")),
}
}

Expand Down
8 changes: 8 additions & 0 deletions src/engine/sqlite/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,13 @@ use crate::error::{PlenumError, Result};
/// `SQLite` database engine implementation
pub struct SqliteEngine;

// `DatabaseEngine` declares these methods as returning futures, so each impl must be
// `async` whether or not its body awaits. The SQLite driver is synchronous, so all three
// methods here have no `.await` and trip `clippy::unused_async` -- a lint that cannot be
// satisfied without hand-rolling `impl Future` bodies purely to appease it. The
// `postgres` and `mysql` impls are unaffected because their drivers genuinely await.
impl DatabaseEngine for SqliteEngine {
#[allow(clippy::unused_async, clippy::unused_async_trait_impl)]
async fn validate_connection(config: &ConnectionConfig) -> Result<ConnectionInfo> {
// Validate config is for SQLite
if config.engine != DatabaseType::SQLite {
Expand Down Expand Up @@ -74,6 +80,7 @@ impl DatabaseEngine for SqliteEngine {
})
}

#[allow(clippy::unused_async, clippy::unused_async_trait_impl)]
async fn introspect(
config: &ConnectionConfig,
operation: &IntrospectOperation,
Expand Down Expand Up @@ -149,6 +156,7 @@ impl DatabaseEngine for SqliteEngine {
Ok(result)
}

#[allow(clippy::unused_async, clippy::unused_async_trait_impl)]
async fn execute(
config: &ConnectionConfig,
query: &str,
Expand Down
8 changes: 4 additions & 4 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ enum Commands {
project_path: Option<String>,

/// Database engine
#[arg(long, value_parser = ["postgres", "mysql", "sqlite"])]
#[arg(long, value_parser = ["postgres", "mysql", "sqlite", "duckdb"])]
engine: Option<String>,

/// Host (postgres/mysql)
Expand Down Expand Up @@ -108,7 +108,7 @@ enum Commands {
#[arg(long)]
database: Option<String>,

/// `SQLite` file path
/// `SQLite` / `DuckDB` file path
#[arg(long)]
file: Option<PathBuf>,

Expand Down Expand Up @@ -153,7 +153,7 @@ enum Commands {
project_path: Option<String>,

/// Engine override
#[arg(long, value_parser = ["postgres", "mysql", "sqlite"])]
#[arg(long, value_parser = ["postgres", "mysql", "sqlite", "duckdb"])]
engine: Option<String>,

/// Host override
Expand Down Expand Up @@ -280,7 +280,7 @@ enum Commands {
project_path: Option<String>,

/// Engine override
#[arg(long, value_parser = ["postgres", "mysql", "sqlite"])]
#[arg(long, value_parser = ["postgres", "mysql", "sqlite", "duckdb"])]
engine: Option<String>,

/// Host override
Expand Down
Loading