2 unstable releases
Uses new Rust 2024
| new 0.2.0 | Dec 2, 2025 |
|---|---|
| 0.1.0 | Nov 8, 2025 |
#482 in Database interfaces
160 downloads per month
Used in datafusion-table-provider…
19KB
125 lines
r2d2_adbc
An r2d2 connection pool manager for ADBC (Arrow Database Connectivity) connections.
Overview
This crate provides a connection pool manager implementation that bridges ADBC database drivers with the r2d2 connection pooling library. It allows you to efficiently manage and reuse ADBC database connections in multi-threaded applications.
Features
- Generic ADBC Support: Works with any ADBC
Databaseimplementation - Connection Options: Configure connections with custom options
- Thread-Safe: Full support for multi-threaded connection pooling
- Type-Safe: Leverages Rust's type system for compile-time safety
Installation
Add this to your Cargo.toml:
[dependencies]
r2d2_adbc = "0.1"
adbc_core = "0.20"
Usage
Basic Usage
use r2d2_adbc::AdbcConnectionManager;
// Create your ADBC database instance
let database = /* your ADBC Database implementation */;
// Create the connection manager
let manager = AdbcConnectionManager::new(database);
// Create the connection pool
let pool = r2d2::Pool::new(manager)?;
// Get a connection from the pool
let conn = pool.get()?;
// Use the connection
let statement = conn.new_statement()?;
With Connection Options
You can configure connections with options that will be applied to each new connection:
use r2d2_adbc::AdbcConnectionManager;
let database = /* your ADBC Database implementation */;
// Method 1: Create with options upfront
let options = vec![
("autocommit".to_string(), "true".to_string()),
("isolation_level".to_string(), "read_committed".to_string()),
("timeout".to_string(), "30".to_string()),
];
let manager = AdbcConnectionManager::with_options(database, options);
// Method 2: Add options after creation
let mut manager = AdbcConnectionManager::new(database);
manager.add_option("autocommit", "true");
manager.add_option("read_only", "false");
// Create the pool
let pool = r2d2::Pool::builder()
.max_size(15)
.build(manager)?;
// All connections from the pool will have the configured options
let conn = pool.get()?;
Configuring the Pool
The r2d2 pool itself can be configured with various parameters:
use r2d2_adbc::AdbcConnectionManager;
use std::time::Duration;
let database = /* your ADBC Database implementation */;
let manager = AdbcConnectionManager::new(database);
let pool = r2d2::Pool::builder()
.max_size(20) // Maximum number of connections
.min_idle(Some(5)) // Minimum idle connections
.connection_timeout(Duration::from_secs(30))
.idle_timeout(Some(Duration::from_secs(600)))
.max_lifetime(Some(Duration::from_secs(1800)))
.build(manager)?;
How It Works
Connection Management
The AdbcConnectionManager implements the r2d2::ManageConnection trait:
connect(): Creates new connections usingDatabase::new_connection()orDatabase::new_connection_with_opts()if options are configuredis_valid(): Validates connections by attempting to create a statementhas_broken(): Quick check for broken connections (defers tois_valid()for ADBC)
Connection Options
Connection options are stored as string key-value pairs and automatically converted to the proper ADBC types (OptionConnection and OptionValue) when creating connections. Standard ADBC options include:
autocommit- Enable/disable autocommit modeisolation_level- Set transaction isolation levelcurrent_catalog- Set the current catalogcurrent_schema- Set the current schemaread_only- Restrict connection to read-only mode- Driver-specific options are also supported
Compatibility
- ADBC: Compatible with
adbc_core0.20.x - r2d2: Compatible with r2d2 0.8.x
- Rust: Requires Rust 2024 edition or later
ADBC Drivers
This crate works with any ADBC driver that implements the adbc_core::Database trait. Some available ADBC drivers include:
- PostgreSQL
- SQLite
- Flight SQL
- Snowflake
- And more...
Refer to the ADBC documentation for a complete list of available drivers.
Example: Complete Application
use r2d2_adbc::AdbcConnectionManager;
use std::error::Error;
fn main() -> Result<(), Box<dyn Error>> {
// Initialize your ADBC database
let database = /* initialize your ADBC database */;
// Create the connection manager with options
let mut manager = AdbcConnectionManager::new(database);
manager.add_option("autocommit", "true");
// Build the connection pool
let pool = r2d2::Pool::builder()
.max_size(10)
.build(manager)?;
// Use connections from the pool
for i in 0..5 {
let conn = pool.get()?;
println!("Got connection {}", i);
// Use the connection
let mut stmt = conn.new_statement()?;
// Execute queries...
}
Ok(())
}
Error Handling
The crate provides an AdbcError type that wraps adbc_core::error::Error and implements the standard Error trait. All connection pool operations return results with this error type.
match pool.get() {
Ok(conn) => {
// Use connection
}
Err(e) => {
eprintln!("Failed to get connection: {}", e);
if let Some(source) = e.source() {
eprintln!("Caused by: {}", source);
}
}
}
Thread Safety
Both AdbcConnectionManager and the resulting connection pool are fully thread-safe and can be shared across threads using Arc:
use std::sync::Arc;
use std::thread;
let pool = Arc::new(r2d2::Pool::new(manager)?);
let mut handles = vec![];
for i in 0..10 {
let pool = Arc::clone(&pool);
let handle = thread::spawn(move || {
let conn = pool.get().unwrap();
// Use connection in this thread
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
Licensed under the Apache License, Version 2.0. See LICENSE for details.
Related Projects
- r2d2 - Generic connection pool for Rust
- Apache Arrow ADBC - Arrow Database Connectivity specification
- adbc_core - Core ADBC types and traits for Rust
Dependencies
~8.5MB
~156K SLoC