Actix: move occurs because `p` has type `r2d2::Pool<MysqlConnectionManager>`, which does not implement the `Copy` trait

I'm trying to implement this Actix example, changing the database provider to mysql instead of sqlite.

My code is as follows:

extern crate mysql;

use actix_web::web::{Data};
use actix_web::{get, App, Error, HttpResponse, HttpServer};


use r2d2_mysql::mysql::{Opts,OptsBuilder};

use serde::Serialize;
use r2d2::Pool;

use r2d2_mysql::MysqlConnectionManager;
use r2d2_mysql::mysql::prelude::Queryable;


#[derive(Serialize)]
pub struct Organization {
    pub id: Option<i32>,
    pub name: String,
    pub country: String
}

#[get("/orgs")]
async fn get_orgs(
    pool: Data<Pool<MysqlConnectionManager>>,
) -> Result<HttpResponse, Error> {
    let mut conn = pool
        .get()
        .map_err(|_| HttpResponse::InternalServerError())?;

    let orgs = conn
        .query_map(
            "SELECT id, name, country from organization",
            |(id, name, country)| {
                Organization { id, name, country }
            },
        ).map_err(|_| HttpResponse::InternalServerError())?;

    Ok(HttpResponse::Ok().json(orgs))
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    let opts = Opts::from_url("mysql://root:mysql@127.0.0.1:33061/ebdb").unwrap();
    let builder = OptsBuilder::from_opts(opts);
    let m = MysqlConnectionManager::new(builder);

    let p = Pool::new(m).unwrap();

    HttpServer::new(move || App::new().data(p).service(get_orgs))
        .bind("127.0.0.1:8080")?
        .run()
        .await
}

Thought I had it running(happy IDE), but doing cargo run results in the following:

error[E0507]: cannot move out of `p`, a captured variable in an `Fn` closure
  --> src/main.rs:50:45
   |
48 |     let p = Pool::new(m).unwrap();
   |         - captured outer variable
49 | 
50 |     HttpServer::new(move || App::new().data(p).service(get_orgs))
   |                                             ^ move occurs because `p` has type `r2d2::Pool<MysqlConnectionManager>`, which does not implement the `Copy` trait

How am I to interpret this error? I've changed use r2d2_sqlite::SqliteConnectionManager; to use r2d2_mysql::MysqlConnectionManager; and build up the opts accordingly. Does it not implement the same traits? How do I then build up a mysql connection if this is not the way, using actix_web?

Thanks in advance. Learning Rust :smile:

Original code has this:

    HttpServer::new(move || App::new().data(p.clone()).service(get_orgs))

The difference is the p.clone() call, so that data consumes not the captured variable itself, but its copy.

1 Like

Mm.. I often see people using r2d2 in order to create a connection pool with mysq, but the mysql crate can already provide a connection pool, doesn't it?

1 Like

Few tutorials out there. thank you for the comment. will try using mysql crate directly, instead of r2d2.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.