Hi there. I try to use and understand diesel and r2d2. Here is my code so far
extern crate diesel;
use diesel::prelude::*;
use diesel::r2d2::ConnectionManager;
use dotenv::dotenv;
use std::env;
fn main() {
dotenv().ok();
let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
let manager = ConnectionManager::<PgConnection>::new(database_url);
let pool = r2d2::Pool::new(manager).unwrap();
let conn = pool.get();
}
I already have some questions...
First: where do i specify the size of the pool?
Second: how do i return the conn to the pool once i don't need it anymore?
Third: how do i share the pool with other modules so these modules can also ask for a connection and return it to the pool after use ? I come from java where i would simply declare a public static method on some object "DbUtils.getConnection()" but here in Rust i'm a bit lost
Last one: see diesel - Rust. The documentation talks about macro infer_schema! but i don't see it in the list of macro. Is it something wrong in the documentation?
extern crate diesel;
use diesel::prelude::*;
use diesel::r2d2::ConnectionManager;
use dotenv::dotenv;
use std::env;
fn main() {
dotenv().ok();
let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
let manager = ConnectionManager::::new(database_url);
let pool = r2d2::Pool::new(manager).unwrap();
let conn = pool.get();
}
Now the answers.
First : where do i specify the size of the pool?
You can use builder, like in the example below:
let pool = r2d2::Pool::builder()
.max_size(15)
.build(manager)
.unwrap();
Second : how do i return the conn to the pool once i don't need it anymore ?
According to Readme file in project:
// use the connection
// it will be returned to the pool when it falls out of scope.
So, if you would write:
fn main() {
dotenv().ok();
let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
let manager = ConnectionManager::::new(database_url);
let pool = r2d2::Pool::new(manager).unwrap();
{
let conn = pool.get();
} // connection goes back to pool here
}
Third : how do i share the pool with other modules so these modules can also ask for a connection and return it to the pool after use ? I come from java where i would simply declare a public static method on some object "DbUtils.getConnection()" but here in RUST i'm a bit lost
I am not an expert, but you can do it same way like in Readme file, so creating a new thread and cloning pool. You can also add pool as argument of the method when needed.
If you write code in Java with Spring framework, then you may have a @Bean which represents a connection pool. You can then pass it as constructor argument. You can do similar in Rust I believe. I hope other people here will elaborate about it. Like I said, I am not an expert in Rust.
Third : how do i share the pool with other modules so these modules can also ask for a connection and return it to the pool after use ? I come from java where i would simply declare a public static method on some object "DbUtils.getConnection()" but here in RUST i'm a bit lost
i did something like this
// utils.rs
use lazy_static;
use diesel::{
r2d2::{Pool, ConnectionManager},
pg::PgConnection
};
type PgPool = Pool<ConnectionManager<PgConnection>>;
pub struct Values<'a> {
pub db_connection: PgPool,
}
lazy_static! {
pub static ref VALUES: Values<'static> = {
Values {
db_connection: PgPool::builder()
.max_size(8)
.build(ConnectionManager::new("yourconnectionstring"))
.expect("failed to create db connection_pool")
}
};
}
then you can access it thus
use super::utils;
pub fn can_connect() -> bool {
utils::VALUES.db_connection.get().is_ok()
}
Did you read the error message? It says it couldn't find the crate lazy_static, so you would have to add it as a dependency to your library in the Cargo.toml file.
Sorry to be such a newbie. lazy_static! is ok now but that doesn't compile because in the struct Values<'a> { pub db_connection: 'a PgPool,} 'a is not used
pub struct Values<'a> {
| ^^ unused parameter
|
= help: consider removing `'a`, referring to it in a field, or using a marker such as `std::marker::PhantomData`
Still that doesn't compile. The provided piece of code is probably not well written...
Values {
25 | | db_connection: PgPool::builder()
| |_____________________________-
26 | || .max_size(8)
27 | || .build(ConnectionManager::new("yourconnectionstring"))
28 | || .expect("failed to create db connection_pool")
| ||______________________________________________________________- temporary value created here
29 | | }
| |_________^ returns a value referencing data owned by the current function
It is impossible to find a clean simple example on how to use Diesel & Postgres with a connection pool .
Yes for sure. This is the code provided by copsevane. That doesn't compile
// utils.rs
use lazy_static;
use diesel::{
r2d2::{Pool, ConnectionManager},
pg::PgConnection
};
type PgPool = Pool<ConnectionManager<PgConnection>>;
pub struct Values<'a> {
pub db_connection: PgPool,
}
lazy_static! {
pub static ref VALUES: Values<'static> = {
Values {
db_connection: PgPool::builder()
.max_size(8)
.build(ConnectionManager::new("yourconnectionstring"))
.expect("failed to create db connection_pool")
}
};
}
I am worry to see how hard it is to find proper documentation for such a simple thing. I would like to insert/retrieve one record in one simple table using Diesel-Postgres-R2D2 but everywhere i find documentation on the internet it is too old (i have found things like infer_table! that doesn't exist anymore see diesel - Rust. The documentation talks about macro infer_schema! but i don't see it in the list of macro). Then i find r2d2-diesel but it is written : THIS CRATE HAS BEEN DEPRECATED, USE THE r2d2 MODULE IN DIESEL INSTEAD