Switch master slave connection inside a function from outside


#1

This is follow up question on this question

I am using below structure for storing connections .
In the below code I want to switch master and slave connection in functions by doing
something like

user_repo.find_user::<Master>("1");
user_repo.find_user::<Slave>("1");

But I am not able to figure out how to best switch master and slave connections in function calls in rust in below scenario.

pub struct Db1Conn {
    pub master: r2d2::PooledConnection<ManagedMysqlConn>,
    pub slave: r2d2::PooledConnection<ManagedMysqlConn>,
}

pub trait UserRepo {
    fn find_user(&self, uid: UserId) -> Option<User>;
}

pub struct MysqlUserRepo<'a> {
    conn: &'a Db1Conn,
}

impl<'a> UserRepoImpl<'a> {
    pub fn new(c: &'a Db1Conn) -> UserRepoImpl<'a> {
        UserRepoImpl { conn: c }
    }
}

impl<'a> UserRepo for UserRepoImpl<'a> {
    fn find_user(&self, uid: UserId) -> Option<User> {
        let mut users = user::table
            .filter(member::id.eq(uid))
            // Need to switch below connection based on some outside parameter while calling function
            .load::<User>(&*self.conn.master)
            .expect("Error loading users");
        // .. other logic
    }
}

#2

You don’t need the master/slave to be a type parameter - just pass an extra arg to find_user that says which db to use and then pick the right one inside the function.


#3

I implemented it. Working fine for me.

pub trait MasterSlave {
    fn from(conn: & Db1Conn) -> &MysqlConnection;
}

pub struct Master;

impl MasterSlave for Master {
	fn from(conn: & Db1Conn) -> &MysqlConnection {
    	&conn.master
    }
}

pub struct Slave;

impl MasterSlave for Slave {
	fn from(conn: & Db1Conn) -> &MysqlConnection {
    	&conn.slave
    }
}

pub trait UserRepo {
    fn find_user<T: MasterSlave>(&self, uid: UserId) -> Option<User>;
}

impl<'a> UserRepo for UserRepoImpl<'a> {
    fn find_user<T: MasterSlave>(&self, uid: UserId) -> Option<User> {
        let mut users = user::table
            .filter(member::id.eq(uid))
            // Need to switch below connection based on some outside parameter while calling function
            .load::<User>(T::from(&self.conn))
            .expect("Error loading users");
        // .. other logic
    }
}