Search code examples
postgresqlruststaticglobal-variables

How do I keep a global Postgres connection?


I want to store the Postgres connection on global scope to access from any function in a module. Here is an example:

use postgres::{Client, NoTls};

static mut client: Option<Client> = None;

pub fn get_player(id: i32) {
    // Use global client connection object:
    for row in client.unwrap().query("SELECT * FROM public.\"User\" WHERE \"accountID\"=$1;",&[&id]).unwrap(){
        let id: i32 = row.get(0);
        let name: &str = row.get(1);

        println!("found player: {} {}", id, name);
    }
}

pub fn init() {
    let mut connection = Client::connect("host=localhost user=postgres", NoTls);
    match connection {
        Ok(cli) => {
            println!("Database connected.");
            client = Some(cli);
        }
        Err(_) => println!("Database ERROR while connecting."),
    }
}

It is not compiling & working as intended and I don't know how to make this in Rust.


Solution

  • Here is an example with lazy_static and r2d2_postgres that provides a database connection pool:

    use r2d2_postgres::postgres::{NoTls, Client};
    use r2d2_postgres::PostgresConnectionManager;
    
    #[macro_use]
    extern crate lazy_static;
    
    lazy_static! {
        static ref POOL: r2d2::Pool<PostgresConnectionManager<NoTls>> = {
            let manager = PostgresConnectionManager::new(
                // TODO: PLEASE MAKE SURE NOT TO USE HARD CODED CREDENTIALS!!!
                "host=localhost user=postgres password=password".parse().unwrap(),
                NoTls,
            );
            r2d2::Pool::new(manager).unwrap()
        };
    }
    
    
    
    pub fn get_player(id: i32) {
        // Use global client connection object:
        let mut client = POOL.get().unwrap();
        for row in client.query("SELECT * FROM public.\"User\" WHERE \"accountID\"=$1;",&[&id]).unwrap(){
            let id: i32 = row.get(0);
            let name: &str = row.get(1);
    
            println!("found player: {} {}", id, name);
        }
    }