So Im trying to make my program create a DB struct that has an open connection that i can pass around as a reference to places that need it. So I have the following class
use mysql::*;
use mysql::prelude::*;
pub struct DB {
pub conn: PooledConn
}
pub fn initialize(url: &str) -> DB{
println!("Initializing!");
let pool = get_pool(url).unwrap();
let conn = pool.get_conn().unwrap();
let db = DB {
conn
};
return db;
}
fn get_pool(url: &str) -> Result<Pool> {
let opts = Opts::from_url(url).unwrap();
println!("{:?}", opts);
let pool = match Pool::new(opts){
Ok(pool) => pool,
Err(e) => {
return Err(e);
}
};
return Ok(pool);
}
So when i call initialize it creates the connection, puts it in a struct and sends that back.
let mut db = db::initialize("connection_string");
Then I can use my connection as follows:
#[derive(Debug, PartialEq, Eq)]
struct Place {
name: String
}
let mut places: Vec<Place> = vec![];
let selected_places = db.conn
.query_map(
"SELECT name from places",
|(name)| {
places.push( Place { name } );
},
).unwrap();
println!("{:?}", places);
}
And this works fine. It prints out the places as expected. But what I want to do is pass that struct around so that a single instance of the database connection is used everywhere a query is needed. so I am trying to do something like:
use mysql::*;
use mysql::prelude::*;
mod db;
fn main() {
println!("Hello, world!");
let mut db = db::initialize("connection_string");
let mut test: &db::DB = &db;
query(test);
}
fn query(mut db: &db::DB) {
#[derive(Debug, PartialEq, Eq)]
struct Place {
name: String
}
let mut rooms: Vec<Place> = vec![];
let selected_places = db.conn
.query_map(
"SELECT name from places",
|(name)| {
places.push( Place { name } );
},
).unwrap();
println!("{:?}", places);
}
If I do this the compiler says when I want to use db.conn
`db` is a `&` reference, so the data it refers to cannot be borrowed as mutable
So how do I pass in a reference to that struct so I can use the same connection in multiple places?
>Solution :
Your function query:
fn query(mut db: &db::DB)
is being passed an immutable reference to a db::DB, but making the db variable mutable. This allows you to change which db::DB the variable references, by eg assigning to it, but doesn’t actually allow you to do anything to the db::DB itself that would require a mutable reference (such as calling .query_map on the conn attribute).
If you change the function signature to:
fn query(db: &mut db::DB)
you should be able to achieve what you’re looking for. In that case, you have a mutable reference to the db::DB.