Crates.io | vertica-rs |
lib.rs | vertica-rs |
version | 0.0.1 |
created_at | 2025-09-05 05:22:23.769469+00 |
updated_at | 2025-09-05 05:22:23.769469+00 |
description | A native Rust driver for Vertica database |
homepage | |
repository | https://gitee.com/awol2010ex/vertica-rs |
max_upload_size | |
id | 1825108 |
size | 314,424 |
A high-performance, native Rust client library for Vertica databases. This library provides a clean, type-safe API for connecting to and querying Vertica databases, with support for connection pooling, TLS encryption, and comprehensive type handling.
Add this to your Cargo.toml
:
[dependencies]
vertica-rs = "0.1.0"
tokio = { version = "1.0", features = ["full"] }
use vertica_rs::{Client, ConnectionConfig};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Initialize logging
env_logger::init();
// Create connection configuration
let config = ConnectionConfig::from_url("vertica://user:password@localhost:5433/database")?;
// Connect to the database
let client = Client::new(config).await?;
// Check connection
if !client.is_ready().await {
eprintln!("Failed to connect to database");
return Ok(());
}
println!("Connected to Vertica database successfully!");
// Simple query
let result = client.query("SELECT 1 as test").await?;
println!("Query returned {} rows", result.len());
Ok(())
}
use vertica_rs::{Client, ConnectionConfig, PoolConfig};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = ConnectionConfig::from_url("vertica://user:password@localhost:5433/database")?;
let pool_config = PoolConfig::default()
.with_min_connections(2)
.with_max_connections(10);
let client = Client::with_pool(config, pool_config).await?;
// All queries will use the connection pool
let result = client.query("SELECT version()").await?;
Ok(())
}
use vertica_rs::{Client, ConnectionConfig};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = ConnectionConfig::from_url("vertica://user:password@localhost:5433/database")?;
let client = Client::new(config).await?;
let mut txn = client.transaction().await?;
// Execute queries within transaction
txn.execute(
"INSERT INTO users (name, email) VALUES (?, ?)",
&[&"Alice", &"alice@example.com"]
).await?;
txn.execute(
"UPDATE users SET email = ? WHERE name = ?",
&[&"updated@example.com", &"Alice"]
).await?;
txn.commit().await?;
Ok(())
}
use vertica_rs::{Client, ConnectionConfig, Value};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = ConnectionConfig::from_url("vertica://user:password@localhost:5433/database")?;
let client = Client::new(config).await?;
let result = client.query_with_params(
"SELECT * FROM users WHERE age > ? AND active = ?",
&[Value::Int(25), Value::Boolean(true)]
).await?;
for row in result.rows() {
let name: String = row.get_by_name("name")?;
let age: i32 = row.get_by_name("age")?;
println!("Active user: {} (age {})", name, age);
}
Ok(())
}
use vertica_rs::{Client, ConnectionConfig};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = ConnectionConfig::from_url("vertica://user:password@localhost:5433/database")?;
let client = Client::new(config).await?;
let queries = [
"SELECT 1",
"SELECT 2",
"SELECT 3",
];
let results = client.execute_batch(&queries).await?;
println!("Batch execution completed with {} results", results.len());
Ok(())
}
The connection URL follows the format:
vertica://[user[:password]@]host[:port]/database[?param1=value1¶m2=value2]
Examples:
vertica://user:pass@localhost:5433/mydb
vertica://user@localhost:5433/mydb?sslmode=require
vertica://localhost:5433/mydb
use vertica_rs::ConnectionConfig;
let config = ConnectionConfig {
host: "localhost".to_string(),
port: 5433,
database: "mydb".to_string(),
username: "user".to_string(),
password: Some("password".to_string()),
ssl_mode: SslMode::Prefer,
connect_timeout: Duration::from_secs(30),
read_timeout: Duration::from_secs(30),
write_timeout: Duration::from_secs(30),
..Default::default()
};
use vertica_rs::PoolConfig;
let pool_config = PoolConfig {
min_connections: 2,
max_connections: 10,
connection_timeout: Duration::from_secs(30),
idle_timeout: Duration::from_secs(300),
max_lifetime: Duration::from_secs(3600),
..Default::default()
};
The library supports several SSL modes:
Disable
: No SSLPrefer
: Use SSL if availableRequire
: Require SSLVerifyCa
: Require SSL and verify CAVerifyFull
: Require SSL and verify hostnameExample with SSL:
use vertica_rs::{ConnectionConfig, SslMode};
let config = ConnectionConfig {
ssl_mode: SslMode::Require,
..ConnectionConfig::from_url("vertica://user:pass@localhost:5433/mydb")?
};
The library supports automatic conversion between Rust types and Vertica data types:
Vertica Type | Rust Type | Description |
---|---|---|
BOOLEAN | bool | Boolean values |
INTEGER | i32 | 32-bit signed integer |
BIGINT | i64 | 64-bit signed integer |
FLOAT | f32 | 32-bit floating point |
DOUBLE PRECISION | f64 | 64-bit floating point |
NUMERIC | Decimal | High-precision decimal |
VARCHAR | String | Variable-length string |
CHAR | String | Fixed-length string |
TEXT | String | Long text data |
DATE | NaiveDate | Date without time |
TIME | NaiveTime | Time without date |
TIMESTAMP | NaiveDateTime | Date and time |
TIMESTAMPTZ | NaiveDateTime | Date and time with timezone |
UUID | Uuid | Universally unique identifier |
BINARY | Vec |
Binary data |
VARBINARY | Vec |
Variable-length binary data |
// Automatic type conversion
let name: String = row.get_by_name("name")?;
let age: i32 = row.get_by_name("age")?;
let salary: f64 = row.get_by_name("salary")?;
let active: bool = row.get_by_name("active")?;
let uuid: Uuid = row.get_by_name("user_id")?;
let decimal: Decimal = row.get_by_name("amount")?;
// Optional values for nullable columns
let middle_name: Option<String> = row.get_opt_by_name("middle_name")?;
let birth_date: Option<NaiveDate> = row.get_opt_by_name("birth_date")?;
use vertica_rs::types::Value;
// Create values
let name = Value::String("Alice".to_string());
let age = Value::Int(30);
let active = Value::Boolean(true);
let salary = Value::Decimal(Decimal::from(50000.50));
let uuid = Value::Uuid(Uuid::new_v4());
// Convert values
let age_int: i32 = age.as_i32()?;
let name_str: String = name.as_string()?;
let active_bool: bool = active.as_bool()?;
The library provides comprehensive error handling with detailed error information:
use vertica_rs::{Client, VerticaError};
match client.query("SELECT * FROM nonexistent_table").await {
Ok(result) => {
// Handle successful query
}
Err(VerticaError::Connection(msg)) => {
eprintln!("Connection error: {}", msg);
}
Err(VerticaError::Query(msg)) => {
eprintln!("Query error: {}", msg);
}
Err(VerticaError::TypeConversion(msg)) => {
eprintln!("Type conversion error: {}", msg);
}
Err(e) => {
eprintln!("Other error: {}", e);
}
}
See the examples/
directory for more detailed examples:
basic_usage.rs
: Basic connection and query examplesconnection_pool.rs
: Connection pooling examplesstring_type_demo.rs
: String type handling examplesall_types_demo.rs
: All data types usage examplespractical_types.rs
: Practical type usage examplesdecimal_demo.rs
: Decimal type usage examplesRun examples with:
cargo run --example basic_usage
cargo run --example connection_pool
cargo run --example string_type_demo
cargo run --example all_types_demo
cargo run --example practical_types
cargo run --example decimal_demo
The library includes comprehensive tests. To run the tests:
# Unit tests
cargo test
# Integration tests (requires running Vertica instance)
cargo test --test integration_test -- --ignored
The library supports the following Cargo features:
default
: Includes TLS supporttls
: Enables TLS/SSL support (enabled by default)pool
: Enables connection pooling supportTo use without TLS:
[dependencies]
vertica-rs = { version = "0.1.0", default-features = false }
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
For questions and support, please open an issue on the Gitee repository.