Reputation: 5805
At https://actix.rs/docs/databases/ there is an example:
async fn index(pool: web::Data<DbPool>, name: web::Path<(String)>) -> impl Responder {
let name = name.into_inner();
let conn = pool.get().expect("couldn't get db connection from pool");
let user = web::block(move || actions::insert_new_user(&conn, &user))
.await
.map_err(|e| {
eprintln!("{}", e);
HttpResponse::InternalServerError().finish()
})?;
Ok(HttpResponse::Ok().json(user))
}
What to do if I need several SQL queries in one function? The following obviously won't work due to moving conn
:
async fn index(pool: web::Data<DbPool>, name: web::Path<(String)>) -> impl Responder {
let name = name.into_inner();
let conn = pool.get().expect("couldn't get db connection from pool");
let user1 = web::block(move || actions::insert_new_user(&conn, &user))
.await
.map_err(|e| {
eprintln!("{}", e);
HttpResponse::InternalServerError().finish()
})?;
// ... asynchronous code here
let user2 = web::block(move || actions::insert_new_user(&conn, &user))
.await
.map_err(|e| {
eprintln!("{}", e);
HttpResponse::InternalServerError().finish()
})?;
Ok(HttpResponse::Ok().json(user))
}
I can receive several connections by repeated calls of pool.get()
, but that inefficient to open a new SQL connection when one connection is enough.
So, how to deal with this?
Upvotes: 1
Views: 890
Reputation: 42756
You just need to move the reference, not the connection itself:
async fn index(pool: web::Data<DbPool>, name: web::Path<(String)>) -> impl Responder {
let name = name.into_inner();
let conn_ = pool.get().expect("couldn't get db connection from pool");
let conn = &conn_;
let user1 = web::block(move || actions::insert_new_user(&conn, &user))
.await
.map_err(|e| {
eprintln!("{}", e);
HttpResponse::InternalServerError().finish()
})?;
// ... asynchronous code here
let user2 = web::block(move || actions::insert_new_user(&conn, &user))
.await
.map_err(|e| {
eprintln!("{}", e);
HttpResponse::InternalServerError().finish()
})?;
Ok(HttpResponse::Ok().json(user))
}
Your problem can be reduced to (not working version):
struct Conn {}
fn foo(_: &Conn) {}
fn main() {
let conn_ = Conn {};
(move || foo(&conn_))();
(move || foo(&conn_))();
}
Working version:
struct Conn {}
fn foo(_: &Conn) {}
fn main() {
let conn_ = Conn {};
let conn = &conn_;
(move || foo(conn))();
(move || foo(conn))();
}
Upvotes: 2