mysql-repo 0.1.0

Repository pattern traits for rust-mysql-simple
Documentation
extern crate mysql;

use mysql::{Params, Row, Error};
use mysql::conn::GenericConnection;

pub trait Repository {

    fn where_one<T, P, Where>(conn: &mut T, sql: &str, params: P) -> Result<Option<Where>, Error>
        where T: GenericConnection, Where: Whereable<Self>, P: Into<Params>, Self: Sized {
        let out = conn.prep_exec(Where::wrapped_sql(sql), params.into())?
            .flat_map(|x| x)
            .flat_map(|x| Where::from_row(x) )
            .next();
        Ok(out)
    }

    fn where_all<T, P, Where>(conn: &mut T, sql: &str, params: P) -> Result<Vec<Where>, Error>
        where T: GenericConnection, Where: Whereable<Self>, P: Into<::mysql::Params>, Self: Sized {
        let out = conn.prep_exec(Where::wrapped_sql(sql), params.into())?
            .flat_map(|x| x)
            .flat_map(|x| Where::from_row(x) )
            .collect();
        Ok(out)
    }

    fn find<T, Find>(conn: &mut T, id: u64) 
        -> Result<Option<Find>, Error> where T: GenericConnection, Find: Findable<Self>, Self: Sized {
        let out = conn.prep_exec(Find::sql(), (id,))?
            .flat_map(|x| x)
            .flat_map(|x| Find::from_row(x) )
            .next();
        Ok(out)
    }

    fn insert<T, Ins>(conn: &mut T, obj: Ins) 
        -> Result<u64, Error> where T: GenericConnection, Ins: Insertable<Self>, Self: Sized {
        let res = conn.prep_exec(Ins::sql(), obj.to_params())?;
        let id = res.last_insert_id();
        Ok(id)
    }

    fn update<T, Up>(conn: &mut T, obj: Up) 
        -> Result<(), Error> where T: GenericConnection, Up: Updatable<Self>, Self: Sized {
        conn.prep_exec(Up::sql(), obj.to_params())?;
        Ok(())
    }

    fn delete<T, Del>(conn: &mut T, obj: Del) 
        -> Result<(), Error> where T: GenericConnection, Del: Deletable<Self>, Self: Sized {
        conn.prep_exec(Del::sql(), obj.to_params())?;
        Ok(())
    }
}

pub trait Whereable<R: Repository>: Sized {
    fn wrapped_sql(sql: &str) -> String;
    fn from_row(row: Row) -> Result<Self, Error>;
}

pub trait Insertable<R: Repository> {
    fn sql() -> &'static str;
    fn to_params(&self) -> Params;
}

pub trait Updatable<R: Repository>: Sized {
    fn sql() -> &'static str;
    fn to_params(&self) -> Params;
}

pub trait Findable<R: Repository>: Sized {
    fn sql() -> &'static str;
    fn from_row(row: Row) -> Result<Self, Error>;
}

pub trait Deletable<R: Repository> {
    fn sql() -> &'static str;
    fn to_params(&self) -> Params;
}