1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128

use postgres::{NoTls};
use r2d2_postgres::PostgresConnectionManager;
use r2d2::{Pool, PooledConnection};
use parking_lot::{ RwLock};
use std::time::Duration;
use std::collections::HashMap;
use unidb::{get_db_properties};
use unidb::build_sql;

pub mod pg_dao;

#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;

lazy_static!{

    static ref PG_POOL: RwLock<Pool<PostgresConnectionManager<NoTls>>> = {
        RwLock::new(create_postgres_connection_manager())
    };
    static ref DATA_TYPE_CACHE: HashMap<String, String> = {

        let sql = build_sql("select_table_columns", "", &HashMap::new());

        let map = match connect_db() {
            Ok(mut conn) => {

                let mut map : HashMap<String, String> = HashMap::new();

                for row in conn.query(sql.as_str(), &[]).unwrap() {

                    let table_name : &str = row.get("table_name");
                    let column_name : &str = row.get("column_name");
                    let udt_name : &str = row.get("udt_name");

                    map.insert(format!("{}.{}", table_name, column_name), udt_name.to_string());
                }
                map
            }
            Err(e) => {
                println!("DATA_TYPE_CACHE error: {}", e);
                HashMap::new()
            }
        };
        map
    };
}
pub fn connect_db() -> Result<PooledConnection<PostgresConnectionManager<NoTls>>, r2d2::Error>{

    let conn = PG_POOL.read();
    return match conn.get() {

        Ok(t) => Ok(t),
        Err(e) => {
            error!("==> {:?}", e);
            drop(conn);

            let mut conn = PG_POOL.write();
            *conn = create_postgres_connection_manager();
            conn.get()
        }
    };
}
pub fn create_postgres_connection_manager() -> Pool<PostgresConnectionManager<NoTls>> {

    let properties = get_db_properties();

    let pool_size = match properties.get("db.pgsql.pool_size") {
        Some(t) =>   t.parse::<u32>().unwrap(),
        None => panic!("No such property: db.pgsql.pool_size")
    };
    let idle_timeout_sec = match properties.get("db.pgsql.idle_timeout_sec") {
        Some(t) =>   t.parse::<u64>().unwrap_or(15),
        None => 15,
    };

    let manager = PostgresConnectionManager::new( get_data_source().parse().unwrap(),NoTls,);
    let pool = r2d2::Pool::builder()
        .idle_timeout(Some(Duration::from_secs(idle_timeout_sec)))
        .max_size(pool_size)
        .build(manager).unwrap();
    pool
}

fn get_data_source() -> String{

    let properties = get_db_properties();

    let data_source
        = format!("host={} port={} user={} password={} dbname={}",
                  match properties.get("db.pgsql.host") {
                      Some(v) => v,
                      _ => panic!("No such property: db.pgsql.host"),
                  },
                  match properties.get("db.pgsql.port") {
                      Some(v) => v,
                      _ => panic!("No such property: db.pgsql.port"),
                  },
                  match properties.get("db.pgsql.user") {
                      Some(v) => v,
                      _ => panic!("No such property: db.pgsql.user"),
                  },
                  match properties.get("db.pgsql.password") {
                      Some(v) => v,
                      _ => panic!("No such property: db.pgsql.password"),
                  },
                  match properties.get("db.pgsql.dbname") {
                      Some(v) => v,
                      _ => panic!("No such property: db.pgsql.dbname"),
                  }
    );
    data_source
}

pub fn get_table_column(){

    // println!("user_api_auth.update_datetime={:?}", DATA_TYPE_CACHE.get("user_api_auth.update_datetime"));
    // println!("user_api_auth.update_datetime={:?}", SQL_CACHE.get("select_table_columns"));
}
#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        assert_eq!(2 + 2, 4);
    }
}