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
use rdbc;

use std::rc::Rc;
use std::cell::RefCell;

use postgres::{Connection, TlsMode};
use rdbc::ResultSet;
use postgres::rows::Rows;

struct PostgresDriver {}

impl PostgresDriver {
    pub fn new() -> Self {
        PostgresDriver {}
    }

    pub fn connect(&self, url: &str) -> Rc<rdbc::Connection> {
        let conn = postgres::Connection::connect(url, TlsMode::None).unwrap();
        Rc::new(PConnection::new(conn))
    }
}

struct PConnection {
    conn: Rc<Connection>
}

impl PConnection {
    pub fn new(conn: Connection) -> Self {
        Self { conn: Rc::new(conn) }
    }
}

impl rdbc::Connection for PConnection {

    fn create_statement(&self, sql: &str) -> rdbc::Result<Rc<dyn rdbc::Statement>> {
        Ok(Rc::new(PStatement {
            conn: self.conn.clone(),
            sql: sql.to_owned()
        }))
    }

}

struct PStatement {
    conn: Rc<Connection>,
    sql: String
}

impl rdbc::Statement for PStatement {

    fn execute_query(&self) -> rdbc::Result<Rc<RefCell<dyn ResultSet>>> {
        let rows: Rows = self.conn.query(&self.sql, &[]).unwrap();
        Ok(Rc::new(RefCell::new(PResultSet { i: 0, rows })))
    }

    fn execute_update(&self) -> rdbc::Result<usize> {
        unimplemented!()
    }
}

struct PResultSet {
    i: usize,
    rows: Rows
}

impl rdbc::ResultSet for PResultSet {

    fn next(&mut self) -> bool {
        if self.i+1 < self.rows.len() {
            self.i = self.i + 1;
            true
        } else {
            false
        }
    }

    fn get_i32(&self, i: usize) -> i32 {
        self.rows.get(self.i).get(i)
    }

    fn get_string(&self, i: usize) -> String {
        self.rows.get(self.i).get(i)
    }

}

#[cfg(test)]
mod tests {

    use super::*;
    use rdbc::{Connection, Statement, ResultSet};

    //#[test]
    fn it_works() {
        let driver = PostgresDriver::new();
        let conn = driver.connect("postgres://postgres@localhost:5433");
        let stmt = conn.create_statement("SELECT foo FROM bar").unwrap();
        let rs = stmt.execute_query().unwrap();
        let mut rs = rs.borrow_mut();
        while rs.next() {
            println!("{}", rs.get_string(1))
        }
    }
}